Back to Paperclip

Release Checklist

doc/RELEASE-CHECKLIST.md

2026.824.03.8 KB
Original Source

Release Checklist

The release captain's checklist for every lane. The mechanics live in RELEASING.md; the user-facing channel guide is 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 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.