From efb8f8245f43bcd64d9eaa2d4b832aa11d2a3f37 Mon Sep 17 00:00:00 2001 From: Jack Chuma Date: Fri, 16 Oct 2026 15:29:24 -0400 Subject: [PATCH] fix(release): generate release notes from the previous final tag --- .github/workflows/publish-release.yml | 8 +++++++- scripts/release/common.sh | 18 ++++++++++++++++++ scripts/release/test-release.sh | 4 ++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index d23fbfa26..2ae06f8b9 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -64,7 +64,13 @@ jobs: if gh release view "$TAG" > /dev/null 2>&1; then echo "Release $TAG already exists; reusing it." else - gh release create "$TAG" --draft --generate-notes --title "$TAG" --verify-tag + source "$RUNNER_TEMP/release-scripts/common.sh" + NOTES_ARGS=() + PREVIOUS_TAG=$(get_previous_final_tag "${TAG#v}") + if [[ -n "$PREVIOUS_TAG" ]]; then + NOTES_ARGS=(--notes-start-tag "$PREVIOUS_TAG") + fi + gh release create "$TAG" --draft --generate-notes "${NOTES_ARGS[@]}" --title "$TAG" --verify-tag fi - name: Summary diff --git a/scripts/release/common.sh b/scripts/release/common.sh index 7275c7470..b7ff7ef8a 100755 --- a/scripts/release/common.sh +++ b/scripts/release/common.sh @@ -25,6 +25,24 @@ get_latest_final_version() { return 1 } +# Release notes need this explicitly: final tags live on release branches, so the +# previous one is often missing from the new tag's history and GitHub falls back further. +get_previous_final_tag() { + local version="$1" tag major minor patch t_major t_minor t_patch + IFS='.' read -r major minor patch <<< "$version" + while IFS= read -r tag; do + if [[ "$tag" =~ ^v([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then + t_major=$((10#${BASH_REMATCH[1]})); t_minor=$((10#${BASH_REMATCH[2]})); t_patch=$((10#${BASH_REMATCH[3]})) + if (( t_major < 10#$major + || (t_major == 10#$major && t_minor < 10#$minor) + || (t_major == 10#$major && t_minor == 10#$minor && t_patch < 10#$patch) )); then + echo "$tag" + return 0 + fi + fi + done < <(git tag -l 'v[0-9]*.[0-9]*.[0-9]*' --sort=-version:refname) +} + get_next_version() { local bump_type="$1" current_version major minor patch if [[ "$bump_type" != major && "$bump_type" != minor && "$bump_type" != patch ]]; then diff --git a/scripts/release/test-release.sh b/scripts/release/test-release.sh index 471f47cd9..96cad9788 100755 --- a/scripts/release/test-release.sh +++ b/scripts/release/test-release.sh @@ -87,6 +87,10 @@ test_version_bumps() { assert_equal 8.11.0 "$(get_next_version minor)" 'minor bumps reset a nonzero patch' assert_equal 8.10.5 "$(get_next_version patch)" 'patch bumps retain major and minor' assert_rejected 'bump_type must be' get_next_version invalid + assert_equal v8.10.4 "$(get_previous_final_tag 8.11.0)" 'previous final tag skips RCs and uses version order' + assert_equal v8.10.0 "$(get_previous_final_tag 8.10.4)" 'previous final tag excludes the version being released' + assert_equal v8.9.0 "$(get_previous_final_tag 8.9.1)" 'a patch on an older line ignores newer releases' + assert_equal '' "$(get_previous_final_tag 8.9.0)" 'the first release has no previous final tag' git tag -d v8.9.0 v8.10.0 v8.10.4 >/dev/null assert_rejected 'No final release tags found' get_latest_final_version