feat: add cross-platform release pipeline and app icons

- Update tauri.conf.json with multi-platform bundle config (macOS unsigned, Windows unsigned)
- Add app icon (1024x1024 source) and generate all required sizes (png, icns, ico)
- Add generate-icons.sh script for regenerating icons from source PNG
- Add GitHub Actions release workflow for 4-target parallel builds (macOS ARM/x64, Linux, Windows)
- Simplify release.sh with tag-based publish instructions

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
zhixian
2026-02-19 11:27:13 +09:00
parent 3b0a776a9f
commit 9717a64310
10 changed files with 205 additions and 7 deletions

92
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,92 @@
name: Release
on:
push:
tags: ['v*']
permissions:
contents: write
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- platform: macos-latest
target: aarch64-apple-darwin
label: macOS-ARM64
- platform: macos-latest
target: x86_64-apple-darwin
label: macOS-x64
- platform: ubuntu-22.04
target: x86_64-unknown-linux-gnu
label: Linux-x64
- platform: windows-latest
target: x86_64-pc-windows-msvc
label: Windows-x64
runs-on: ${{ matrix.platform }}
name: Build (${{ matrix.label }})
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Rust cache
uses: swatinem/rust-cache@v2
with:
workspaces: src-tauri
- name: Install Linux dependencies
if: matrix.platform == 'ubuntu-22.04'
run: |
sudo apt-get update
sudo apt-get install -y \
libwebkit2gtk-4.1-dev \
libappindicator3-dev \
librsvg2-dev \
patchelf
- name: Install frontend dependencies
run: npm ci
- name: Build Tauri app
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_SIGNING_PRIVATE_KEY: ''
with:
tagName: ${{ github.ref_name }}
releaseName: ClawPal ${{ github.ref_name }}
releaseBody: |
## ClawPal ${{ github.ref_name }}
### Installation
**macOS** (unsigned — requires manual approval):
- Download the `.dmg` for your architecture (ARM for Apple Silicon, x64 for Intel)
- Open the DMG and drag ClawPal to Applications
- First launch: right-click the app → Open, or run `xattr -cr /Applications/ClawPal.app`
**Windows** (unsigned — SmartScreen will warn):
- Download the `.exe` (NSIS installer) or `.msi`
- If SmartScreen blocks: click "More info" → "Run anyway"
**Linux**:
- `.deb`: `sudo dpkg -i clawpal_*.deb`
- `.AppImage`: `chmod +x ClawPal_*.AppImage && ./ClawPal_*.AppImage`
releaseDraft: true
prerelease: false
args: --target ${{ matrix.target }}

83
scripts/generate-icons.sh Executable file
View File

@@ -0,0 +1,83 @@
#!/usr/bin/env bash
set -euo pipefail
# Generate platform icons from a 1024x1024 source PNG
# Usage: ./scripts/generate-icons.sh [source.png]
# Defaults to src-tauri/icons/icon.png
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
SOURCE="${1:-$PROJECT_ROOT/src-tauri/icons/icon.png}"
ICON_DIR="$PROJECT_ROOT/src-tauri/icons"
if [ ! -f "$SOURCE" ]; then
echo "Error: source image not found: $SOURCE"
exit 1
fi
echo "Generating icons from: $SOURCE"
echo "Output directory: $ICON_DIR"
# sips -z modifies the source file in-place even with --out, so we work from a
# temporary copy to preserve the original 1024x1024 PNG.
TMP_DIR=$(mktemp -d)
SAFE_SOURCE="$TMP_DIR/source.png"
cp "$SOURCE" "$SAFE_SOURCE"
resize() {
# resize <size> <output_path>
# Use -Z (resample to max dimension) instead of -z to preserve alpha/transparency
cp "$SAFE_SOURCE" "$2"
sips -Z "$1" "$2" >/dev/null
}
# PNG sizes needed by Tauri
resize 32 "$ICON_DIR/32x32.png"
resize 128 "$ICON_DIR/128x128.png"
resize 256 "$ICON_DIR/128x128@2x.png"
echo " Created 32x32.png, 128x128.png, 128x128@2x.png"
# macOS .icns via iconutil
ICONSET_DIR="$TMP_DIR/icon.iconset"
mkdir -p "$ICONSET_DIR"
resize 16 "$ICONSET_DIR/icon_16x16.png"
resize 32 "$ICONSET_DIR/icon_16x16@2x.png"
resize 32 "$ICONSET_DIR/icon_32x32.png"
resize 64 "$ICONSET_DIR/icon_32x32@2x.png"
resize 128 "$ICONSET_DIR/icon_128x128.png"
resize 256 "$ICONSET_DIR/icon_128x128@2x.png"
resize 256 "$ICONSET_DIR/icon_256x256.png"
resize 512 "$ICONSET_DIR/icon_256x256@2x.png"
resize 512 "$ICONSET_DIR/icon_512x512.png"
resize 1024 "$ICONSET_DIR/icon_512x512@2x.png"
iconutil -c icns "$ICONSET_DIR" -o "$ICON_DIR/icon.icns"
echo " Created icon.icns"
# Windows .ico
# Try magick (ImageMagick), then png2ico, then skip
if command -v magick &>/dev/null; then
magick "$SAFE_SOURCE" -define icon:auto-resize=256,128,64,48,32,16 "$ICON_DIR/icon.ico"
echo " Created icon.ico (via ImageMagick)"
elif command -v convert &>/dev/null; then
convert "$SAFE_SOURCE" -define icon:auto-resize=256,128,64,48,32,16 "$ICON_DIR/icon.ico"
echo " Created icon.ico (via convert)"
elif command -v png2ico &>/dev/null; then
# png2ico requires width < 256 and multiple of 8
TMP_ICO_DIR="$TMP_DIR/ico"
mkdir -p "$TMP_ICO_DIR"
resize 128 "$TMP_ICO_DIR/128.png"
resize 48 "$TMP_ICO_DIR/48.png"
resize 32 "$TMP_ICO_DIR/32.png"
resize 16 "$TMP_ICO_DIR/16.png"
png2ico "$ICON_DIR/icon.ico" "$TMP_ICO_DIR/128.png" "$TMP_ICO_DIR/48.png" "$TMP_ICO_DIR/32.png" "$TMP_ICO_DIR/16.png"
echo " Created icon.ico (via png2ico)"
else
echo " WARNING: No tool found to create icon.ico (install ImageMagick: brew install imagemagick)"
echo " Skipping .ico generation"
fi
rm -rf "$TMP_DIR"
echo "Done! Icons generated in $ICON_DIR"

View File

@@ -19,12 +19,21 @@ run_or_print() {
fi
}
say "ClawPal MVP release assistant"
VERSION=$(node -p "require('./package.json').version")
say "ClawPal v${VERSION} release assistant"
say "======================================"
run_or_print "npm run typecheck"
run_or_print "npm run build"
run_or_print "cd src-tauri && cargo fmt --all --check"
run_or_print "cd src-tauri && cargo check"
run_or_print "cd src-tauri && cargo check --target-dir target/check"
run_or_print "cd src-tauri && cargo check"
run_or_print "cd src-tauri && cargo tauri build"
say "Done."
say ""
say "Local build complete!"
say ""
say "To publish via GitHub Actions (builds macOS + Windows + Linux):"
say " git tag v${VERSION}"
say " git push origin v${VERSION}"
say ""
say "This will trigger .github/workflows/release.yml and create a draft release."

BIN
src-tauri/icons/128x128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
src-tauri/icons/32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src-tauri/icons/icon.icns Normal file

Binary file not shown.

BIN
src-tauri/icons/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 228 B

After

Width:  |  Height:  |  Size: 579 KiB

View File

@@ -20,7 +20,21 @@
},
"bundle": {
"active": true,
"icon": [],
"targets": ["deb", "dmg", "msi"]
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
],
"targets": "all",
"macOS": {
"minimumSystemVersion": "10.15",
"signingIdentity": null
},
"windows": {
"certificateThumbprint": null,
"timestampUrl": ""
}
}
}