From 4b554123090f62f8a2c8160fda43277d923d4732 Mon Sep 17 00:00:00 2001 From: Joe Ferner Date: Wed, 2 Sep 2026 21:42:20 -0400 Subject: [PATCH] Correct the merge advice for a library release The note added with 0.2.0 said the merge in step 4 "needs `gh pr merge --admin`". It was written from the shape of the problem rather than from having run it, and when it was run the merge came back with `Required status check "package verifies" is failing` despite the account holding admin on the repository. The reason is that `main` is protected by a ruleset, not by classic branch protection, and the two differ exactly here: a ruleset grants bypass only to the actors named in `bypass_actors`, so an empty list refuses a repository admin like anyone else. Whether `--admin` works is therefore a property of the ruleset's configuration and not of who is running it, which is worth a reader checking rather than assuming. The section now gives both routes and what each costs. The second one is worth having written down even where the bypass is available: dispatching the release job against the branch publishes the version, which turns the one red check green on its own and lets the pull request merge with no bypass at all. That is safe to follow with a tag on `main` because the publish step already asks the sparse index whether the version exists and skips it if so -- the idempotence that was put there for re-running a failed release turns out to make this ordering work too. --- RELEASING.md | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/RELEASING.md b/RELEASING.md index 0f03d76..7482d13 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -85,15 +85,33 @@ path dependency is stripped when packaging, which is the point of writing both a `version` and a `path` — and a version that is not there yet fails the CLI's release before it starts. -**So `package verifies` is red from step 2 until step 5, and that is the -expected state rather than a fault.** Once step 2 has raised the CLI's +**So `package verifies` is red from step 2 until the publish, and that is +the expected state rather than a fault.** Once step 2 has raised the CLI's requirement, every other job is green and that one job asks crates.io for -a version this release has not published yet. It cannot be made to pass -earlier: publishing is what fixes it. Since the ruleset lists it among the -required checks, merging in step 4 needs `gh pr merge --admin` — the one -place in either release where a protection is deliberately stepped over, -and the reason to do the publish immediately rather than leaving `main` -sitting in that state. +a version this release has not published yet. Nothing in the pull request +can make it pass; publishing is what fixes it. Since the ruleset lists it +among the required checks, the merge in step 4 has to get past a check +that cannot go green first, and there are two ways: + +- **Bypass it**, with `gh pr merge --squash --admin`. This works only if + the `main` ruleset grants a bypass actor. A ruleset is not classic + branch protection: with `bypass_actors` empty it refuses a repository + admin as flatly as anyone else, and `--admin` comes back with + `Required status check "package verifies" is failing`. Check with + `gh api repos/:owner/:repo/rulesets/ --jq .bypass_actors` before + planning around it. +- **Publish first, then merge with no bypass at all.** Dispatch the + release job against the release branch — + `gh workflow run release.yml --ref -f package=ota` — which is + what the `package` input exists for, since a dispatch has no tag to + read. crates.io then has the version, `package verifies` goes green on + a re-run, and the pull request merges normally. Tagging `main` + afterwards is safe: the publish step asks the sparse index first and + skips a version that is already there, so the tag lands where the + changelog's link expects it without publishing twice. + +Either way the publish wants doing promptly rather than leaving `main` +sitting with a red required check. **What counts as breaking:** the Rust API as usual, and the bundle format itself. A change to the container's bytes is breaking in a way a semver