@@ -14,14 +14,21 @@ permissions:
1414 packages : write
1515
1616jobs :
17- require-pr- merge :
18- name : Require PR Merge
17+ resolve- merge-context :
18+ name : Resolve Merge Context
1919 runs-on : blacksmith-4vcpu-ubuntu-2404
2020 permissions :
2121 contents : read
2222 pull-requests : read
23+ outputs :
24+ pr_number : ${{ steps.context.outputs.pr_number }}
25+ pr_url : ${{ steps.context.outputs.pr_url }}
26+ pr_title : ${{ steps.context.outputs.pr_title }}
27+ pr_head_ref : ${{ steps.context.outputs.pr_head_ref }}
28+ is_bump_pr : ${{ steps.context.outputs.is_bump_pr }}
2329 steps :
2430 - name : Ensure push commit came from merged PR
31+ id : context
2532 uses : actions/github-script@v7
2633 with :
2734 script : |
3744 state
3845 mergedAt
3946 url
47+ title
48+ headRefName
4049 }
4150 }
4251 }
@@ -95,10 +104,26 @@ jobs:
95104 `Publish gate passed via merged PR #${mergedPr.number} (${mergedPr.url})`,
96105 );
97106
98- publish-and-bump :
99- name : Publish Next + Open Bump PR
107+ const isBumpPr =
108+ (mergedPr.headRefName ?? "").startsWith("ci/version-bump-") ||
109+ /^chore:\s*bump package version to 0\\.0\\.\\d+$/i.test(
110+ mergedPr.title ?? "",
111+ );
112+
113+ core.setOutput("pr_number", String(mergedPr.number));
114+ core.setOutput("pr_url", mergedPr.url ?? "");
115+ core.setOutput("pr_title", mergedPr.title ?? "");
116+ core.setOutput("pr_head_ref", mergedPr.headRefName ?? "");
117+ core.setOutput("is_bump_pr", isBumpPr ? "true" : "false");
118+
119+ core.info(
120+ `Resolved publish mode: ${isBumpPr ? "stable release (latest)" : "prerelease (next)"}`,
121+ );
122+
123+ publish-and-manage-bump :
124+ name : Publish Package + Manage Bump PR
100125 runs-on : blacksmith-4vcpu-ubuntu-2404
101- needs : require-pr- merge
126+ needs : resolve- merge-context
102127 permissions :
103128 contents : write
104129 pull-requests : write
@@ -127,13 +152,26 @@ jobs:
127152 bun test
128153 bun run build
129154
155+ - name : Report publish strategy
156+ run : |
157+ echo "Merged PR #${{ needs.resolve-merge-context.outputs.pr_number }} (${{ needs.resolve-merge-context.outputs.pr_url }})"
158+ echo "Head ref: ${{ needs.resolve-merge-context.outputs.pr_head_ref }}"
159+ echo "Title: ${{ needs.resolve-merge-context.outputs.pr_title }}"
160+ echo "Bump PR: ${{ needs.resolve-merge-context.outputs.is_bump_pr }}"
161+
130162 - name : Resolve package metadata
131163 id : meta
164+ env :
165+ IS_BUMP_PR : ${{ needs.resolve-merge-context.outputs.is_bump_pr }}
132166 run : |
133167 node <<'NODE'
134168 const fs = require("node:fs");
135169 const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"));
136170 const match = /^0\.0\.(\d+)$/.exec(pkg.version ?? "");
171+ const isBumpPr = process.env.IS_BUMP_PR === "true";
172+ const runNumber = process.env.GITHUB_RUN_NUMBER ?? "0";
173+ const runAttempt = process.env.GITHUB_RUN_ATTEMPT ?? "1";
174+ const shortSha = (process.env.GITHUB_SHA ?? "sha").slice(0, 7);
137175
138176 if (!pkg.name) {
139177 console.error("Missing package name in package.json");
@@ -147,10 +185,30 @@ jobs:
147185 process.exit(1);
148186 }
149187
150- const nextVersion = `0.0.${Number(match[1]) + 1}`;
188+ const stableVersion = pkg.version;
189+ const nextStableVersion = `0.0.${Number(match[1]) + 1}`;
190+ const prereleaseVersion = `${nextStableVersion}-next.${runNumber}.${runAttempt}.${shortSha}`;
191+
192+ const publishVersion = isBumpPr ? stableVersion : prereleaseVersion;
193+ const publishTag = isBumpPr ? "latest" : "next";
194+ const createBumpPr = isBumpPr ? "false" : "true";
195+
151196 fs.appendFileSync(process.env.GITHUB_OUTPUT, `name=${pkg.name}\n`);
152- fs.appendFileSync(process.env.GITHUB_OUTPUT, `version=${pkg.version}\n`);
153- fs.appendFileSync(process.env.GITHUB_OUTPUT, `next_version=${nextVersion}\n`);
197+ fs.appendFileSync(process.env.GITHUB_OUTPUT, `stable_version=${stableVersion}\n`);
198+ fs.appendFileSync(process.env.GITHUB_OUTPUT, `next_stable_version=${nextStableVersion}\n`);
199+ fs.appendFileSync(process.env.GITHUB_OUTPUT, `publish_version=${publishVersion}\n`);
200+ fs.appendFileSync(process.env.GITHUB_OUTPUT, `publish_tag=${publishTag}\n`);
201+ fs.appendFileSync(process.env.GITHUB_OUTPUT, `create_bump_pr=${createBumpPr}\n`);
202+ NODE
203+
204+ - name : Set package version for prerelease publish
205+ if : steps.meta.outputs.create_bump_pr == 'true'
206+ run : |
207+ node <<'NODE'
208+ const fs = require("node:fs");
209+ const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"));
210+ pkg.version = "${{ steps.meta.outputs.publish_version }}";
211+ fs.writeFileSync("package.json", `${JSON.stringify(pkg, null, 2)}\n`);
154212 NODE
155213
156214 - name : Configure npm for GitHub Packages
@@ -160,28 +218,28 @@ jobs:
160218 npm config set @shpitdev:registry https://npm.pkg.github.com
161219 npm config set //npm.pkg.github.com/:_authToken "$NODE_AUTH_TOKEN"
162220
163- - name : Publish package with next tag
221+ - name : Publish package
164222 id : publish
165223 env :
166224 NODE_AUTH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
167225 run : |
168- PACKAGE_REF="${{ steps.meta.outputs.name }}@${{ steps.meta.outputs.version }}"
226+ PACKAGE_REF="${{ steps.meta.outputs.name }}@${{ steps.meta.outputs.publish_version }}"
169227
170228 if npm view "$PACKAGE_REF" version --registry https://npm.pkg.github.com >/dev/null 2>&1; then
171229 echo "Version $PACKAGE_REF already exists in GitHub Packages; skipping publish."
172230 echo "published=false" >> "$GITHUB_OUTPUT"
173231 exit 0
174232 fi
175233
176- npm publish --registry https://npm.pkg.github.com --tag next
234+ npm publish --registry https://npm.pkg.github.com --tag "${{ steps.meta.outputs.publish_tag }}"
177235 echo "published=true" >> "$GITHUB_OUTPUT"
178236
179237 - name : Verify registry install
180238 if : steps.publish.outputs.published == 'true'
181239 env :
182240 NODE_AUTH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
183241 run : |
184- PACKAGE_REF="${{ steps.meta.outputs.name }}@${{ steps.meta.outputs.version }}"
242+ PACKAGE_REF="${{ steps.meta.outputs.name }}@${{ steps.meta.outputs.publish_version }}"
185243
186244 mkdir -p e2e-install
187245 cd e2e-install
@@ -205,27 +263,30 @@ jobs:
205263 ./node_modules/.bin/opencode-sandboxed-research-setup --help
206264
207265 - name : Prepare next patch bump
266+ if : steps.meta.outputs.create_bump_pr == 'true'
208267 run : |
209268 node <<'NODE'
210269 const fs = require("node:fs");
211270 const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"));
212- pkg.version = "${{ steps.meta.outputs.next_version }}";
271+ pkg.version = "${{ steps.meta.outputs.next_stable_version }}";
213272 fs.writeFileSync("package.json", `${JSON.stringify(pkg, null, 2)}\n`);
214273 NODE
215274
216275 - name : Open bump PR
276+ if : steps.meta.outputs.create_bump_pr == 'true'
217277 uses : peter-evans/create-pull-request@v6
218278 with :
219279 token : ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }}
220- branch : ci/version-bump-${{ steps.meta.outputs.next_version }}
280+ branch : ci/version-bump-${{ steps.meta.outputs.next_stable_version }}
221281 draft : true
222282 delete-branch : true
223- commit-message : " chore: bump package version to ${{ steps.meta.outputs.next_version }}"
224- title : " chore: bump package version to ${{ steps.meta.outputs.next_version }}"
283+ commit-message : " chore: bump package version to ${{ steps.meta.outputs.next_stable_version }}"
284+ title : " chore: bump package version to ${{ steps.meta.outputs.next_stable_version }}"
225285 body : |
226286 Automated post-publish bump.
227287
228- - Published `${{ steps.meta.outputs.name }}@${{ steps.meta.outputs.version }}` with npm tag `next`
229- - Next patch version prepared: `${{ steps.meta.outputs.next_version }}`
288+ - Merged PR: #${{ needs.resolve-merge-context.outputs.pr_number }}
289+ - Published `${{ steps.meta.outputs.name }}@${{ steps.meta.outputs.publish_version }}` with npm tag `${{ steps.meta.outputs.publish_tag }}`
290+ - Next stable version prepared: `${{ steps.meta.outputs.next_stable_version }}`
230291 add-paths : |
231292 package.json
0 commit comments