84 lines
3.8 KiB
Markdown
84 lines
3.8 KiB
Markdown
# Release Checklist
|
|
|
|
The release captain's checklist for every lane. The mechanics live in
|
|
[`RELEASING.md`](RELEASING.md); the user-facing channel guide is
|
|
[`CHANNELS.md`](CHANNELS.md).
|
|
|
|
## Canary (automatic, every `master` push)
|
|
|
|
- [ ] the push's `Release` run is green (verify + publish)
|
|
- [ ] `npm view paperclipai@canary version` matches the expected canary
|
|
- [ ] Docker `:canary` updated (the same push's `Docker` run)
|
|
- [ ] a canary publish failure is a release-infra regression — fix it before
|
|
trusting later promotions
|
|
|
|
## Nightly (automatic, 09:00 UTC)
|
|
|
|
- [ ] the scheduled run selected the newest green canary, or skipped with a
|
|
job-summary reason (no new candidate / already shipped / red smoke)
|
|
- [ ] the release smoke suite passed against the exact candidate canary
|
|
before anything published
|
|
- [ ] `npm view paperclipai@nightly version` shows the new `-nightly.N`
|
|
- [ ] `nightly/v*` tag pushed; `:nightly` and `:nightly-cloud` images built
|
|
- [ ] on a tag-push rejection (workflows-permission error), follow the
|
|
recovery commands in the job summary
|
|
|
|
To force a nightly: dispatch `release.yml` with `channel: nightly`
|
|
(optional exact canary in `source_version`; `dry_run` to preview).
|
|
|
|
## Beta (manual promotion)
|
|
|
|
Happy path:
|
|
|
|
- [ ] pick the nightly to promote (empty `source_version` selects the newest)
|
|
- [ ] dispatch `release.yml` with `channel: beta`
|
|
- [ ] approve the `npm-beta` environment gate
|
|
- [ ] `npm view paperclipai@beta version` shows the new `-beta.N`
|
|
- [ ] `beta/v*` tag pushed; `:beta` and `:beta-cloud` images built
|
|
- [ ] post-publish smoke (`smoke_beta`) is green
|
|
- [ ] `draft_stable_notes` pushed `release-notes/v<beta-version>`; open the
|
|
notes PR from the job-summary link
|
|
- [ ] during the soak: edit the notes PR into release voice and merge it
|
|
(the stable promotion reads `releases/beta/v<beta-version>.md` from
|
|
`master`)
|
|
|
|
Fix path (cherry-picked candidate):
|
|
|
|
- [ ] cut `candidate/beta-<target>` from the chosen nightly's source commit
|
|
- [ ] cherry-pick only the required fixes; push the branch
|
|
- [ ] dispatch `channel: beta` with `candidate_branch`
|
|
- [ ] confirm the job summary records the cherry-picked commits and that
|
|
full verification ran on the candidate head
|
|
- [ ] after shipping: reconcile the fixes to `master`, delete the branch
|
|
|
|
## Stable (manual promotion)
|
|
|
|
- [ ] pick the beta to promote; its source commit is `source_ref`
|
|
- [ ] the beta has soaked ≥ 3 days with no open beta-blocker issues
|
|
- [ ] the beta's notes PR (`releases/beta/v<beta-version>.md`) is merged on
|
|
`master` — preflight fails, before the approval gate, without it
|
|
- [ ] dispatch `release.yml` with `channel: stable` (a dry run first shows
|
|
the resolved version and soak state without publishing)
|
|
- [ ] approve the `npm-stable` environment gate
|
|
- [ ] `npm view paperclipai version` (dist-tag `latest`) shows the stable
|
|
- [ ] `vYYYY.MDD.P` tag pushed; GitHub Release created; `:latest` and the
|
|
versioned Docker tags built
|
|
- [ ] if the soak gate was bypassed, `skip_soak_justification` carries a
|
|
real written reason (it lands in the job summary)
|
|
- [ ] open and merge the canonicalization PR
|
|
(`release-notes/v<version>-canonicalize`) so the notes land at
|
|
`releases/vYYYY.MDD.P.md`
|
|
|
|
Fix path: `candidate/release-<target>` from the beta's source commit; the
|
|
soak gate will demand a justification because the exact bits were not
|
|
soaked — write one that stands on its own. A candidate branch carries its
|
|
own `releases/vYYYY.MDD.P.md` (preflight prefers source-tree notes), so
|
|
author the notes as a commit on the candidate.
|
|
|
|
## After any incomplete run
|
|
|
|
The failure playbooks in [`RELEASING.md`](RELEASING.md) cover: red canary,
|
|
skipped or failed nightly, a beta that looks bad during soak, partial
|
|
stable releases, broken `latest`, and rejected tag pushes. Every publish
|
|
job's summary names what completed and what remains.
|