From 7313bbf715d7531a6aef634c1e60c380df7419fa Mon Sep 17 00:00:00 2001 From: Anthony Date: Tue, 9 Jun 2026 16:21:22 +0200 Subject: [PATCH] release: version-less GUI installer aliases for stable download links tauri-action names the installers with the version, which would break any fixed download URL on the next release. Add a workflow step that uploads version-less aliases (TutaBridge-macOS.dmg, TutaBridge-Windows-setup.exe, TutaBridge-Linux.AppImage/.deb/.rpm) next to them, and point the README download links at releases/latest/download of those stable names so they follow every future release automatically. The CLI assets were already version-less. The current rc.1 release was backfilled with the aliases. --- .github/workflows/release.yml | 34 ++++++++++++++++++++++++++++++++++ README.md | 6 +++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0d0b333..99f08f2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -114,6 +114,40 @@ jobs: cp "$src" "${{ matrix.cli_asset }}" gh release upload "${{ github.ref_name }}" "${{ matrix.cli_asset }}" --clobber + # tauri-action names the GUI installers with the version (e.g. + # TutaBridge_0.1.0_universal.dmg), which would break any fixed download + # link on the next release. Upload version-less aliases alongside them so + # `releases/latest/download/TutaBridge-macOS.dmg` (and friends) always + # resolve to the current build. The CLI assets are already version-less. + - name: Attach version-less GUI installer aliases + if: startsWith(github.ref, 'refs/tags/') + shell: bash + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + bp="${{ matrix.bundle_path }}" + tag="${{ github.ref_name }}" + alias() { # $1 = glob, $2 = stable name + f=$(ls $1 2>/dev/null | head -n1) + if [ -n "$f" ]; then + cp "$f" "$2" + gh release upload "$tag" "$2" --clobber + else + echo "::warning::no installer matched $1" + fi + } + case "${{ runner.os }}" in + macOS) + alias "$bp/dmg/*.dmg" "TutaBridge-macOS.dmg" ;; + Linux) + alias "$bp/appimage/*.AppImage" "TutaBridge-Linux.AppImage" + alias "$bp/deb/*.deb" "TutaBridge-Linux.deb" + alias "$bp/rpm/*.rpm" "TutaBridge-Linux.rpm" ;; + Windows) + alias "$bp/nsis/*-setup.exe" "TutaBridge-Windows-setup.exe" + alias "$bp/msi/*.msi" "TutaBridge-Windows.msi" ;; + esac + # --- Manual run: publish everything as downloadable workflow artifacts --- - name: Upload GUI bundles as artifacts if: ${{ !startsWith(github.ref, 'refs/tags/') }} diff --git a/README.md b/README.md index afd8444..b390fea 100644 --- a/README.md +++ b/README.md @@ -63,9 +63,9 @@ Download the app for your OS (see [all releases](https://github.com/spartanz51/t | OS | Desktop app | |----|-------------| -| ๐ŸŽ **macOS** (Apple Silicon) | [Download `.dmg`](https://github.com/spartanz51/tutabridge/releases/latest/download/TutaBridge_0.1.0_universal.dmg) | -| ๐ŸชŸ **Windows** (x64) | [Download installer `.exe`](https://github.com/spartanz51/tutabridge/releases/latest/download/TutaBridge_0.1.0_x64-setup.exe) | -| ๐Ÿง **Linux** (x64) | [`.AppImage`](https://github.com/spartanz51/tutabridge/releases/latest/download/TutaBridge_0.1.0_amd64.AppImage) ยท [`.deb`](https://github.com/spartanz51/tutabridge/releases/latest/download/TutaBridge_0.1.0_amd64.deb) ยท [`.rpm`](https://github.com/spartanz51/tutabridge/releases/latest/download/TutaBridge-0.1.0-1.x86_64.rpm) | +| ๐ŸŽ **macOS** (Apple Silicon) | [Download `.dmg`](https://github.com/spartanz51/tutabridge/releases/latest/download/TutaBridge-macOS.dmg) | +| ๐ŸชŸ **Windows** (x64) | [Download installer `.exe`](https://github.com/spartanz51/tutabridge/releases/latest/download/TutaBridge-Windows-setup.exe) | +| ๐Ÿง **Linux** (x64) | [`.AppImage`](https://github.com/spartanz51/tutabridge/releases/latest/download/TutaBridge-Linux.AppImage) ยท [`.deb`](https://github.com/spartanz51/tutabridge/releases/latest/download/TutaBridge-Linux.deb) ยท [`.rpm`](https://github.com/spartanz51/tutabridge/releases/latest/download/TutaBridge-Linux.rpm) | The build is not code-signed, so the first launch needs one click to allow it: