fix(changelog): refuse to release a version older than the newest

`release 0.4.9` on a changelog topped by 0.5.0 wrote the section above it
with a backwards compare link and deleted the entries; `check` caught the
file only afterwards (Pullfrog on #82). The version is now compared before
anything is written.

Also: the #78 entry names the calendar's open offers and the session API's
read-path allowlist, added there since.

Claude-Session: https://claude.ai/code/session_01RqPPVeVDrnLoP7NUZmLRxY
This commit is contained in:
Rasyidan Akbar F. 2026-11-04 20:47:20 +07:00
commit eb4e2d4162
3 changed files with 27 additions and 3 deletions

View file

@ -188,6 +188,13 @@ EOF
if changelog release 0.5.0 2026-11-06 >/dev/null 2>&1; then
fail "release accepted a version already released"
fi
if err="$(changelog release 0.4.9 2026-11-06 2>&1)"; then
fail "release accepted a version older than the newest"
elif ! grep -q "older than 0.5.0" <<<"$err"; then
fail "release of an older version said: ${err}"
fi
[[ -f "$work/changes/unreleased/again.md" ]] || fail "a refused release deleted the entries"
diff -q "$expected" "$work/CHANGELOG.md" >/dev/null || fail "a refused release changed CHANGELOG.md"
rm "$work/changes/unreleased/again.md"
if changelog release 0.5.1 >/dev/null 2>&1; then
fail "release accepted no entries"

View file

@ -132,6 +132,13 @@ cmd_check() {
printf 'changelog: ok (%s unreleased entries)\n' "$(entries | wc -l | tr -d ' ')"
}
# A version as a string that sorts like the version: 0.10.0 after 0.9.9.
version_key() {
local major minor patch
IFS=. read -r major minor patch <<<"$1"
printf '%06d%06d%06d' "$((10#$major))" "$((10#$minor))" "$((10#$patch))"
}
# The newest version in CHANGELOG.md, if any.
latest_version() {
awk '/^## \[[0-9]/ { print substr($2, 2, length($2) - 2); exit }' "$changelog"
@ -182,6 +189,13 @@ cmd_release() {
if grep -q "^## \[${version//./\\.}\] " "$changelog"; then
die "${version} is already in CHANGELOG.md"
fi
# The new section goes on top, so it must be the newest version; checked
# before anything is written or an entry deleted.
local previous
previous="$(latest_version)"
if [[ -n "$previous" ]] && [[ "$(version_key "$version")" < "$(version_key "$previous")" ]]; then
die "${version} is older than ${previous}, the newest version in CHANGELOG.md"
fi
local files=()
local file
@ -190,8 +204,7 @@ cmd_release() {
done < <(entries)
((${#files[@]} > 0)) || die "no entries in changes/unreleased/ to release"
local previous section body
previous="$(latest_version)"
local section body
local out
out="$(mktemp "${TMPDIR:-/tmp}/changelog.XXXXXX")"
{