- Configure Tauri updater plugin with Ed25519 signing - Add GitHub Actions support for signed builds - Set up GitHub releases as update endpoint - Enable update checking in Settings modal
227 lines
7.8 KiB
YAML
227 lines
7.8 KiB
YAML
name: Release
|
||
|
||
on:
|
||
push:
|
||
tags:
|
||
- 'v*'
|
||
|
||
permissions:
|
||
contents: write
|
||
|
||
jobs:
|
||
release:
|
||
runs-on: ${{ matrix.os }}
|
||
strategy:
|
||
matrix:
|
||
include:
|
||
- os: windows-latest
|
||
- os: ubuntu-latest
|
||
- os: macos-latest
|
||
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
|
||
- name: Setup Node.js
|
||
uses: actions/setup-node@v4
|
||
with:
|
||
node-version: '20'
|
||
|
||
- name: Setup Rust
|
||
uses: dtolnay/rust-toolchain@stable
|
||
|
||
- name: Add macOS targets
|
||
if: runner.os == 'macOS'
|
||
run: |
|
||
rustup target add aarch64-apple-darwin x86_64-apple-darwin
|
||
|
||
- name: Install Linux system deps
|
||
if: runner.os == 'Linux'
|
||
shell: bash
|
||
run: |
|
||
set -euxo pipefail
|
||
sudo apt-get update
|
||
# Core build tools and pkg-config
|
||
sudo apt-get install -y --no-install-recommends \
|
||
build-essential \
|
||
pkg-config \
|
||
curl \
|
||
wget \
|
||
file \
|
||
patchelf \
|
||
libssl-dev
|
||
# GTK/GLib stack for gdk-3.0, glib-2.0, gio-2.0
|
||
sudo apt-get install -y --no-install-recommends \
|
||
libgtk-3-dev \
|
||
librsvg2-dev \
|
||
libayatana-appindicator3-dev
|
||
# WebKit2GTK (version differs across Ubuntu images; try 4.1 then 4.0)
|
||
sudo apt-get install -y --no-install-recommends libwebkit2gtk-4.1-dev \
|
||
|| sudo apt-get install -y --no-install-recommends libwebkit2gtk-4.0-dev
|
||
# libsoup also changed major version; prefer 3.0 with fallback to 2.4
|
||
sudo apt-get install -y --no-install-recommends libsoup-3.0-dev \
|
||
|| sudo apt-get install -y --no-install-recommends libsoup2.4-dev
|
||
|
||
- name: Setup pnpm
|
||
uses: pnpm/action-setup@v2
|
||
with:
|
||
version: 10.12.3
|
||
run_install: false
|
||
|
||
- name: Get pnpm store directory
|
||
id: pnpm-store
|
||
shell: bash
|
||
run: echo "path=$(pnpm store path --silent)" >> $GITHUB_OUTPUT
|
||
|
||
- name: Setup pnpm cache
|
||
uses: actions/cache@v3
|
||
with:
|
||
path: ${{ steps.pnpm-store.outputs.path }}
|
||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||
restore-keys: ${{ runner.os }}-pnpm-store-
|
||
|
||
- name: Install frontend deps
|
||
run: pnpm install --frozen-lockfile
|
||
|
||
- name: Build Tauri App (macOS)
|
||
if: runner.os == 'macOS'
|
||
env:
|
||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
||
run: pnpm tauri build --target universal-apple-darwin
|
||
|
||
- name: Build Tauri App (Windows)
|
||
if: runner.os == 'Windows'
|
||
env:
|
||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
||
run: pnpm tauri build
|
||
|
||
- name: Build Tauri App (Linux)
|
||
if: runner.os == 'Linux'
|
||
env:
|
||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
||
run: pnpm tauri build
|
||
|
||
- name: Prepare macOS Assets
|
||
if: runner.os == 'macOS'
|
||
shell: bash
|
||
run: |
|
||
set -euxo pipefail
|
||
mkdir -p release-assets
|
||
echo "Looking for .app bundle..."
|
||
APP_PATH=""
|
||
for path in \
|
||
"src-tauri/target/release/bundle/macos" \
|
||
"src-tauri/target/universal-apple-darwin/release/bundle/macos" \
|
||
"src-tauri/target/aarch64-apple-darwin/release/bundle/macos" \
|
||
"src-tauri/target/x86_64-apple-darwin/release/bundle/macos"; do
|
||
if [ -d "$path" ]; then
|
||
APP_PATH=$(find "$path" -name "*.app" -type d | head -1)
|
||
[ -n "$APP_PATH" ] && break
|
||
fi
|
||
done
|
||
if [ -z "$APP_PATH" ]; then
|
||
echo "No .app found" >&2
|
||
exit 1
|
||
fi
|
||
APP_DIR=$(dirname "$APP_PATH")
|
||
APP_NAME=$(basename "$APP_PATH")
|
||
cd "$APP_DIR"
|
||
# 使用 ditto 打包更兼容资源分叉
|
||
ditto -c -k --sequesterRsrc --keepParent "$APP_NAME" "CC-Switch-macOS.zip"
|
||
mv "CC-Switch-macOS.zip" "$GITHUB_WORKSPACE/release-assets/"
|
||
echo "macOS zip ready"
|
||
|
||
- name: Prepare Windows Assets
|
||
if: runner.os == 'Windows'
|
||
shell: pwsh
|
||
run: |
|
||
$ErrorActionPreference = 'Stop'
|
||
New-Item -ItemType Directory -Force -Path release-assets | Out-Null
|
||
# 安装器(优先 NSIS,其次 MSI)
|
||
$installer = Get-ChildItem -Path 'src-tauri/target/release/bundle' -Recurse -Include *.exe,*.msi -ErrorAction SilentlyContinue |
|
||
Where-Object { $_.FullName -match '\\bundle\\(nsis|msi)\\' } |
|
||
Select-Object -First 1
|
||
if ($null -ne $installer) {
|
||
$dest = if ($installer.Extension -ieq '.msi') { 'CC-Switch-Setup.msi' } else { 'CC-Switch-Setup.exe' }
|
||
Copy-Item $installer.FullName (Join-Path release-assets $dest)
|
||
Write-Host "Installer copied: $dest"
|
||
} else {
|
||
Write-Warning 'No Windows installer found'
|
||
}
|
||
# 绿色版(portable):仅可执行文件
|
||
$exeCandidates = @(
|
||
'src-tauri/target/release/cc-switch.exe',
|
||
'src-tauri/target/x86_64-pc-windows-msvc/release/cc-switch.exe'
|
||
)
|
||
$exePath = $exeCandidates | Where-Object { Test-Path $_ } | Select-Object -First 1
|
||
if ($null -ne $exePath) {
|
||
$portableDir = 'release-assets/CC-Switch-Portable'
|
||
New-Item -ItemType Directory -Force -Path $portableDir | Out-Null
|
||
Copy-Item $exePath $portableDir
|
||
Compress-Archive -Path "$portableDir/*" -DestinationPath 'release-assets/CC-Switch-Windows-Portable.zip' -Force
|
||
Remove-Item -Recurse -Force $portableDir
|
||
Write-Host 'Windows portable zip created'
|
||
} else {
|
||
Write-Warning 'Portable exe not found'
|
||
}
|
||
|
||
- name: Prepare Linux Assets
|
||
if: runner.os == 'Linux'
|
||
shell: bash
|
||
run: |
|
||
set -euxo pipefail
|
||
mkdir -p release-assets
|
||
# 仅上传安装包(deb)
|
||
DEB=$(find src-tauri/target/release/bundle -name "*.deb" | head -1 || true)
|
||
if [ -n "$DEB" ]; then
|
||
cp "$DEB" release-assets/
|
||
echo "Deb package copied"
|
||
else
|
||
echo "No .deb found" >&2
|
||
exit 1
|
||
fi
|
||
|
||
- name: List prepared assets
|
||
shell: bash
|
||
run: |
|
||
ls -la release-assets || true
|
||
|
||
- name: Collect Signatures
|
||
shell: bash
|
||
run: |
|
||
# 查找并复制签名文件到 release-assets
|
||
find src-tauri/target -name "*.sig" -type f 2>/dev/null | while read sig; do
|
||
cp "$sig" release-assets/ || true
|
||
done
|
||
echo "Collected signatures:"
|
||
ls -la release-assets/*.sig || echo "No signatures found"
|
||
|
||
- name: Upload Release Assets
|
||
uses: softprops/action-gh-release@v1
|
||
with:
|
||
tag_name: ${{ github.ref_name }}
|
||
name: CC Switch ${{ github.ref_name }}
|
||
body: |
|
||
## CC Switch ${{ github.ref_name }}
|
||
|
||
Claude Code 供应商切换工具
|
||
|
||
### 下载
|
||
|
||
- macOS: `CC-Switch-macOS.zip`(解压即用)
|
||
- Windows: `CC-Switch-Setup.exe` 或 `CC-Switch-Setup.msi`(安装版);`CC-Switch-Windows-Portable.zip`(绿色版)
|
||
- Linux: `*.deb`(Debian/Ubuntu 安装包)
|
||
|
||
---
|
||
提示:macOS 如遇“已损坏”提示,可在终端执行:`xattr -cr "/Applications/CC Switch.app"`
|
||
files: release-assets/*
|
||
env:
|
||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||
|
||
- name: List generated bundles (debug)
|
||
if: always()
|
||
shell: bash
|
||
run: |
|
||
echo "Listing bundles in src-tauri/target..."
|
||
find src-tauri/target -maxdepth 4 -type f -name "*.*" 2>/dev/null || true
|