diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0d434b3..31aab5b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -469,9 +469,13 @@ jobs: run: | set -euo pipefail - # We reuse the "latest"/"preview" tag, therefore GitHub's generate-notes must be anchored - # to a different tag name pointing at the previous channel release commit. Use a temporary - # tag and delete it afterwards to avoid accumulating tags. + # We reuse the moving "latest"/"preview" tags for releases. GitHub's generate-notes compares + # tag_name -> previous_tag_name, so using the moving tag as tag_name would compare old -> old + # (because the tag hasn't moved yet) and returns empty notes. + # To keep tags clean and avoid new permanent tags, we create two short-lived tags: + # - one on the previous release commit + # - one on the new release commit + # Then we diff temp-new -> temp-prev and delete both tags. if ! PREVIOUS_RELEASE_SHA=$(gh release view "$RELEASE_NAME" --json targetCommitish --jq '.targetCommitish' 2>/dev/null); then echo "ERROR: Failed to query existing '$RELEASE_NAME' release; cannot generate release notes." >&2 exit 1 @@ -482,9 +486,11 @@ jobs: fi TEMP_PREV_TAG="${RELEASE_NAME}-prev-${GITHUB_RUN_ID}" + TEMP_HEAD_TAG="${RELEASE_NAME}-head-${GITHUB_RUN_ID}" cleanup() { - git push --delete origin "$TEMP_PREV_TAG" >/dev/null 2>&1 || true - git tag -d "$TEMP_PREV_TAG" >/dev/null 2>&1 || true + # Best-effort cleanup; don't fail the job if cleanup fails. + git push --delete origin "$TEMP_PREV_TAG" "$TEMP_HEAD_TAG" >/dev/null 2>&1 || true + git tag -d "$TEMP_PREV_TAG" "$TEMP_HEAD_TAG" >/dev/null 2>&1 || true } trap cleanup EXIT @@ -494,20 +500,30 @@ jobs: git fetch --no-tags origin "${PREVIOUS_RELEASE_SHA}" fi - # Ensure the temporary tag exists for generate-notes diffing + # Ensure both temporary tags exist for generate-notes diffing. git tag -f "$TEMP_PREV_TAG" "$PREVIOUS_RELEASE_SHA" + git tag -f "$TEMP_HEAD_TAG" "$GITHUB_SHA" git push --force origin "refs/tags/${TEMP_PREV_TAG}" + git push --force origin "refs/tags/${TEMP_HEAD_TAG}" + + echo "Using temp tags: prev=${TEMP_PREV_TAG} (${PREVIOUS_RELEASE_SHA}), head=${TEMP_HEAD_TAG} (${GITHUB_SHA})" # 1) Prefer GitHub's generate-notes API so we get PR links and @mentions - ARGS=(-X POST "repos/${GITHUB_REPOSITORY}/releases/generate-notes" -f tag_name="$RELEASE_NAME" -f target_commitish="$GITHUB_SHA") - ARGS+=(-f previous_tag_name="$TEMP_PREV_TAG") - gh api "${ARGS[@]}" --jq '.body' > release-notes.md + gh api -X POST "repos/${GITHUB_REPOSITORY}/releases/generate-notes" \ + -f tag_name="$TEMP_HEAD_TAG" \ + -f target_commitish="$GITHUB_SHA" \ + -f previous_tag_name="$TEMP_PREV_TAG" \ + --jq '.body' > release-notes.md if ! grep -q '[^[:space:]]' release-notes.md; then echo "ERROR: GitHub generate-notes returned an empty body." >&2 exit 1 fi + # Remove the "Full Changelog" line to avoid broken links from temp tags. + sed -E -i.bak '/^\*\*Full Changelog\*\*:/d' release-notes.md + rm -f release-notes.md.bak + printf "\n%s\n" "$LEGAL_NOTICE" >> release-notes.md