-
Fetch and determine the target version. Run git fetch origin main, then read the current root version from origin/main. The next version follows the release-bump rules in scripts/determine-version-utils.ts: an RC base advances its counter (8.0.0-rc.1 → 8.0.0-rc.2), a pre-8 stable base transitions onto the RC line (0.17.0 → 8.0.0-rc.1), a stable 8.x base advances the minor.
git fetch origin main
CURRENT=$(git show origin/main:package.json | node -e 'process.stdout.write(JSON.parse(require("fs").readFileSync(0,"utf8")).version)')
NEXT=$(node -e "import('./scripts/determine-version-utils.ts').then(m => process.stdout.write(m.computeNextReleaseVersion(process.argv[1])))" "$CURRENT")
echo "$CURRENT → $NEXT"
($NEXT is only for naming the branch and PR — the authoritative bump in step 3 recomputes it inside the fresh origin/main worktree. The command above runs the helper from your checkout, which may be older than origin/main; step 3 therefore ends by verifying the two agree.)
-
Create a fresh worktree off origin/main. Use the convention release/<version> for both the branch and the sibling worktree path:
git worktree add -b "release/$NEXT" "../release-$NEXT" origin/main
cd "../release-$NEXT"
This is what makes the skill safe to invoke from any worktree: the bump happens against a fresh checkout of origin/main, not against the maintainer's current branch. The branch name encodes the target version so reviewers can tell at a glance what the PR ships.
-
Bump. From the new worktree, run pnpm bump-version. The script reads the root package.json version from git show HEAD:package.json (in this worktree, HEAD is origin/main), computes the next release version, and writes it to every workspace package.json via scripts/set-version.ts.
Note: bump-version requires node_modules to resolve its dependencies (e.g. pathe). If the fresh worktree has no node_modules, run pnpm install --frozen-lockfile --ignore-scripts first.
Then confirm the version it wrote matches $NEXT from step 1. A mismatch means the helper in your original checkout has diverged from origin/main (step 1 ran the local copy); the worktree's value is authoritative — remove the worktree and branch, and restart from step 1 using the value the bump printed.
-
Refresh the lockfile. Workspace-internal dependencies in this repo are pinned as workspace:<version> (not workspace:*), so the bump changes their specifiers in pnpm-lock.yaml. Run:
pnpm install --lockfile-only
to update pnpm-lock.yaml in lockstep. Without this step, CI fails with ERR_PNPM_OUTDATED_LOCKFILE on the release PR.
-
Sanity-check the diff. Confirm:
- Every modified file is either a
package.json or pnpm-lock.yaml.
- The
package.json diffs are exactly version field changes plus internal workspace:<old> → workspace:<new> specifier bumps (no other fields).
- The
pnpm-lock.yaml diff is exactly specifier: workspace:<old> → workspace:<new> lines (no resolution churn for external packages).
-
Commit. Stage package.json files and pnpm-lock.yaml together in a single commit:
chore(release): bump to <version>
No body is required — the PR description will explain the bump in detail.
-
Draft the release notes. From inside this release/<version> worktree, run the draft-release-notes skill for <version>. It enumerates the merged PRs since the previous stable v* tag, triages which are user-facing, categorizes them (breaking changes first), writes docs/releases/v<version>.md, and prepends a matching CHANGELOG.md entry — committing both on the release branch as their own commit. Committing the notes here is what lands them in the bump PR diff, so the PR-mode check:release-notes gate passes and the maintainer reviews the notes as part of the release PR.
-
Push the branch to origin.
-
Open the PR with gh pr create. Use the title:
Bump to version <version>
The body should:
- State the previous and new version (
<previous> → <new>).
- Link to
docs/oss/versioning.md for context.
- Point reviewers at the committed
docs/releases/v<version>.md (authored by the draft-release-notes skill in step 7) as the human-review surface for the release's user-facing changes.
- Note that merging this PR ships the release: the resulting push to
main carries the bumped root version, the Publish to npm workflow detects the change and publishes <new> under dist-tag latest, and a matching GitHub Release (marked pre-release on the RC line) is created automatically.
-
Stop and report the PR URL and the worktree path to the maintainer. The maintainer can git worktree remove ../release-<version> after the PR merges. Do not merge the PR yourself; the merge is a human gate where someone confirms the release notes are acceptable. (Merging triggers the publish — there is no separate dispatch step.)