docs: describe merge-door resume recovery
Some checks failed
CI / action-exercise (pull_request) Successful in 29s
CI / self-guards (pull_request) Failing after 32s
CI / release-exercise (pull_request) Successful in 39s
CI / docs-sync-exercise (pull_request) Successful in 12s
labels / labels (pull_request) Successful in 14s
Refs guard / refs-not-closing (pull_request) Successful in 11s
CI / test (pull_request) Failing after 1m11s

This commit is contained in:
codex-bot-andresmgsl 2026-08-31 11:21:09 +00:00
parent 7bd331a44d
commit 79e747b163
4 changed files with 19 additions and 16 deletions

1
.github/labeler.yml vendored
View file

@ -46,6 +46,7 @@ scope:release-flow:
- CHANGELOG.md
- drills/**
- test/decide.test.sh
- test/preflight.test.sh
- test/facts.test.sh
- test/release-chain.test.sh
- test/version.test.sh

View file

@ -19,6 +19,7 @@ printf '%s\n' \
bin/ \
lib/version.sh \
lib/decide.sh \
lib/preflight.sh \
lib/facts.sh \
lib/changelog.sh \
lib/forge.sh

View file

@ -127,12 +127,13 @@ steps run past the tag, and what a failure at each leaves behind is what
sorts them. Two fail before the release exists: the consumer's
[artifact hook](docs/CONSUMERS.md#the-artifact-hook) sits between the tag and
the publish, so its non-zero exit aborts, and the publish itself
([`forge_release_create`](.github/workflows/release.yml#L255-L268))
([`forge_release_create`](.github/workflows/release.yml#L264-L277))
can fail on the API call or the assets. Either leaves the same state — a tag
standing and no release — which the
[nothing-exists assert](#the-merge-door-refused-releaseyml) names and the tag
door recovers. The third is the re-arm, which runs after the publish, and its
refusal is the single failure in this file that leaves a real release behind.
standing and no release — which the merge-door preflight recognizes and a
re-run resumes. The tag door remains the fallback when the original run is no
longer reachable or the release must come from a fixed tree. The third is the
re-arm, which runs after the publish, and its refusal is the single failure in
this file that leaves a real release behind.
## The two doors
@ -482,18 +483,17 @@ without its stamp (a state the
the PR — red main here means it was overridden). Stamp the section on main,
then publish by the tag door.
> tag '$VER' already exists — this release already happened, or a manual tag won the race; refusing to re-release, creating nothing.
> release '$VER' already exists — refusing to re-release, creating nothing.
> release '$VER' already exists — this release already happened; refusing to re-release, creating nothing.
> tag '$VER' already exists at <tag sha> but this run would tag <MERGE_SHA> — a manual tag won the race, or it names a different commit; refusing to re-release, creating nothing. Delete that tag, or re-tag the merge commit.
> NOTICE: tag '$VER' already stands at this merge commit and no release exists — a previous run of this door tagged and then failed to publish. Resuming: the tag is not recreated; the artifact hook and the publish run.
[L208L223](.github/workflows/release.yml#L208-L223), the nothing-exists
assert — what makes a re-run of a completed ceremony refuse instead of
clobber, and what catches a manual tag racing the merge. If the release
truly exists, there is nothing to do: this red is the system declining to do
the thing twice. If the tag exists but the release does not (a manual tag
won the race, or
[a failed artifact hook](docs/CONSUMERS.md#the-artifact-hook), or the publish
step itself failing after the tag), recover by the tag door: delete and
re-push the tag, or run `forge_release_create` by hand from a fixed tree.
[L208L239](.github/workflows/release.yml#L208-L239), the merge-door
preflight — the published-release refusal prevents clobbering, the
different-commit refusal diagnoses a racing or manual tag with both SHAs, and
the notice resumes this door after its tag succeeded but the artifact hook or
publish failed. Re-run the merge-door job first. If that run is no longer
reachable or the tree itself needs repair, use the tag-door fallback: delete
and re-push the tag from the fixed tree, or run `forge_release_create` by hand.
> direct push refused (branch protection?) — opening the bump PR instead

1
changelog.d/273.md Normal file
View file

@ -0,0 +1 @@
- Merge-door release reruns resume after a matching stranded tag while completed or conflicting releases still refuse with precise diagnostics (#273).