From e5c1cc2740744f16ffdd442008dd5ccc4b00803c Mon Sep 17 00:00:00 2001 From: Martin Storath Date: Fri, 8 May 2026 04:39:49 +0000 Subject: [PATCH] Auto-create GitHub Release on tag push (alongside PyPI publish) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tag-push currently uploads to PyPI but does not create a GitHub Release entry — when DCEBE first ships, the Releases page on github.com/mstorath/DCEBE will stay empty unless a Release object is created. This step does that automatically: it tries to extract the matching `## ` section from CHANGELOG.md, falls through to a tag-commits-link stub if no changelog yet (DCEBE's port is still in progress), and posts to GitHub Releases via softprops/action-gh-release@v2 with all build artifacts attached. Implementation: - `contents: write` permission added (required by the release action). `id-token: write` for OIDC stays. - `actions/checkout@v4` added so CHANGELOG.md is on disk if/when one exists in the repo. - An awk extractor; defensive fallback to a tag-commits link if no CHANGELOG.md or no matching heading. - `generate_release_notes: true` provides an auto-generated PR/commit summary on top — this carries the first DCEBE Release until a curated CHANGELOG.md lands. - Idempotent: updates an existing Release for the tag rather than erroring, so manual pre-creation never blocks a re-run. See devcontainer reports/12-auto-github-release-pattern.md for the shared pattern and the rationale. --- .github/workflows/release.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1957966..f5c3830 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -45,7 +45,11 @@ jobs: url: https://pypi.org/p/dcebe permissions: id-token: write # required for OIDC trusted publishing + contents: write # required for the GitHub Release step below steps: + - name: Checkout (for CHANGELOG.md if present) + uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 with: name: dist @@ -56,3 +60,30 @@ jobs: # No `password:` argument — OIDC trusted publisher (configure # at https://pypi.org/manage/account/publishing/ before the # first release). + + - name: Extract release notes from CHANGELOG.md (or fall through) + # Pulls the section bounded by `## ` (bracket-tolerant) and + # the next `## ` heading. DCEBE doesn't have a CHANGELOG.md yet — + # this step writes a stub link to the tag's commits, and the + # release-creation step's `generate_release_notes: true` provides + # an auto-generated PR/commit summary as the visible content. + 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/*