actions/changelog-armed — fragment mode: the directory is the arming, and a bad entry fails on its own PR #115
Labels
No labels
attention
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-ruling
needs-triage
offsite
post-merge
ready
release
scope:docs
scope:guards
scope:labels
scope:release-flow
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/ceremony#115
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Part of #112.
actions/changelog-armedasks one question — is there a heading for the next PR's entry to land under, and is it the right one for the state this tree is in — keyed on the tree's version. Under fragments the answer moves: the place a PR's entry lands ischangelog.d/, and a directory is always armed. The guard keeps its name and its question, and gains a second mode (D7).Two things it must not lose. Its header comment's warning — rig#44 and cast#108 both had to revert the naive "always require
## Unreleased" form — stays true and stays in the file, because legacy mode still is that guard. And the box#108 failure it was built for (an entry landing cleanly under a heading that shipped while the PR was open) is structurally impossible under fragments; the file should say so rather than leave a reader wondering what happened to the guard's reason for existing.The consumers are pinned at
0.1.0and adopt on a pin bump. Dual mode (D8) is what lets that happen per repo instead of in one flag day, and it is what lets ceremony's own flip (#117) be a single reviewable PR.Spec
Mode detection:
changelog.d/exists in the tree → fragment mode. Otherwise → legacy mode, which is today's script, behavior-identical, tests unchanged. The directory is the switch because it is the thing the adoption PR creates, so a repo's mode is a property of its tree and never of a flag someone forgets to pass. The action gains an optionalfragments-dirinput defaulting tochangelog.d; the script takes it as a third positional argument, matching the existing<changelog> <version-source>shape.Fragment mode,
-devtree (the everyday case, every PR):changelog.d/must exist and contain its generatedREADME.md— the directory is the arming, and the README is what makes an otherwise-empty directory trackable by git (the.ceremony/README.mdprecedent).CHANGELOG.mdmust have no## Unreleasedsection (D6). Nothing accumulates there any more; one left behind is a second anchor with no owner and no assembler, and prose written into it would never ship.changelog_fragment_problemfrom #114, run over each file, diagnosis reproduced verbatim (D9). This is the real prize: the rules the publisher used to enforce at release time, on main, after the merge, now fail on the PR that wrote the bad entry, where the author is still holding it.Fragment mode, bare tree (the ceremony PR and its merge commit):
changelog.d/must contain no fragments — they were consumed by the assembly. A fragment surviving the ceremony is an entry that silently misses its release.## <ver>— notUnreleased, which no longer exists in this mode — and it must be publishable: the existingchangelog_section_problemassert, unchanged, through the very extractor the publisher uses.The bare-tree asymmetry that legacy mode needs — both re-armed and stamped shapes legal — has no fragment-mode counterpart, because there is no re-arm. Say that in the file, next to the paragraph that explains why the asymmetry exists in legacy mode.
Diagnostics: every refusal prints the fix, in the register the file already uses. The two new ones a reader will not have seen before are "a
## Unreleasedsection survived the adoption — move its entries intochangelog.d/<issue>.mdand delete the heading" and "these fragments were not consumed: … — re-runchangelog-assemble <ver>".Tasks
actions/changelog-armed/changelog-armed.sh— mode detection, the six rules, diagnostics.actions/changelog-armed/action.yml— thefragments-dirinput, defaulted, documented.test/changelog-armed.test.sh— fragment-mode rows beside the existing ones.test/run.shgreen.Acceptance criteria
changelog.d/behaves exactly as at2f58d9b— every existing test row passes unmodified.-dev+changelog.d/present + no## Unreleased+ well-formed fragments → green.-dev+ a surviving## Unreleased→ red, naming the section.-dev+changelog.d/missing itsREADME.md→ red.-dev+ one malformed fragment → red, quotingchangelog_fragment_problem's diagnosis and the file.## <ver>with entries + directory consumed → green.changelog_section_problem(the half-ceremony row survives the mode change).lib/changelog.sh— no second copy of them in this file.Test plan
Extend
test/changelog-armed.test.sh, whose constructed two-file trees grow a directory. Every existing row stays and must stay green — that is the D8 proof.Fragment rows that must pass:
-dev, directory with README and no fragments (a freshly released main);-devwith several well-formed fragments, flat; the same grouped; bare with the stamped section and an emptied directory; bare where the changelog also still carries every older section.Fragment rows that must fail: each of the six rules violated in isolation; a
## Unreleasedthat is empty (still refused — the heading is the problem, not its contents); a fragment namednotes.md; a fragment with a###heading and nothing under it; bare with the stamp missing entirely.Cross-mode: the same tree with and without
changelog.d/produces different verdicts on the same changelog, and both are correct — the row that proves mode detection is doing the work.Dependencies
Part of #112. Blocked by #114. Blocks #117.
Every issue named by
Blocked byis closed. The sweep is moving this issue toready.Starting this build. I’ll implement fragment-mode detection and guard behavior in
changelog-armed, preserve the legacy contract unchanged, add the specified constructed-tree coverage, and open a draft PR as soon as the first red-test checkpoint is committed.