Skip to content

Ship a release

Merge the release PR and confirm the new commit is live on every Worker it touched.

You need:

Merge to main

You do not deploy. Every merge lands in the one open release PR (chore(main): release <version>).

Read the plan on the release PR

The sticky comment marks each Worker deploy or skip, with the commit it serves and the changed inputs. An unrecognised path deploys everything and names itself; classify it in src/deploy/affected.ts.

Merge the release PR

Merging tags the version, publishes the release, and deploys the marked Workers in this order:

The run also publishes the images as ghcr.io/<owner>/<repo> (bot), -resident and -sandbox, at :<version> and :latest, with provenance and an SBOM (Deploy verifies one). A third job publishes @coreplane/switchboard to npm only for a release cut from the default branch and only while the variable SWITCHBOARD_PUBLISH_NPM is true — turn it off before merging a release PR and that release ships everything but the package — on the run's own identity — npm trusts this workflow as the package's publisher, so no token is stored anywhere (Configure the repository).

Confirm it is live

Deployed is not live. The bot step is done when /healthz reports a container running the release commit; the old one answers during the handoff, up to 15 minutes while a ship pipeline finishes.

See what any PR would deploy

Every PR's deploy targets check shows the same table against the PR's base. From a checkout:

bash
npm run cli -- deploy plan --affected                      # against what production serves
npm run cli -- deploy plan --affected --base origin/main   # against a ref

Deploy by hand, rarely

A failed release deploy or a deliberate full roll goes through the workflow, never a laptop. It refuses any ref but main.

bash
gh workflow run deploy-production.yml --ref main -f targets=affected   # the default: what is stale
gh workflow run deploy-production.yml --ref main -f targets=all
gh workflow run deploy-production.yml --ref main -f targets=bot,resident
gh workflow run deploy-production.yml --ref main -f targets=bot -f force=true   # bypasses the preflights — say why in the run

Next