Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: Release

on:
push:
tags:
- "v*"

permissions:
contents: write

jobs:
release:
runs-on: macos-latest
defaults:
run:
working-directory: apps/desktop
steps:
- uses: actions/checkout@v5

- uses: dtolnay/rust-toolchain@stable

- uses: Swatinem/rust-cache@v2

- uses: actions/setup-node@v5
with:
node-version: 22
cache: npm
cache-dependency-path: apps/desktop/package-lock.json

- name: Check tag matches app version
run: |
version="$(node -p "require('./src-tauri/tauri.conf.json').version")"
tag="${GITHUB_REF_NAME#v}"
if [ "$tag" != "$version" ]; then
echo "Tag v$tag does not match tauri.conf.json version $version" >&2
exit 1
fi

- run: npm ci

# No --features dev-token-store here: release builds use the encrypted
# token store. Ad-hoc signing comes from bundle.macOS.signingIdentity
# ("-") in tauri.conf.json, so local and CI builds are signed identically.
- name: Build app bundle
run: npx tauri build --bundles app

- name: Verify code signature
run: |
codesign --verify --deep --strict --verbose=2 ../../target/release/bundle/macos/Retune.app
codesign -dv --verbose=2 ../../target/release/bundle/macos/Retune.app

- name: Package
id: package
run: |
version="${GITHUB_REF_NAME#v}"
artifact="Retune-${version}-aarch64.tar.gz"
tar -czf "$artifact" -C ../../target/release/bundle/macos Retune.app
shasum -a 256 "$artifact" > "$artifact.sha256"
cat "$artifact.sha256"
echo "artifact=$artifact" >> "$GITHUB_OUTPUT"

- name: Create GitHub release
env:
GH_TOKEN: ${{ github.token }}
run: |
artifact="${{ steps.package.outputs.artifact }}"
sha="$(cut -d' ' -f1 "$artifact.sha256")"
cat > release-notes.md <<EOF
macOS (Apple Silicon) app bundle, ad-hoc signed (not notarized).

SHA-256 of \`$artifact\`:

\`\`\`
$sha
\`\`\`

Because the app is not notarized, install via Homebrew
(\`brew install --cask --no-quarantine open-cli-collective/tap/retune\`)
or clear the quarantine attribute manually:

\`\`\`
xattr -cr /Applications/Retune.app
\`\`\`
EOF
gh release create "$GITHUB_REF_NAME" \
"$artifact" "$artifact.sha256" \
--title "Retune $GITHUB_REF_NAME" \
--notes-file release-notes.md
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,25 @@ Retune is for people who want to maintain a music library, not just stream one.
* Rate albums and tracks, track plays, search, and manage owned playlists.
* Back up, restore, or merge the library as JSON or gzip.

## Install with Homebrew

Retune ships as a prebuilt Apple Silicon app via the
[open-cli-collective tap](https://github.com/open-cli-collective/homebrew-tap):

```sh
brew install --cask --no-quarantine open-cli-collective/tap/retune
```

Release builds are ad-hoc signed but **not notarized** (there is no Apple
Developer ID behind them). Without `--no-quarantine`, Gatekeeper will refuse
to open the app with a "Retune is damaged" dialog. The cask also clears the
quarantine attribute after install; if you downloaded the app some other way,
clear it yourself:

```sh
xattr -cr /Applications/Retune.app
```

## Run from source

Retune currently targets macOS. Building it requires:
Expand Down
3 changes: 3 additions & 0 deletions apps/desktop/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
"bundle": {
"active": true,
"targets": "all",
"macOS": {
"signingIdentity": "-"
},
"icon": [
"icons/32x32.png",
"icons/128x128.png",
Expand Down
6 changes: 6 additions & 0 deletions scripts/build-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ cd "$repo/apps/desktop"
# and we install straight into /Applications anyway).
npx tauri build --bundles app --features dev-token-store

# Tauri ad-hoc signs the bundle (bundle.macOS.signingIdentity is "-" in
# tauri.conf.json — same as release builds). Fail loudly if it didn't.
codesign --verify --deep --strict "$bundle"
codesign -dv "$bundle" 2>&1 | grep -q "Signature=adhoc" \
|| { echo "Expected an ad-hoc signature on $bundle" >&2; exit 1; }

# Quit a running copy before overwriting it, then install fresh.
osascript -e 'quit app "Retune"' >/dev/null 2>&1 || true
rm -rf "$app"
Expand Down