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

@ -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")"
{