forked from heavy-duty/ceremony
README: the re-arm refusal is the rc path, not an unreachable guard
The section called version_next_dev's refusal unreachable by reading decide's sense of 'bare' (not -dev) into version_next_dev's regex (^X.Y.Z$). An rc lives between the two: row 6 admits a labeled rc transition as a shippable ceremony, the bump step gates only on ceremony=yes, and its VER is the tree's version verbatim -- so an rc release tags, notes, publishes, then refuses here. State that path and its remedy (version.sh L78-L82: an rc's next version is a human decision), keep the guard reading for the -dev/garbage half that really is unreachable, and close the same conflation in row 6. Also: version_write runs npm pkg set + a lockfile-only install, not npm version (which would tag); and drop 'unarmed main' so the section uses release.yml's one sense of armed. Reported by claude-bot-andresmgsl on #315.
This commit is contained in:
parent
dac4946e43
commit
052c8734b9
1 changed files with 30 additions and 14 deletions
44
README.md
44
README.md
|
|
@ -160,7 +160,7 @@ block *is* the spec, and the table is contract-tested offline by
|
||||||
| 3 | version bare, unchanged, already released | green `NOTICE`, no-op | The post-release window: the ceremony landed, the `-dev` bump hasn't. Nothing to do. |
|
| 3 | version bare, unchanged, already released | green `NOTICE`, no-op | The post-release window: the ceremony landed, the `-dev` bump hasn't. Nothing to do. |
|
||||||
| 4 | version bare, unchanged, **never released** | **red, nothing created** | The label says ship but this PR did not mint the version. Mislabeled → drop the label. Meant to release → it forgot the bump; re-do the ceremony PR. A repo whose first version never carried `-dev` ships its first release by the **tag door** — the known first-release edge (cast#111; [lib/decide.sh](lib/decide.sh#L70-L74)). |
|
| 4 | version bare, unchanged, **never released** | **red, nothing created** | The label says ship but this PR did not mint the version. Mislabeled → drop the label. Meant to release → it forgot the bump; re-do the ceremony PR. A repo whose first version never carried `-dev` ships its first release by the **tag door** — the known first-release edge (cast#111; [lib/decide.sh](lib/decide.sh#L70-L74)). |
|
||||||
| 5 | version transitioned to bare, **no merged `release`-labeled PR** behind the commit | **red, nothing created** | A transition nobody declared — a release is a labeled ceremony PR, not a bare push. Label a proper ceremony PR and re-do it, or publish by the tag door if the tree is genuinely right. |
|
| 5 | version transitioned to bare, **no merged `release`-labeled PR** behind the commit | **red, nothing created** | A transition nobody declared — a release is a labeled ceremony PR, not a bare push. Label a proper ceremony PR and re-do it, or publish by the tag door if the tree is genuinely right. |
|
||||||
| 6 | version transitioned to bare, merged `release`-labeled PR behind the commit | **the ceremony** | Tag → notes → publish → `-dev` re-arm. Your move afterwards: verify the release exists and main reads `X.Y.(Z+1)-dev`. |
|
| 6 | version transitioned to bare, merged `release`-labeled PR behind the commit | **the ceremony** | Tag → notes → publish → `-dev` re-arm. Your move afterwards: verify the release exists and main reads `X.Y.(Z+1)-dev`. **Read *bare* as decide reads it** — anything not `-dev` ([lib/decide.sh](lib/decide.sh#L108-L110)) — so an rc transition is a shippable ceremony here too, and the release lands but the re-arm stops for you to pick the next version ([The re-arm refused](#the-re-arm-refused-releaseyml)). |
|
||||||
|
|
||||||
The green rows are the point as much as the red ones: the machinery must be
|
The green rows are the point as much as the red ones: the machinery must be
|
||||||
safe to work on, so every legitimate non-ceremony is a green `NOTICE` no-op,
|
safe to work on, so every legitimate non-ceremony is a green `NOTICE` no-op,
|
||||||
|
|
@ -503,22 +503,37 @@ delete and re-push the tag.
|
||||||
The bump belongs to the merge door alone — the tag door deliberately does not
|
The bump belongs to the merge door alone — the tag door deliberately does not
|
||||||
rewrite main ([L303–L307](.github/workflows/release.yml#L303-L307)) — and it
|
rewrite main ([L303–L307](.github/workflows/release.yml#L303-L307)) — and it
|
||||||
runs *after* the tag, the notes and the publish. So a refusal here leaves a
|
runs *after* the tag, the notes and the publish. So a refusal here leaves a
|
||||||
real release behind an unarmed main: the release exists and main still reads
|
real release standing behind a main that never re-armed — the release exists,
|
||||||
the version it just shipped. That is the one failure in this catalog whose
|
and main is left *armed to impersonate* it, still reading the version it just
|
||||||
remedy is a manual bump, not a re-run.
|
shipped ([L266](.github/workflows/release.yml#L266)). That is the one failure
|
||||||
|
in this catalog whose remedy is a manual bump, not a re-run.
|
||||||
|
|
||||||
> version_next_dev: refusing '$ver' — expected bare X.Y.Z
|
> version_next_dev: refusing '$ver' — expected bare X.Y.Z
|
||||||
|
|
||||||
[L86](lib/version.sh#L86): the version reaching the bump is not bare —
|
[L86](lib/version.sh#L86): the version reaching the bump is not bare `X.Y.Z`.
|
||||||
`-dev`, `-rc1`, or garbage. Not reachable through either door as they stand:
|
Two senses of *bare* meet here, and the gap between them is the **rc release
|
||||||
the step runs only on `ceremony=yes`, which rows 5–6 reach only on a
|
path** — the one door an operator actually walks through. decide calls a
|
||||||
transition *to* bare, and the tag door never bumps. Treat it as the guard it
|
version bare when it is not `-dev`
|
||||||
is — it fires if a decide change ever lets a non-bare version through.
|
([version_is_dev](lib/version.sh#L69-L76) matches that suffix and nothing
|
||||||
|
else), so row 6 admits a transition to `1.2.3-rc1`, and a labeled rc ceremony
|
||||||
|
is designed to ship ([lib/decide.sh](lib/decide.sh#L108-L110)).
|
||||||
|
`version_next_dev` means `^[0-9]+\.[0-9]+\.[0-9]+$`. An rc sits between the
|
||||||
|
two, and nothing filters it out on the way: the step's only gate is
|
||||||
|
`ceremony == 'yes'` and its `VER` is the tree's version verbatim. So an rc
|
||||||
|
ceremony tags, writes the notes, publishes — and *then* the re-arm refuses.
|
||||||
|
That is the machine correctly declining to guess rather than a bug: an rc's
|
||||||
|
next version "is a human decision, not arithmetic"
|
||||||
|
([L78–L82](lib/version.sh#L78-L82)), so make the decision and bump main by
|
||||||
|
hand to it. A `-dev` or garbage version reaching this line is the same
|
||||||
|
refusal's other half, and that half really is unreachable as the doors stand —
|
||||||
|
rows 1–2 send `-dev` to a no-op, and the tag door never bumps.
|
||||||
|
|
||||||
> version_write: npm is required for version-source: package-json
|
> version_write: npm is required for version-source: package-json
|
||||||
|
|
||||||
[L106](lib/version.sh#L106): `version_write` shells out to `npm version` on
|
[L106](lib/version.sh#L106): the package-json backend needs npm to write —
|
||||||
the package-json backend, and the runner has no npm. The read path fails the
|
`npm pkg set version=` plus a lockfile-only `npm install`
|
||||||
|
([L102–L112](lib/version.sh#L102-L112)), never `npm version`, which would tag
|
||||||
|
— and the runner has none. The read path fails the
|
||||||
same way one step earlier (`node is required…`, above), so a run reaching
|
same way one step earlier (`node is required…`, above), so a run reaching
|
||||||
*this* message got past the read — set up node/npm in the caller.
|
*this* message got past the read — set up node/npm in the caller.
|
||||||
|
|
||||||
|
|
@ -528,9 +543,10 @@ same way one step earlier (`node is required…`, above), so a run reaching
|
||||||
backend`, and unreachable for the same reason — `VERSION_SOURCE` was validated
|
backend`, and unreachable for the same reason — `VERSION_SOURCE` was validated
|
||||||
before either was called. Fix the caller.
|
before either was called. Fix the caller.
|
||||||
|
|
||||||
In every case main is left armed to impersonate the release it just shipped:
|
In every case the remedy has the same shape — bump `VERSION` (or the
|
||||||
bump `VERSION` (or the `package.json` version field) to `X.Y.(Z+1)-dev` by
|
`package.json` version field) by hand and push: `X.Y.(Z+1)-dev` where the
|
||||||
hand and push. Note that a *push* refusal is not one of these — branch
|
shipped version was bare, and where it was an rc, whatever you have decided
|
||||||
|
comes next. Note that a *push* refusal is not one of these — branch
|
||||||
protection is expected, and the step opens the bump PR itself rather than
|
protection is expected, and the step opens the bump PR itself rather than
|
||||||
failing ([L293–L301](.github/workflows/release.yml#L293-L301)).
|
failing ([L293–L301](.github/workflows/release.yml#L293-L301)).
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue