Skip to content

Commit 2cef0b2

Browse files
Split prerelease and stable publish flows (#13)
1 parent 25f36c8 commit 2cef0b2

File tree

2 files changed

+81
-20
lines changed

2 files changed

+81
-20
lines changed

.github/workflows/publish-package.yml

Lines changed: 79 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,21 @@ permissions:
1414
packages: write
1515

1616
jobs:
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: |
@@ -37,6 +44,8 @@ jobs:
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

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,9 @@ bun run analyze -- --input example.md --out-dir findings-confidence-3 --analyze-
195195
## Release Automation
196196

197197
- `main` merges trigger `.github/workflows/publish-package.yml` automatically (no manual dispatch).
198-
- The workflow publishes the current package version to GitHub Packages with npm tag `next`.
199198
- Versioning is enforced as patch-only `0.0.x` and starts at `0.0.1`.
200-
- After publish, the workflow opens a PR that bumps `package.json` to the next patch (for example `0.0.1 -> 0.0.2`).
199+
- Normal PR merges publish a prerelease for the next patch with npm tag `next` (for example `0.0.2-next.<run>.<attempt>.<sha>`), then keep/create a draft bump PR (for example `0.0.1 -> 0.0.2`).
200+
- Merging the automated bump PR publishes that bumped version as the public release (`latest`) and does not create another `.next` publish.
201201

202202
---
203203

0 commit comments

Comments
 (0)