Skip to content

chore(changelog): fail when a released section no longer matches its tag - #670

Merged
haribo merged 1 commit into
developfrom
chore/669-changelog-released-sections
Sep 13, 2026
Merged

haribo merged 1 commit into
developfrom
chore/669-changelog-released-sections

Conversation

@haribo

@haribo haribo commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Summary

An entry added to a released section of CHANGELOG.md was not invalid, it was invisible:
test/changelog-rule.sh validates the entries inside [Unreleased], so an entry that is not
there is not checked, it is absent.

test/changelog-frozen.sh compares each ## [X.Y.Z] section against the same section at its
tag, using the extraction release.yaml uses to build the notes — so it compares what was
actually published rather than something adjacent to it.

What running it found

Three instances, not the two the issue named. The oldest has been in the file since August:

version commit what
[0.2.2] 2c11460 (#277, 7 Aug) a ### Fixed entry appended to a section tagged 4 Aug
[0.12.0] #630 the unless entry
[0.14.0] #667, repaired in #668 #658's entry

16 of the 18 released sections are byte-identical to their tags.

Why it is not a prohibition

[0.9.0] diverges on purpose: 713cd07 (#556) added a ### Migration block the day it
shipped, because the breaking entry named plan syntax only while the same rule governs ~{…}
in a template. The check as the issue described it — differ and fail — would have blocked that,
and #556 was right.

So the goal is that a published section cannot be edited invisibly, not that it cannot be
edited. The shape chosen is the one test/e2e/def-coverage.sh already uses: comparison plus a
named allowance carrying its reason, so adding a line to it is part of the change and a
reviewer reads why. A digest file was the alternative and was rejected — a digest can be updated
without anyone reading what changed, and it is one more thing to keep in step at release time.

[0.2.2] is in that list too, and labelled as the defect rather than as a legitimate edit:
repairing it would only move the divergence to the section that actually shipped the entry, and
the published notes for v0.2.2 never contained it anyway.

Test plan

OK — 16 released changelog section(s) match their tag
note: not compared, named in allowed() with the reason: v0.9.0 v0.2.2

Mutation-tested: an entry inserted into [0.13.0] turns it red, printing the diff and naming
the version.

CI needed a fix to work at all. actions/checkout@v7 with no fetch-depth is a depth-1
clone with no tags, so the check would have been a silent no-op on every run. The coverage
job's checkout now sets fetch-depth: 0, with the reason on the line — checked rather than
assumed, which is what the issue asked for.

Added to the pre-PR list in CLAUDE.md: a check nobody runs locally is a check that fails in CI.

Closes #669

@haribo
haribo merged commit 53cfc9e into develop Sep 13, 2026
8 checks passed
@haribo
haribo deleted the chore/669-changelog-released-sections branch September 13, 2026 16:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant