diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 191aa0f..af2bb5d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -88,7 +88,12 @@ jobs: needs: [linux, macos, windows, sdist] if: startsWith(github.ref, 'refs/tags/v') environment: pypi + permissions: + id-token: write # required for OIDC trusted publishing + contents: write # required for the GitHub Release step below steps: + - name: Checkout (for CHANGELOG.md) + uses: actions/checkout@v4 - uses: actions/download-artifact@v4 with: path: dist @@ -96,3 +101,28 @@ jobs: - uses: pypa/gh-action-pypi-publish@release/v1 with: skip-existing: true + + - name: Extract release notes from CHANGELOG.md + # Pulls the section bounded by `## ` (bracket-tolerant) and + # the next `## ` heading. Falls back to a tag-commits link if + # the heading is missing or CHANGELOG.md doesn't exist. + run: | + VER="${GITHUB_REF_NAME#v}" + if [ -f CHANGELOG.md ]; then + awk -v ver="$VER" ' + $0 ~ "^## \\[?" ver "\\]?( |$)" { found=1; next } + found && /^## / { exit } + found { print } + ' CHANGELOG.md > release-notes.md + fi + [ -s release-notes.md ] || echo "See [tag commits](https://github.com/${GITHUB_REPOSITORY}/commits/${GITHUB_REF_NAME})." > release-notes.md + + - name: Create GitHub Release + # Idempotent: updates an existing Release for this tag rather + # than erroring, so manual pre-creation never blocks a re-run. + uses: softprops/action-gh-release@v2 + with: + name: ${{ github.ref_name }} + body_path: release-notes.md + generate_release_notes: true + files: dist/*