← Workflows

阅读中文版本

Release Branch Cut and Freeze Workflow

Cut a release branch from main, freeze feature merges into it, and channel last-minute changes through cherry-picks with review gates.

beginner~20 minreleasegitprocess

Objective

Create a stabilized release branch that only receives reviewed fixes, keeping main free for ongoing development.

Environment

  • A main branch with green CI
  • A release calendar or trigger event
  • Cherry-pick and tag permissions on the repository

Steps

1. Verify main is releasable

Run the full CI pipeline on main and confirm tests, security scans, and build artifacts are green before cutting.

Expected state: A green pipeline run with a recorded URL exists for the exact commit being cut.

2. Cut the release branch

Create release/1.8 from the verified commit with a naming convention that encodes the version.

Expected state: The branch exists and its head commit matches the verified green run.

3. Freeze direct merges

Set branch protection on the release branch: no direct pushes, merges only via reviewed PRs labeled fix or cherry-pick.

Expected state: Direct push attempts are rejected by the platform.

4. Define the cherry-pick path

Document that late changes land on main first (or the fix branch), then cherry-pick into release with the original PR link in the description.

Expected state: Every release-branch commit traces to a reviewed PR, none are hand-crafted fixes.

5. Tag the candidate

Tag v1.8.0-rc1 on the release branch and produce build artifacts from that tag only.

Expected state: Artifacts carry the tag, and rebuilding the tag reproduces the same artifact hash.

Decision points

Cut from main or from a stabilization integration branch?

  • Cut from main when trunk stays green
  • Cut from an integration branch when features land broken

Start with main plus a freeze; add an integration branch only if main red-rate makes candidates unstable.

How late can fixes land?

  • Until tagging
  • Until RC2 only

Freeze fixes two working days before final tag to leave room for verification runs.

Expected outcome

A protected release branch whose every commit is a reviewed fix, and release candidates built from immutable tags rather than moving heads.

Verification

Branch protection settings show blocked direct pushes; the release branch log shows only merge commits referencing PRs; the rc1 tag hash matches the shipped artifact.

Freeze is a decision, not a hope

Cutting a release branch without protection just creates a second place where unreviewed changes can appear. The workflow makes the freeze mechanical: branch protection rejects everything except reviewed cherry-picks, and candidates build only from tags.

# cut from a verified green commit
git checkout -b release/1.8 <verified-sha>
git push origin release/1.8

# protect: no pushes, PR-only, required reviews
# every late fix:
git checkout main && git cherry-pick <fix-sha>
git checkout release/1.8 && git cherry-pick <fix-sha>

git tag v1.8.0-rc1 release/1.8 && git push origin v1.8.0-rc1

Fixes flow main-first

Cherry-picking straight into the release branch creates commits that exist nowhere else and will conflict with the next release. The rule that fixes land on main first and are then picked keeps the branches convergent and the fix permanently in the product.

Build from tags, not heads

A release branch head moves with every late fix; a tag does not. Building artifacts from the tag makes the candidate reproducible and lets anyone verify that the shipped bytes came from the reviewed state.