0013. Releases cut versions and promote prod
- Status: accepted
- Date: 2026-10-12
Context
ADR 0012 promoted every merge to main onto pixel-prod after GitHub Environment prod approval. The Release workflow also ran on those pushes and cut CHANGELOG.md Unreleased into a version. Because that bump commit uses GITHUB_TOKEN, it does not start CD, so prod often ran the pre-bump SHA.
Thomas asked to stop deploying prod on every merge. Unreleased notes should accumulate on main until a human cuts a release. The VitePress site in docs/ should ship as that same release, not on every docs change to main.
Decision
- Merges to
main:.github/workflows/cd.ymlstill publishesghcr.io/pixelbar/pixel:<sha>and:main, and uploads Sentry source maps. It does not log in to Azure, does not use GitHub Environmentprod, and has no path topixel-prod. It does not publish the docs site. - A human cuts a release:
.github/workflows/release.yml(workflow_dispatchonmain). It runsjust bump --commit(Added → minor, Fixed/Changed → patch, never major before 1.0), pushes theRelease vX.Y.Zcommit and tag, opens a GitHub Release with those notes, rebuilds GHCR from that commit (:<sha>,:vX.Y.Z,:main), uploads Sentry maps for Sentry environmentprod, publishes the VitePress site to GitHub Pages, then theprod-cdjob (GitHub Environmentprod) rollspixel-prodto that same digest withaz containerapp update. It does not apply Terraform. Approvers stay on Environmentprod(required reviewers, branchmain). - Azure
dev: stilljust deploy-dev. CI still does not deploy pull requests. - Docs PRs:
.github/workflows/docs.ymlstill builds the site on pull requests that touchdocs/. Publishing frommainis the Release workflow.workflow_dispatchon Docs site remains an escape hatch to republish without a version bump. - Never copy
pixel-dev-kv, the Mini.env, or the Pixel Dev bot token into prod.
This supersedes ADR 0012's promotion-on-merge clause. infra/envs/prod, Environment prod OIDC, and "no Terraform apply from CD" stay as 0012 decided.
Consequences
- Unreleased changelog entries sit on
mainuntil someone runs Actions → Release → Run workflow onmain. - The image prod runs includes the bumped
package.jsonversion (/ping), not the merge SHA from before the bump. - If Azure or Pages fails after the tag exists, use Re-run failed jobs. Re-running every job also works: HEAD is already
Release vX.Y.Zand Unreleased is empty, so the bump job continues that version instead of failing. - After a command-changing release,
just registerstill needs a prod.envon a laptop. The GitHub identity is Contributor on the RG, not Key Vault Secrets User.