mirror of
https://github.com/block/buzz.git
synced 2026-10-27 04:30:52 +00:00
feat(release): support version-matched mobile stable branches (#8430)
Mobile candidates currently require the current `main` commit, so a stable release branch cannot publish through the existing protected tag workflow. Add optional `--source-branch mobile-vMAJOR.MINOR` selection while preserving `main` as the default. Both the command and App-backed publisher reject a stable branch whose major/minor differs from the requested version. Candidates retain exact-tip checks and immutable annotated tags; the private build pipeline is unchanged. Document the temporary stable-only distribution policy and explicit per-fix backport decisions. No candidate, build, or upload is triggered by this change. No duplicate implementation was found among open release PRs. Stable publication now checks active review and status-check protection in both the operator and publisher. The process permits approved backport PRs and stable-only corrections for regressions caused by earlier backports. Administrator activation and verification of the no-bypass ruleset remain outstanding; non-admin API responses hide the bypass actor list. ### Validation - Full local `just ci` passed during preparation; the final changes affect shell release tooling, its workflow inputs, CI path detection, and documentation. - Publisher contract passed, including version-matched stable sources and mismatched branch rejection. - Operator contract covers default main, a divergent stable commit, missing or mismatched sources, immutable sequencing, and publication races. The final operator contract run passed. - Updated publisher and operator contracts pass, including 17 weakened-policy cases and rejection of unavailable protection. The live, currently unprotected stable branch is rejected. --------- Signed-off-by: Tom Brow <tomb@block.xyz>
This commit is contained in:
75
RELEASING.md
75
RELEASING.md
@@ -1,7 +1,8 @@
|
||||
# Releasing Buzz
|
||||
|
||||
Buzz has three independent release lanes. Desktop and relay use release PRs.
|
||||
Mobile uses immutable release-candidate tags cut directly from remote `main`:
|
||||
Mobile uses immutable release-candidate tags cut from remote `main` by default,
|
||||
with an optional stable source branch:
|
||||
|
||||
| Lane | Entry point | Artifact |
|
||||
|------|-------------|----------|
|
||||
@@ -38,7 +39,8 @@ scripts/mobile-release.sh candidate 0.5.0
|
||||
Desktop uses an immutable generated candidate PR; relay continues using its
|
||||
metadata PR. Mobile does not. Each `mobile-vX.Y.Z-rc.N` tag is an immutable
|
||||
candidate and the artifact of record.
|
||||
There is no mobile release branch, stable mobile tag alias, finalization step,
|
||||
Optional stable branches use `mobile-vMAJOR.MINOR`. There is no
|
||||
stable mobile tag alias, finalization step,
|
||||
or mobile GitHub Release.
|
||||
|
||||
---
|
||||
@@ -153,10 +155,47 @@ RC tags. For example, iOS can ship `mobile-v0.5.0-rc.2` while Android ships
|
||||
There is intentionally no single selected or final candidate for the marketing
|
||||
version.
|
||||
|
||||
The simplification trades away a separate stabilization line. Unrelated commits
|
||||
that reach `main` become part of every later candidate, and there is no retained
|
||||
hotfix branch or branch-ancestry history. Add a dedicated hotfix flow later if a
|
||||
release actually needs isolation from `main`.
|
||||
### Optional stable release branches
|
||||
|
||||
For a release that needs isolation from ongoing development, create a branch
|
||||
such as `mobile-v0.25` from an explicitly selected, verified source commit.
|
||||
Publish candidates from its current remote tip:
|
||||
|
||||
```bash
|
||||
scripts/mobile-release.sh candidate 0.25.0 --source-branch mobile-v0.25
|
||||
```
|
||||
|
||||
The branch must match the marketing version's major and minor components:
|
||||
`mobile-v0.25` accepts 0.25.x, but rejects 0.26.x and 1.25.x. Without the option,
|
||||
the source remains `main`. Both the operator and publisher validate the source;
|
||||
a missing branch or changed tip fails rather than falling back to `main`.
|
||||
The GitHub workflow itself continues to run from reviewed `main`. The private
|
||||
pipeline still builds only the resulting immutable candidate tag.
|
||||
|
||||
For the October 2026 stabilization period, all distributed mobile builds,
|
||||
including Company Portal dogfood builds, must come from `mobile-v0.25` until
|
||||
after the conference. Do not upload builds from `main` or a later minor version
|
||||
that would displace the stable dogfood build. The branch starts from
|
||||
`mobile-v0.24.0-rc.2`, the source of uploaded iOS 0.24.0 (7).
|
||||
|
||||
General fix PRs must target `main` and land there first. At each fix landing,
|
||||
ask the release owner whether to
|
||||
backport the merged commit to the stable branch. For each explicitly approved
|
||||
fix, cherry-pick with `-x --signoff` onto a backport branch and open a backport-only
|
||||
PR targeting the stable branch. Require review and passing checks before merging
|
||||
that PR. Preserve the original commit provenance and validate the resulting
|
||||
stable source. A correction for a regression introduced by an earlier backport
|
||||
may target the stable branch directly; identify the faulty backport and keep the
|
||||
correction scoped to that regression. The same review and checks apply.
|
||||
Never merge `main` wholesale.
|
||||
Remote agents and App Clip are post-conference work. There is no preselected
|
||||
fix list and no requirement to create a stable branch for every minor release.
|
||||
|
||||
The initial 0.25.0 candidate uses an empty commit above that baseline to verify
|
||||
that the existing pipeline builds a commit outside `main`. Verify identical
|
||||
source trees, absence of that commit from remote `main`, and the exact tag,
|
||||
commit, marketing version and build number in the uploaded artifacts. Upload
|
||||
and external TestFlight review do not establish production App Store approval.
|
||||
|
||||
`mobile/pubspec.yaml` keeps `0.0.0+1` only as a valid, visibly non-release
|
||||
fallback for local development and validation builds. Release jobs always
|
||||
@@ -317,8 +356,15 @@ Mobile candidate publication requires workflow-dispatch access and the existing
|
||||
release App because strict tag protection denies direct human creation. The App
|
||||
must be installed on `block/buzz`, have Contents write and Metadata read, and
|
||||
retain an `always` bypass on the immutable `mobile-v*` tag rules. It does not
|
||||
require GitHub Releases permissions, repository Administration permission, or a
|
||||
mobile release-branch ruleset. The publisher validates the App token's effective
|
||||
require GitHub Releases permissions or repository Administration permission.
|
||||
Stable sources additionally require active branch ruleset `19321162` covering
|
||||
`refs/heads/mobile-v*`, with no exclusions or bypass actors, deletion and
|
||||
force-push prevention, at least one approval, stale-approval dismissal, last-push
|
||||
approval, resolved review threads, and strict required `Mobile` and `DCO Check`
|
||||
checks. An administrator must configure and audit the empty bypass list; GitHub
|
||||
hides that list from non-admin tokens. Both operator and publisher verify the
|
||||
public policy and their effective lack of branch bypass on every publication.
|
||||
The publisher validates the App token's effective
|
||||
`current_user_can_bypass` value rather than reading the ruleset's hidden bypass
|
||||
actor list.
|
||||
|
||||
@@ -343,18 +389,19 @@ Commit or stash your changes before running the release recipe.
|
||||
### New commits land after publishing a mobile candidate
|
||||
|
||||
Run `scripts/mobile-release.sh candidate <version>` again after the intended
|
||||
fix reaches remote `main`. It publishes a new immutable RC tag at the new exact
|
||||
fix reaches the intended remote source branch. Use the same `--source-branch`
|
||||
option for a stable release. The command publishes a new immutable RC tag at the new exact
|
||||
remote commit. Continue referring to each tested or shipped platform artifact by
|
||||
its own exact tag.
|
||||
|
||||
### `scripts/mobile-release.sh candidate` fails because `main` moved during publication
|
||||
### `scripts/mobile-release.sh candidate` fails because the source branch moved during publication
|
||||
|
||||
The App-backed workflow may already have published the requested immutable RC
|
||||
at the prior `main` tip before the operator command detects the race. Do not
|
||||
move or delete that tag, and do not treat it as the candidate for current
|
||||
`main`. Inspect the run URL from the command output, then rerun
|
||||
at the prior source branch tip before the operator command detects the race. Do not
|
||||
move or delete that tag, and do not treat it as the candidate for the current
|
||||
source branch. Inspect the run URL from the command output, then rerun
|
||||
`scripts/mobile-release.sh candidate <version>` to publish the next RC from the
|
||||
new current `main` tip.
|
||||
new current source branch tip, preserving the source-branch option.
|
||||
|
||||
### A mobile candidate command selects the wrong RC number
|
||||
|
||||
|
||||
Reference in New Issue
Block a user