From 21043d542acda29d25b50e95a378cf90a70d6377 Mon Sep 17 00:00:00 2001 From: Tobias Gesellchen Date: Tue, 18 Aug 2026 21:47:34 +0200 Subject: [PATCH] feat(release): add real per-platform download links to release notes Release notes previously pointed at the flat, alphabetical Assets list, forcing readers to hunt for their platform's soundtouch-service or soundtouch-cli build. Generate direct per-platform links (with inline checksum links, one row per OS/arch) from the deterministic asset naming convention, and wire it into both release paths: the auto-generated notes (create_release) and the hand-authored notes a maintainer publishes via the GitHub web UI (update_release, which now replaces the Downloads footer line in place). The footer-replace logic always goes through the same strip-then-append path so re-running the job for the same tag stays byte-for-byte idempotent. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/release.yml | 64 ++++++++++++++++++++++++++- docs/content/docs/downloads/_index.md | 17 ++++--- scripts/release/quick-downloads.sh | 59 ++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 8 deletions(-) create mode 100755 scripts/release/quick-downloads.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7aca391..00110aa 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -346,6 +346,14 @@ jobs: TAG_NAME="${{ needs.validate.outputs.tag }}" VERSION="${TAG_NAME#v}" + # Real per-platform links for the two most-used tools, generated + # from the deterministic `---[.exe]` asset + # naming convention (see scripts/release/quick-downloads.sh), + # instead of requiring a scroll through the flat, alphabetical + # Assets list. Inline checksum link per row (à la Helm's release + # notes) instead of sending people to the combined checksums file. + QUICK_DOWNLOADS="$(scripts/release/quick-downloads.sh "$TAG_NAME" "${{ github.repository }}")" + # Short, accurate header. GitHub's auto-generated "What's Changed" # + "Full Changelog" are appended after this (generate_release_notes). cat > release_notes.md << EOF @@ -353,13 +361,15 @@ jobs: **Bose SoundTouch Toolkit.** Keep your Bose SoundTouch speakers alive after the Bose cloud shutdown. No Bose infrastructure required. + $QUICK_DOWNLOADS + ## What's included Pre-built binaries for Linux (amd64, arm64, armv7), macOS (Intel & Apple Silicon), Windows (amd64), and FreeBSD (amd64): - - **soundtouch-service**: local server that replaces the Bose cloud. Point your speaker at it and you keep full control; the built-in web UI on port 8000 handles setup. + - **soundtouch-service** (see above) + - **soundtouch-cli** (see above) - **soundtouch-player**: standalone LAN web UI for device control: play/pause, volume, presets, live status. (Formerly \`soundtouch-web\`.) - - **soundtouch-cli**: command-line control of any device: playback, presets, sources, multiroom zones, discovery, and migration. Good for scripting and home automation. - **soundtouch-backup**: back up your Bose cloud account and each speaker's local state. \`soundtouch-backup all\` captures everything in one step. Not sure which file to grab? The [Downloads page](https://gesellix.github.io/Bose-SoundTouch/docs/downloads/) explains which tool you need and which \`-\` build matches your computer. @@ -414,12 +424,62 @@ jobs: if: github.event_name == 'release' && github.event.action == 'published' steps: + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ needs.validate.outputs.tag }} + - name: Download release assets uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: release-assets path: ./release-assets + - name: Upgrade the Downloads footer with direct per-platform links + # This is the path real releases take: a maintainer hand-writes + # "Noteworthy" notes and publishes via the GitHub web UI, which + # fires this job, not create_release (workflow_dispatch only). + # _/releases/_TEMPLATE.md's convention is a trailing footer line: + # --- + # 📦 **Downloads / installation:** + # Drop that line (if present) and append the quick-downloads + # block in its place. Always goes through the same append path + # (strip block + strip footer + append), whether or not a + # footer line is still there, so re-runs stay byte-for-byte + # idempotent instead of drifting on the 2nd run. + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + TAG_NAME="${{ needs.validate.outputs.tag }}" + + scripts/release/quick-downloads.sh "$TAG_NAME" "${{ github.repository }}" > quick_downloads.md + gh release view "$TAG_NAME" --json body -q .body > existing_body.md + + python3 - << 'PYEOF' + import re + + with open("existing_body.md") as f: + body = f.read() + with open("quick_downloads.md") as f: + block = f.read().rstrip("\n") + + # Drop a block this automation inserted on a previous run. + body = re.sub(r"\n*.*?\n*", "\n", body, flags=re.DOTALL) + + # Drop the hand-authored footer line (first run only) so both + # cases converge on the same append below and re-runs stay + # byte-for-byte idempotent. + footer = re.compile(r"^📦 \*\*Downloads / installation:\*\*.*\n?", re.MULTILINE) + body = footer.sub("", body, count=1) + + body = body.rstrip("\n") + "\n\n" + block + "\n" + + with open("combined_notes.md", "w") as f: + f.write(body) + PYEOF + + gh release edit "$TAG_NAME" --notes-file combined_notes.md + - name: Upload additional assets to existing release uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2 with: diff --git a/docs/content/docs/downloads/_index.md b/docs/content/docs/downloads/_index.md index c46e5cf..f892d98 100644 --- a/docs/content/docs/downloads/_index.md +++ b/docs/content/docs/downloads/_index.md @@ -17,12 +17,17 @@ then **which build** matches your computer. AfterTouch is a small set of separate programs. Most people run one or two of them. -| Tool | What it does | You want this if… | -|----------------------|-----------------------------------------------------------------------------------------------|----------------------------------------------------------| -| `soundtouch-service` | The local cloud replacement ("AfterTouch"). Runs always-on and takes over from the Bose cloud. | You are migrating speakers off the Bose cloud. | -| `soundtouch-player` | A browser control panel (radio browsing, device control). | You want a web UI to browse radio and control speakers. | -| `soundtouch-cli` | Command-line control and setup (status, play, presets, groups, **migration**, …). | You want to script things, or run a migration by hand. | -| `soundtouch-backup` | Backs up your Bose cloud account and each speaker's local state. | You are preparing before a shutdown / factory reset. | +| Tool | What it does | You want this if… | +|----------------------|------------------------------------------------------------------------------------------------|---------------------------------------------------------| +| `soundtouch-service` | The local cloud replacement ("AfterTouch"). Runs always-on and takes over from the Bose cloud. | You are migrating speakers off the Bose cloud. | +| `soundtouch-cli` | Command-line control and setup (status, play, presets, groups, **migration**, …). | You want to script things, or run a migration by hand. | +| `soundtouch-player` | A browser control panel (radio browsing, device control). | You want a web UI to browse radio and control speakers. | +| `soundtouch-backup` | Backs up your Bose cloud account and each speaker's local state. | You are preparing before a shutdown / factory reset. | + +Most people only need **`soundtouch-service`** and **`soundtouch-cli`** — the +release notes on each [GitHub release](https://github.com/gesellix/Bose-SoundTouch/releases/latest) +link those two directly, one row per platform, so you don't have to hunt +through the flat Assets list below. > Running a migration from the command line (for example the telnet > re-migration in the diff --git a/scripts/release/quick-downloads.sh b/scripts/release/quick-downloads.sh new file mode 100755 index 0000000..9f74fdb --- /dev/null +++ b/scripts/release/quick-downloads.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +# Emits a "Quick downloads" markdown section with real, direct download +# links for soundtouch-service and soundtouch-cli, one row per platform. +# Asset URLs are deterministic (---[.exe]), so this +# needs no GitHub API call to build them. +# +# Usage: quick-downloads.sh +# Output goes to stdout, wrapped in +# markers so callers can find-and-replace a previously inserted block. + +set -euo pipefail + +TAG_NAME="$1" +REPOSITORY="$2" +BASE_URL="https://github.com/${REPOSITORY}/releases/download/${TAG_NAME}" + +# suffix|human label, same order as docs/content/docs/downloads/_index.md +PLATFORMS=( + "linux-arm64|Raspberry Pi (64-bit) / ARM64 Linux" + "linux-armv7|Raspberry Pi (32-bit) / ARMv7" + "linux-amd64|Linux (64-bit PC)" + "darwin-arm64|macOS (Apple Silicon)" + "darwin-amd64|macOS (Intel)" + "windows-amd64.exe|Windows (64-bit)" + "freebsd-amd64|FreeBSD (64-bit)" +) + +build_table() { + local BINARY_NAME=$1 + echo "| Platform | Download | Checksum |" + echo "|---|---|---|" + for ENTRY in "${PLATFORMS[@]}"; do + local SUFFIX="${ENTRY%%|*}" + local LABEL="${ENTRY##*|}" + local FILENAME="${BINARY_NAME}-${TAG_NAME}-${SUFFIX}" + echo "| ${LABEL} | [${FILENAME}](${BASE_URL}/${FILENAME}) | [sha256](${BASE_URL}/${FILENAME}.sha256) |" + done +} + +SERVICE_TABLE="$(build_table soundtouch-service)" +CLI_TABLE="$(build_table soundtouch-cli)" + +cat << EOF + +## Quick downloads + +Most people only need one of these two: + +**soundtouch-service** — the local server that replaces the Bose cloud. Point your speaker at it and you keep full control; the built-in web UI on port 8000 handles setup. + +$SERVICE_TABLE + +**soundtouch-cli** — command-line control of any device: playback, presets, sources, multiroom zones, discovery, and migration. Good for scripting and home automation. + +$CLI_TABLE + +Everything else (soundtouch-player, soundtouch-backup, other platforms, Docker, install scripts): [Downloads page](https://gesellix.github.io/Bose-SoundTouch/docs/downloads/). + +EOF