mirror of
https://github.com/akitaonrails/ai-memory.git
synced 2026-10-02 03:24:46 +08:00
`bin/release` copies `## [Unreleased]` into the new version section verbatim, so a repeated `### ` heading there ships release notes with the entries split across two identical headings. It is valid Markdown and invisible in review, which is why it kept happening — I introduced one merging #429, fixed it in #436, then reintroduced it in #439 and caught it only when `bin/release` produced a visibly wrong 1.29.0 section. The check found the same defect in four already-released sections (1.19.0, 1.13.0, 1.4.0, 1.1.1), so this predates today by months. Those are folded here so the check can be enforced repo-wide instead of carrying an exemption list. The fold is deliberately minimal: duplicate headings are merged into their first occurrence and section order is left exactly as it was, rather than re-sorting into Keep a Changelog order. Verified by comparing every non-heading line before and after — the only delta is the five blank lines that separated the five removed headings. No entry text moved between versions, no entry altered, all 92 version headings intact. Fails loudly rather than merging automatically, so the second author sees the collision instead of having it silently resolved. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
65 lines
2.0 KiB
Bash
Executable File
65 lines
2.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Fail if any CHANGELOG version section repeats a `### ` heading.
|
|
#
|
|
# `bin/release` copies `## [Unreleased]` into the new version section
|
|
# verbatim. A duplicated heading there ships release notes with, say, two
|
|
# separate "Fixed" lists and the entries split between them — and nothing
|
|
# else catches it, because a duplicate heading is valid Markdown.
|
|
#
|
|
# This is not hypothetical: it happened twice in one day, both times from
|
|
# a maintainer adding a section at the top of `[Unreleased]` while an
|
|
# equivalent one already sat further down after an earlier merge.
|
|
#
|
|
# Merging on merge, rather than rejecting, would hide the conflict from
|
|
# whoever wrote the second entry; failing loudly keeps the choice with a
|
|
# human.
|
|
|
|
set -euo pipefail
|
|
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
CHANGELOG="${1:-$REPO_ROOT/CHANGELOG.md}"
|
|
|
|
if [[ ! -f "$CHANGELOG" ]]; then
|
|
echo "check-changelog-sections: $CHANGELOG not found" >&2
|
|
exit 2
|
|
fi
|
|
|
|
status=0
|
|
current=""
|
|
|
|
while IFS= read -r line; do
|
|
case "$line" in
|
|
'## ['*)
|
|
current="${line#\#\# }"
|
|
seen=" "
|
|
;;
|
|
'### '*)
|
|
[[ -n "$current" ]] || continue
|
|
heading="${line#\#\#\# }"
|
|
# Trailing whitespace should not create a distinct heading.
|
|
heading="${heading%"${heading##*[![:space:]]}"}"
|
|
if [[ "$seen" == *" ${heading} "* ]]; then
|
|
echo "error: ${current} repeats the '### ${heading}' heading." >&2
|
|
status=1
|
|
else
|
|
seen="${seen}${heading} "
|
|
fi
|
|
;;
|
|
esac
|
|
done < "$CHANGELOG"
|
|
|
|
if [[ $status -ne 0 ]]; then
|
|
cat >&2 <<'EOF'
|
|
|
|
Each version section may use a given heading only once. Merge the entries
|
|
under a single heading, in Keep a Changelog order:
|
|
|
|
Added, Changed, Deprecated, Removed, Fixed, Security
|
|
|
|
(this project also uses Improved, placed after Changed).
|
|
EOF
|
|
exit 1
|
|
fi
|
|
|
|
echo "CHANGELOG section headings are unique within every version."
|