diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 84dd26d..4a2e427 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -107,6 +107,16 @@ jobs: DMG_URL="https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/eWiz-${{ steps.ver.outputs.version }}.dmg" ./scripts/make-appcast.sh "${{ steps.ver.outputs.version }}" "$DMG_URL" "eWiz ${{ steps.ver.outputs.version }}" + # The release notes are this version's CHANGELOG.md section, which the + # Version PR wrote. ewiz.app's changelog and download pages read them from + # the GitHub release, so the site needs no edit per release. + - name: Write release notes + if: startsWith(github.ref, 'refs/tags/') + run: | + ./scripts/release-notes.sh "${{ steps.ver.outputs.version }}" > dist/release-notes.md + [ -s dist/release-notes.md ] || echo "eWiz ${{ steps.ver.outputs.version }}" > dist/release-notes.md + cat dist/release-notes.md + # On a tag push, attach DMG + appcast.json to a published GitHub Release. - name: Publish GitHub Release if: startsWith(github.ref, 'refs/tags/') @@ -114,12 +124,12 @@ jobs: with: name: "eWiz ${{ steps.ver.outputs.version }}" tag_name: ${{ github.ref_name }} + body_path: dist/release-notes.md files: | dist/eWiz-${{ steps.ver.outputs.version }}.dmg dist/appcast.json draft: false make_latest: true - generate_release_notes: true # Point the public in-app update feed at this release. Done inline here # rather than in a separate `release: published` workflow because releases diff --git a/scripts/release-notes.sh b/scripts/release-notes.sh new file mode 100755 index 0000000..2f7f522 --- /dev/null +++ b/scripts/release-notes.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# Prints one version's release notes: its section of CHANGELOG.md without the +# changesets bookkeeping (the "### Patch Changes" headings and the commit-hash +# prefix on each entry). The GitHub release carries this text, and ewiz.app's +# changelog page reads it from there. +# Usage: ./scripts/release-notes.sh +set -euo pipefail + +VERSION="${1:?usage: release-notes.sh }" +REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +awk -v v="$VERSION" ' + /^## / { if (inside) exit; inside = ($2 == v); next } + !inside || /^### (Major|Minor|Patch) Changes$/ { next } + { + # "- 5dadc82: text" -> "- text" + if (match($0, /^- [0-9a-f]+: /) && RLENGTH >= 11) $0 = "- " substr($0, RLENGTH + 1) + # Drop leading and trailing blank lines, and squeeze runs of them into one. + if ($0 ~ /^[ \t]*$/) { if (printed) blank = 1; next } + if (blank) { print ""; blank = 0 } + print + printed = 1 + } +' "$REPO_DIR/CHANGELOG.md" | +# Unwrap hard-wrapped paragraphs: GitHub renders every newline in a release +# body as a line break. List items, headings, quotes and code stay as they are. +awk ' + function flush() { if (have) print buf; have = 0 } + { + s = $0; sub(/^[ \t]+/, "", s) + if (s ~ /^```/) { flush(); print; fence = !fence; next } + if (fence) { print; next } + if (s == "") { flush(); print; next } + if (have && buf !~ /^[ \t]*#/ && s !~ /^([-*+] |[0-9]+\. |#|>|\|)/) { buf = buf " " s; next } + flush(); buf = $0; have = 1 + } + END { flush() } +'