ci: move the release cut into a GitHub Actions workflow - #28
Merged
Conversation
Releases previously required running ./release.sh locally. Add a 'Cut Release' workflow that runs release.sh in CI: bump package.json, run the full gate (typecheck against the live prod OpenAPI spec, lint, test, build), then commit, tag, and push. The v* tag push triggers the existing release.yml publish pipeline unchanged. release.sh changes are minimal and keep it usable locally: - CI mode (CI env set): version arg required, branch must be main, no interactive prompts - RELEASE_DRY_RUN=1: run the bump and all checks, then revert and exit before commit/tag/push The workflow pushes with a RELEASE_PUSH_TOKEN PAT secret rather than GITHUB_TOKEN, because tags pushed with GITHUB_TOKEN do not trigger other workflows (release.yml would never fire).
…ored PAT Replace the RELEASE_PUSH_TOKEN fine-grained PAT with the org-standard pattern: load coreplane-bot GitHub App credentials from the 1Password CI vault (op://CI/coreplane-bot) via load-secrets-action, mint a short-lived App installation token with create-github-app-token, and hand that to actions/checkout so release.sh's push still triggers release.yml. Dry runs skip the 1Password/App-token steps entirely and check out with the default read-only GITHUB_TOKEN, so they keep working without any secret configured. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LekzRRztX696SLGyefENYm
boristane
approved these changes
Aug 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by boris · Slack thread
Before: cutting a release means boris runs
./release.shon his laptop — it bumpspackage.json, runs the checks, commits, tags, and pushes; the tag push then triggers the existingrelease.ymlpublish pipeline.After: a Cut Release workflow in the Actions tab does the same thing. Pick "Cut Release" → Run workflow → enter the version (e.g.
0.3.0). Everything downstream (release.yml: npm publish, GitHub release, Homebrew bump) is unchanged and still triggers off thev*tag.How
The workflow (
.github/workflows/cut-release.yml) runsrelease.shitself rather than duplicating its logic in YAML — one source of truth. The script got two minimal, backwards-compatible edits (it still works locally exactly as before):CIis set): no interactive prompts — the version argument is required and the branch must bemain, otherwise it dies.RELEASE_DRY_RUN=1: runs the version bump and the full gate, then reverts the bump and exits before committing/tagging/pushing.The order of operations is preserved: typecheck (codegen against the live prod OpenAPI spec — the hard gate that protects fresh installs from polylane.com), lint, test, and build all run before anything is committed, tagged, or pushed. If any check fails, no tag is created and
release.ymlnever fires.One non-obvious detail: the workflow pushes the version-bump commit and tag using a short-lived coreplane-bot GitHub App token, minted at run time from App credentials loaded out of the 1Password CI vault (the org-standard pattern used by our other repos) — not the default
GITHUB_TOKEN. Tags pushed withGITHUB_TOKENdeliberately do not trigger other workflows, sorelease.ymlwould silently never run. Dry runs skip the 1Password/App-token steps entirely and check out with the default read-only token, since they never push.Secrets to add
Before the first CI release, add this in repo Settings → Secrets and variables → Actions → New repository secret:
OP_SERVICE_ACCOUNT_TOKENv*tag so the push triggersrelease.yml.The workflow also reads
POLYLANE_API_DOMAIN,POLYLANE_OAUTH_CLIENT_ID, andPOLYLANE_OAUTH_CLIENT_SECRETfor the build gate — these already exist (used bychecks.yml/release.yml), nothing new to add there.Dry run
Run the workflow with dry_run checked: it bumps, runs the full gate (including the live-prod-spec typecheck), then reverts and stops — no commit, no tag, no publish. Dry runs skip the 1Password/App-token steps, so this works even before
OP_SERVICE_ACCOUNT_TOKENis configured — a good first smoke test of this PR.Validation done here
bash -n release.shandactionlinton all workflows: clean.npm ci && npm run typecheck && npm run lint && npm run test && npm run buildagainst the live prod spec: all pass.CI=1 RELEASE_DRY_RUN=1 ./release.sh 9.9.9): bump → all checks → revert, exit 0; the no-version and wrong-branch CI guards both die as intended.workflow_dispatchrun on GitHub (needs the secret and a merge).Generated by Claude Code