diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0618db3c..99701d93 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -416,18 +416,29 @@ jobs: echo "$ANNOUNCEMENT_BODY" > "$RUNNER_TEMP/notes.txt" # Append the commits included in this release (previous stable tag -> this release). - # Find the most recent stable v.. tag that isn't the one being - # released; canary-* and other non-release tags are ignored by the glob. - previous_tag="$(git tag --list 'v[0-9]*.[0-9]*.[0-9]*' --sort=-version:refname \ + # + # Resolve the commit this release actually points at. On a manual + # workflow_dispatch the tag may already exist and point at a different + # commit than the workflow's github.sha, so prefer the tag when it + # resolves; otherwise fall back to the release commit (the normal push + # flow creates the tag at this commit in the release step below). + release_ref="$RELEASE_COMMIT" + if git rev-parse -q --verify "refs/tags/${RELEASE_TAG}^{commit}" >/dev/null 2>&1; then + release_ref="refs/tags/${RELEASE_TAG}^{commit}" + fi + + # Find the most recent stable v.. tag that precedes + # this release in its own ancestry (--merged), so re-publishing an older + # or backport release never picks an unrelated newer tag as the previous + # one. canary-* and other non-release tags are ignored by the glob. + previous_tag="$(git tag --list 'v[0-9]*.[0-9]*.[0-9]*' --merged "$release_ref" --sort=-version:refname \ | grep -vFx "$RELEASE_TAG" | head -n1 || true)" if [ -n "$previous_tag" ]; then - commit_range="${previous_tag}..${RELEASE_COMMIT}" - range_heading="$previous_tag...$RELEASE_TAG" + commit_range="${previous_tag}..${release_ref}" else - # First release: include the whole history up to this commit. - commit_range="$RELEASE_COMMIT" - range_heading="$RELEASE_TAG" + # First release (no earlier tag in ancestry): include the whole history. + commit_range="$release_ref" fi commits="$(git log --no-merges --pretty=format:'- %s (%h)' "$commit_range" || true)"