diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..8c3d124 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,34 @@ +# A tag with no release reads as abandonment on the repo page: on 2026-09-01 +# four versions shipped to PyPI while "Latest" still said v0.3.1. The notes +# already live in CHANGELOG.md, so the release is derived from it -- title +# from the heading, body from the section -- and nothing is written twice. +# A tag whose section is missing fails loudly instead of publishing an empty +# release. +name: release +on: + push: + tags: ["v*"] +permissions: + contents: write +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: release from the CHANGELOG section + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ github.ref_name }} + run: | + # heading: "## v0.7.0 — subtitle (2026-09-01)"; body: until the next "## " + awk -v tag="$TAG" ' + /^## / { if (on) exit; on = ($2 == tag) ; if (on) { print > "/tmp/heading"; next } } + on { print } + ' CHANGELOG.md > /tmp/notes.md + if [ ! -s /tmp/heading ]; then + echo "::error::CHANGELOG.md has no '## $TAG' section; add it, then re-push the tag" + exit 1 + fi + TITLE=$(sed -E 's/^## //; s/ \([0-9]{4}-[0-9]{2}-[0-9]{2}\)$//' /tmp/heading) + echo "title: $TITLE" + gh release create "$TAG" --verify-tag --title "$TITLE" --notes-file /tmp/notes.md