actions/changelog-assembled — the release PR's section must be exactly the fragments it consumed #116
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#116
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. Under fragments the release PR's changelog edit is produced by a tool (#114) but committed by a person:
bin/changelog-assembleis run by hand in the ceremony PR, because the assembled section has to land in the diff where the panel reads it. Nothing yet proves the section that landed is the one the fragments say.That gap is the same shape as every failure this repo has already built a guard for: it leaves no trace. Drop one fragment from the delete list and its entry is simply absent from the release — the file is well-formed,
changelog-armedis green (the section exists and has prose),changelog-monotonicis green (no heading was deleted), the publisher happily publishes the shortened section, and the only way anyone finds out is by reading the release body against a directory that no longer exists. Hand-edit the assembled prose and the published history quietly stops being what the authors wrote.changelog-armedcannot ask this: "the section matches the fragments it consumed" is not a property of a tree, it is a property of a diff — exactly the argumentchangelog-monotonicmakes for being its own git-aware action rather than a clause insidechangelog-armed. This is the third guard, on the same reasoning.Spec
actions/changelog-assembled— assert that a release PR's new section is exactly what the fragments it deleted assemble to.When it applies: the merge base has
changelog.d/(fragment mode) and HEAD's version is bare — the ceremony PR and its merge commit. Every other tree is a pass with a NOTICE, not a skip in silence: an ordinary PR does not touch the changelog's sections and has nothing to prove here.The check:
git show <base>:changelog.d/...), not the working tree — the working tree's are gone, that is the point.--checkover that set for HEAD's version, using the date already stamped in HEAD's top heading, so a date difference is never mistaken for a prose difference.changelog_section "$CHANGELOG" "$VER"on HEAD, byte for byte.Degradation: no resolvable merge base is a hard failure under the fail-closed switch CI sets, matching
changelog-monotonic's stance and itsfetch-depth: 0requirement — a guard that can quietly stop guarding is the failure shape these checks exist to refuse.Where it runs: the consumer CI guard list in docs/CONSUMERS.md, beside
changelog-armedandchangelog-monotonic, adopted at the same pin bump as fragments themselves.The action is a thin wrapper: the assembly definition stays in
lib/changelog.shand the diffing lives inchangelog-assembled.sh, its own file, sotest/changelog-assembled.test.shcan drive it against constructed git repos.Tasks
actions/changelog-assembled/changelog-assembled.sh— applicability, the four refusals, the fail-closed switch, a header comment stating the failure it catches and why it cannot live inchangelog-armed.actions/changelog-assembled/action.yml— inputsbase-ref,changelog,fragments-dir,version-source,strict, mirroring the sibling guards' input names exactly.test/changelog-assembled.test.sh— constructed git repos..github/workflows/ci.yml— run it on this repo, withfetch-depth: 0already present for monotonic.test/run.shgreen.Acceptance criteria
-devPR → green NOTICE, whatever it does tochangelog.d/.changelog.d/at the merge base) → green NOTICE, always.Test plan
Constructed git repos in a temp dir (
changelog-monotonic's suite is the pattern), each with a merge base commit and a HEAD commit.Green rows: faithful assembly, flat; faithful assembly, grouped; an ordinary PR adding a fragment; an ordinary PR adding none; a legacy repo mid-ceremony (no fragments dir at base); strict off with no base ref.
Red rows: dropped entry; dropped fragment-with-no-entry; edited entry; re-ordered entries; surviving fragment at HEAD; missing section; strict on with an unresolvable base.
Interaction: run the trio (
changelog-armed,changelog-monotonic,changelog-assembled) over one faithful ceremony tree and assert all three green — and over the dropped-entry tree and assert this one is the only one red. That row is the issue's whole argument, and it belongs in the suite.Dependencies
Part of #112. Blocked by #114. Blocks #117.
Every issue named by
Blocked byis closed. The sweep is moving this issue toready.Claiming — starting now. Branch
build/116-changelog-assembled; draft PR follows with the first commit.PR up and ready-for-review: #124 — built and verified (34-check suite over constructed histories including the trio interaction row: on the dropped-entry tree armed and monotonic stay green and
changelog-assembledis the only red; full suite 17/17 files, shellcheck 37 scripts clean, actionlint clean), panel requested.