Releases are automated. You bump the version via a workflow, merge the bump PR, and the tag, GitHub Release, and npm publish happen on their own (behind a manual approval gate).
Notation: X.Y.Z is a concrete SemVer; release/X.Y.x is the audit branch for
the X.Y line (the x is literal — it denotes the patch line, not a point);
N is a prerelease counter.
main— the alpha line; always exists.release/X.Y.x— theX.Ypatch line; cut frommainwhen an audit starts, carriesX.Y.0-rc.N → X.Y.0(and any laterX.Y.Zhotfixes). Deleted after back-merge; recreate it from thevX.Y.Ztag if a later hotfix is needed.
There is no long-lived per-version branch: a version bump is just a PR into
main or a release/X.Y.x branch.
- Run Prepare release (
prepare-release.yml) via Actions → Run workflow: pick the branch, type the exact target version. It opens achore/bump-<version>PR into that branch. - Review and merge the bump PR.
- On merge, Create release (
create-release.yml) cutsv<version>+ a GitHub Release from that branch (--prereleasefor any-alpha/-rcversion). - That fires Publish (
release.yml), which pauses at thereleaseapproval gate. An authorized reviewer approves, then it publishes to npm.
npm dist-tags: stable → latest, -alpha/-rc → beta.
Standard SemVer pre-release identifiers, in sort order:
X.Y.0-alpha.N → … → X.Y.0-rc.N → … → X.Y.0. Counters start at .1 (no
-rc.0). Content drives the minor (X.Y); the 3-week cadence drives only the
alpha counter.
Scheduled alpha (from main)
- Prepare release on
main, versionX.Y.0-alpha.N→ merge → publishesbeta.
Audit starts (cut the release line)
git branch release/X.Y.x <audit-sha> && git push origin release/X.Y.x(creating the branch cuts nothing — its version is already tagged).- Prepare release on
release/X.Y.x, versionX.Y.0-rc.1→ merge → publishesbeta. - rc fixes later: repeat with
X.Y.0-rc.2, etc.
Audit clears (stable + next alpha, same day)
- Merge audit fixes into
release/X.Y.x. - Prepare release on
release/X.Y.x, versionX.Y.0→ merge → publisheslatest. - Prepare release on
main, next minor's first alphaX.(Y+1).0-alpha.1→ merge → publishesbeta. - Back-merge
release/X.Y.x→main(keepmain's higher version on conflict), then deleterelease/X.Y.x.
Re-running is safe: create-release.yml only cuts a release if the tag has no
release yet, so no manual tag/release deletion is needed.
- Settings → Environments →
release: add required reviewers (this is what makes the approval gate real; without it the publish job pauses for no one). - Variables/secrets:
GH_APP_ID(var) andGH_APP_PRIVATE_KEY(secret) must be set — bothprepare-release.ymlandcreate-release.ymlneed the app token (the latter so its release event chains to the publish workflow).