From e89704d4ad98517081e2ac0f0e61d46cbf1caec8 Mon Sep 17 00:00:00 2001 From: Bentley Davis <10065854+NonPolynomialTim@users.noreply.github.com> Date: Thu, 30 Jul 2026 23:38:10 -0400 Subject: [PATCH] fix(ci): scope nightly release notes to commits since last release The nightly prerelease published with `generate_release_notes: true` on the non-semver `nightly` tag. GitHub's auto base-selection can't order `nightly` against the tag soup (v0.1..v2.0.0 + legacy OpenXcomCoop_*), so it diffs from ~repo start and the notes accumulate every commit ever made, growing without bound. Pin the diff base to the last official release instead: - meta job exports `lastTag` = git describe --match "v[0-9]*" (v2.0.0 today; skips legacy junk tags; empty on a tagless repo). - Publish with generate_release_notes: false (release still uses the curated CHANGELOG body; nightly is published body-less). - The notes step now generates the list via `gh api .../releases/generate-notes -f previous_tag_name=$lastTag`, then runs the existing New-Contributors + `by @author` strip. Falls back to GitHub's default base when lastTag is empty. Net: nightly notes span ..HEAD and reset at the next official release tag. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/ci-main.yml | 44 ++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci-main.yml b/.github/workflows/ci-main.yml index b49020d73..e4e0a4f5b 100644 --- a/.github/workflows/ci-main.yml +++ b/.github/workflows/ci-main.yml @@ -44,6 +44,7 @@ jobs: name: ${{ steps.meta.outputs.name }} prerelease: ${{ steps.meta.outputs.prerelease }} latest: ${{ steps.meta.outputs.latest }} + lastTag: ${{ steps.meta.outputs.lastTag }} steps: - uses: actions/checkout@v4 with: { fetch-depth: 0 } # full history: version = git describe @@ -82,9 +83,15 @@ jobs: "prerelease=true" >> $env:GITHUB_OUTPUT "latest=false" >> $env:GITHUB_OUTPUT } + # Last official release tag reachable from HEAD (e.g. v2.0.0). Used to pin the + # base for nightly release-notes so they cover only "since the last release" + # instead of the whole history. Match v to skip legacy junk tags + # (OpenXcomCoop_*, v-non-numeric). Empty on a repo with no release tag yet. + $lastTag = (git describe --tags --abbrev=0 --match "v[0-9]*" 2>$null) + "lastTag=$lastTag" >> $env:GITHUB_OUTPUT "version=$v" >> $env:GITHUB_OUTPUT "gitSuffix=$gitSuffix" >> $env:GITHUB_OUTPUT - Write-Host "version: $v$gitSuffix" + Write-Host "version: $v$gitSuffix (base: $lastTag)" build: needs: meta @@ -361,24 +368,39 @@ jobs: prerelease: ${{ needs.meta.outputs.prerelease }} make_latest: ${{ needs.meta.outputs.latest }} files: ${{ env.ASSETS }} # x64 zip + WinXP zip + Linux tarball, one call - # release -> curated notes from CHANGELOG.md; nightly -> auto-generated + # release -> curated notes from CHANGELOG.md; nightly -> generated by the next + # step, pinned to previous_tag_name (GitHub's auto base picks the whole history + # for the non-semver `nightly` tag -> notes grow forever). Publish with an empty + # body; the strip step below fills it in. body_path: ${{ needs.meta.outputs.channel == 'release' && 'release-notes.md' || '' }} - generate_release_notes: ${{ needs.meta.outputs.channel != 'release' }} + generate_release_notes: false - - name: Strip 'New Contributors' + author handles from nightly notes + - name: Generate nightly notes since last release + strip authorship if: needs.meta.outputs.channel == 'nightly' shell: pwsh env: GH_TOKEN: ${{ github.token }} run: | + # Generate the "What's Changed" list ourselves, pinned to the last official + # release. GitHub's auto base-selection can't order the non-semver `nightly` + # tag against the legacy junk tags, so it diffs from ~repo start and the notes + # grow without bound. previous_tag_name = last release => notes cover exactly + # the commits since that release. Empty lastTag (no release yet) falls back to + # GitHub's default base. + $prev = "${{ needs.meta.outputs.lastTag }}" + $call = @('api', "repos/$env:GITHUB_REPOSITORY/releases/generate-notes", + '-f', 'tag_name=nightly', + '-f', 'target_commitish=${{ github.sha }}') + if ($prev) { $call += @('-f', "previous_tag_name=$prev") } + Write-Host "generate-notes base: $(if ($prev) { $prev } else { '(auto)' })" + # gh returns the body as a string[] (one element per line). Without an explicit + # -join, PowerShell coerces it to a single string joined with SPACES, which + # destroys every newline (notes render as one run-on paragraph) and makes the + # regexes below never match. Always -join "`n" first. + $body = (& gh @call --jq '.body') -join "`n" # "New Contributors" is meaningless on a rolling tag: GitHub recomputes it each - # run against a shifting base (the last release tag) and flags even the original - # dev as "new". Remove that section, keeping "## What's Changed" + "Full Changelog". - # NOTE: gh returns the body as a string[] (one element per line). Without an - # explicit -join, PowerShell coerces it to a single string joined with SPACES, - # which destroys every newline (notes render as one run-on paragraph) and makes - # the regex below never match. Always -join "`n" first. - $body = (gh release view nightly --repo "$env:GITHUB_REPOSITORY" --json body --jq '.body') -join "`n" + # run against a shifting base and flags even the original dev as "new". Remove + # that section, keeping "## What's Changed" + "Full Changelog". $clean = [regex]::Replace($body, "(?s)\r?\n?## New Contributors\r?\n(?:\*.*\r?\n?)*\r?\n?(?=\*\*Full Changelog\*\*)", "`n`n") # Drop the "by @author" credit from each "What's Changed" bullet - the notes # should describe the change, not the committer.