docs/release.md had grown into one page that mixed the release model, the CI pipeline, changelogs, signatures, nightlies and the fires seen at release time. A reader looking for one of them read all of it, and an edit to one part reflowed the rest. It now indexes one page per topic under docs/release/. The pages already describe how fixes reach a release line through the backport batch, which the following commits add. Workflows, scripts and tests that named docs/release.md now point at the page that holds the text they mean. Assisted-By: LLM Signed-off-by: Myasnikov Daniil <myasnikovdaniil2001@gmail.com>
6.2 KiB
Patch Releases
A patch release now follows exactly the same shape as a regular release — by the time vX.Y.0 ships, everything is already happening on release-X.Y. The only difference is where the line starts:
release-X.Yalready exists, created by the freeze atvX.Y.0-rc.1, so there is no branch to create.- Patch commits are cherry-picked onto it, and the rc is cut by dispatching from
release-X.Y— the same dispatch used forrc.2of the original release.
Let's assume that we've released v1.2.0 and that development is ongoing. We have introduced a couple of new features and some fixes to features that we have released in v1.2.0.
Once problems were found and fixed, a patch release is due.
gitGraph
commit id: "feature 3" tag: "v1.2.0-rc.1"
branch release-1.2
checkout release-1.2
commit id: "Release v1.2.0" tag: "v1.2.0"
checkout main
commit id: "feature 4"
commit id: "patch 1"
commit id: "feature 5"
commit id: "patch 2"
-
Fixes reach the existing
release-1.2branch frommainthrough the backport batch, which cherry-picks what the backport policy admits and nothing else.The batch runs twice a week, so a fix merged into
mainreaches the line with the next batch that can pick it cleanly, without anyone asking for it.gitGraph commit id: "feature 3" tag: "v1.2.0-rc.1" branch release-1.2 checkout release-1.2 commit id: "Release v1.2.0" tag: "v1.2.0" checkout main commit id: "feature 4" commit id: "patch 1" commit id: "feature 5" commit id: "patch 2" checkout release-1.2 cherry-pick id: "patch 1" cherry-pick id: "patch 2"Merge the open batch pull request first. Before the cut,
./backport-batch check --line release-1.2 --cut(build it withgo build ./cmd/backport-batch) has to exit 0: it exits 1 while a fix the rules take is not on the line, including one that is only on the open batch pull request, which the cut would not carry, and prints the URLs; it prints what the batch deferred as warnings. See Cherry-pick triage before a patch. -
The maintainer cuts a release candidate (
v1.2.1-rc.N) via theCut Pre-release Tagworkflow (manual dispatch fromrelease-1.2), which tags that branch'sHEAD. CI builds and publishes the rc, pushes therelease-1.2.1-rc.Nstaging branch, and runs the mandatory fullrc-e2ejob against the published tag. -
Watch
rc-e2eand wait for it to pass, then complete the other release checks. A successful manuale2e-tag.yamlrun forv1.2.1-rc.Nis also valid evidence if the latesttags.yamlrun does not carry a greenrc-e2e. Optional: press theGenerate RC Changelogbutton (changelog-rc.yaml) to generatedocs/changelogs/v1.2.1.mdat rc time and bank it on the rc staging branch; promotion then reuses it instead of regenerating. -
Once the checks are green, run
promote-rc.yaml(manual dispatch frommain, as for every promotion, not fromrelease-1.2) with that rc tag. It runs the same five jobs as a regular promotion: the dispatch first gates on the latest tag-pushrc-e2eor a successful tag-correlated manual E2E run (skip_e2e_gateoverrides it), verifies thatrelease-1.2already carries the candidate-aware pipeline, then commits and publishes the rewritten packages tree under a run-specific temporarypromotion-*tag, adds a second commit pinning the candidate on therelease-1.2.1branch, drafts thev1.2.1release with the restamped assets, generates or picks updocs/changelogs/v1.2.1.mdand commits it onto that branch, opens the parkedcozystack/websitedocs PR (updating the existingv1.2/directory in place, since a patch does not promotenext/), and opens the promote PR intorelease-1.2with only thereleaselabel. The promote PR body carries the same ✅/⚠️ E2E, changelog, and website-docs lines and runs no E2E by default; addfull-e2emanually to force a repeat. As with a regular release every stable name is deferred to merge; retention protects the temporary candidate while this PR is open and, after it merges, whilerelease-1.2still pins it — until finalize retags it stable.gitGraph commit id: "feature 3" tag: "v1.2.0-rc.1" branch release-1.2 checkout release-1.2 commit id: "Release v1.2.0" tag: "v1.2.0" checkout main commit id: "feature 4" commit id: "patch 1" commit id: "feature 5" commit id: "patch 2" checkout release-1.2 cherry-pick id: "patch 1" cherry-pick id: "patch 2" tag: "v1.2.1-rc.1" branch release-1.2.1 commit id: "Prepare release v1.2.1" checkout release-1.2 merge release-1.2.1 id: "Pull request"Finally, when release is confirmed, the release sequence goes on.
-
Maintainer reviews the PR against the Phase 4 checklist, confirms the E2E-verification and changelog lines and notes the parked website-docs line, and merges it — do not squash-merge. GitHub removes the merged branch
release-1.2.1(auto-delete-on-merge is enabled). -
CI workflow triggers on merge (all consumer-visible or write-once side effects, after the rc E2E gate and PR review):
- Verifies the pinned packages candidate against the merged tree and the original rc artifact's container digests.
- Creates the tag
v1.2.1at the newly created merge commit — write-once. The tag is published here for the first time, never moved. - Cuts the write-once
api/apps/v1alpha1/v1.2.1Go-module tag at the same commit. - Publishes the release page (
draft→latest;latestmoves only ifv1.2.1is the newest published stable). - Retags the verified packages candidate and rc container images by digest to
v1.2.1and publishes the stablecozy-installerchart — no container rebuild.
-
Once the release is published, merge the parked
cozystack/websitedocs PR, then announce the release to the community.