Cutting a Superpipelines Release
Cut a version release after the feature PR(s) are merged into main. Full step detail + gotchas live in RUNBOOK.md — read it before acting.
Hard constraints (read first)
mainis branch-protected. No directgit push origin main. Every change goes through a PR.gh pr merge <n> --squash --adminbypassesREVIEW_REQUIRED(CI must still be green) — confirm with the user before any--adminoverride.- JSON must be BOM-free. Never
Set-Content -Encoding UTF8for JSON. Use the Edit tool orpython3writes (encoding="utf-8"). - 5 version targets must agree before tagging:
package.json,.Codex-plugin/plugin.json,.Codex-plugin/marketplace.json(plugins.0.version— NOT the top-level1.0.0),.cursor-plugin/plugin.json,AGENTS.md(- **Project Version**: vX.Y.Z). First 3 listed in.version-bump.json; last 2 are manual. - Tag ↔ changelog convention: every tag
vX.Y.ZMUST have a matching## X.Y.ZCHANGELOG entry and a## vX.Y.ZRELEASE-NOTES entry beforegh release create. - gh CLI in Bash tool: never
--body @'...'@(PowerShell here-string, fails). Write the body to a temp.md, use--body-file, thenrmit. Keep temp files out of commits.
Workflow
- Preflight —
git fetch origin; confirmorigin/mainhas the feature merge; verify all 5 version targets agree and equal the intended vX.Y.Z (npm run check:versionscovers 6 including.codex-plugin); check tag/release naming convention (vX.Y.Z — <Title Case Name>). Profile-drift check: confirm the latest "Profile drift review" issue (opened monthly by.github/workflows/profile-drift.yml) is closed or its findings are consciously deferred in the release notes; amodel_tiers_versionolder than 90 days blocks unless deferred. - Sync local main —
ExitWorktree action:keepif in a worktree;git checkout main && git pull --ff-only origin main(clear stale untracked blockers first — diff againstorigin/main). - Draft doc entries — add
## X.Y.ZtoCHANGELOG.mdand a<release_entry>toRELEASE-NOTES.md, mirroring the previous entry's format exactly. Source bullets from real changes; do not invent. - Land docs via PR — branch
release-notes-X.Y.Z, commit, push,gh pr create(--body-file), wait for CI pass, confirm intent,gh pr merge --squash --admin --delete-branch, re-sync main. - Create release + tag — extract the new CHANGELOG section as the release body, append the install line,
gh release create vX.Y.Z --target main --title "vX.Y.Z — <Title>" --notes-file <tmp>. - Verify — tag commit ==
origin/main; release not draft/prerelease;Closes #Nissues CLOSED; follow-up issues still OPEN. - Aiboarding pointer (optional) — if release docs don't touch the 3 AIBOARDING sections, no-op advance
last_synced_committo HEAD via the same PR +--adminflow. Expect one residual drift nag on the bump commit — STOP, do not chase.
Gotchas checklist
- Bumped
plugins.0.versionin marketplace.json, not top-level1.0.0. - All 5 version targets agree before tagging (
npm run check:versions). - Latest profile-drift review issue closed or explicitly deferred.
- CHANGELOG + RELEASE-NOTES entries exist before
gh release create. - Used
--body-filefor all gh bodies (never@'...'@). - No direct push to main — everything via PR.
- Got user OK before any
--adminoverride. - Temp files cleaned up, kept out of commits.