cc-haha/.github/workflows/release-desktop.yml
程序员阿江(Relakkes) 47b3cc4d40 Reduce Windows installer confusion and heuristic AV exposure
Windows releases were shipping both NSIS exe and MSI bundles, which made the
release page harder to understand and increased the chance that users would
pick the wrong asset. Restricting Windows output to MSI narrows the installer
surface while the release asset naming now spells out platform, architecture,
and bundle type directly in every published filename.

Constraint: Remote desktop packaging is triggered by GitHub Actions releases, not local uploads
Constraint: Updater metadata must keep latest.json stable for existing clients
Rejected: Keep publishing both NSIS and MSI with better docs | still leaves the higher-risk installer on the release page
Rejected: Rename assets manually after upload | easy to drift from workflow output and updater metadata
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: If Windows exe bundles are reintroduced later, reassess SmartScreen and AV impact before publishing them again
Tested: YAML parse for both desktop workflows; git diff --check on modified files; manual review of PowerShell changes
Not-tested: End-to-end GitHub Actions release run; PowerShell parser validation on a Windows host
2026-04-21 18:26:42 +08:00

182 lines
6.1 KiB
YAML

name: Release Desktop
on:
push:
tags: ['v*.*.*']
workflow_dispatch:
inputs:
draft:
description: 'Create as draft release'
required: false
default: true
type: boolean
permissions:
contents: write
concurrency:
group: release-desktop-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
# macOS Apple Silicon
- platform: macos-latest
rust_target: aarch64-apple-darwin
tauri_args: '--target aarch64-apple-darwin'
label: macOS-ARM64
asset_name_pattern: 'Claude-Code-Haha_[version]_macos_arm64_[bundle][ext]'
# macOS Intel
- platform: macos-latest
rust_target: x86_64-apple-darwin
tauri_args: '--target x86_64-apple-darwin'
label: macOS-x64
asset_name_pattern: 'Claude-Code-Haha_[version]_macos_x64_[bundle][ext]'
# Linux x64
- platform: ubuntu-22.04
rust_target: x86_64-unknown-linux-gnu
tauri_args: '--bundles deb'
label: Linux-x64
asset_name_pattern: 'Claude-Code-Haha_[version]_linux_x64_[bundle][ext]'
# Linux ARM64
- platform: ubuntu-22.04-arm
rust_target: aarch64-unknown-linux-gnu
tauri_args: '--bundles deb'
label: Linux-ARM64
asset_name_pattern: 'Claude-Code-Haha_[version]_linux_arm64_[bundle][ext]'
# Windows x64
- platform: windows-latest
rust_target: x86_64-pc-windows-msvc
tauri_args: '--bundles msi'
label: Windows-x64
asset_name_pattern: 'Claude-Code-Haha_[version]_windows_x64_[bundle][ext]'
runs-on: ${{ matrix.platform }}
name: Build (${{ matrix.label }})
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Read version
id: version
shell: bash
run: |
VERSION=$(jq -r '.version' desktop/src-tauri/tauri.conf.json)
echo "value=$VERSION" >> "$GITHUB_OUTPUT"
- name: Validate tag matches version
if: github.event_name == 'push'
shell: bash
run: |
EXPECTED_TAG="v${{ steps.version.outputs.value }}"
if [ "${GITHUB_REF_NAME}" != "$EXPECTED_TAG" ]; then
echo "::error::Tag ${GITHUB_REF_NAME} does not match app version ${EXPECTED_TAG}"
exit 1
fi
- name: Load release notes
id: release_notes
shell: bash
run: |
NOTES_FILE="release-notes/v${{ steps.version.outputs.value }}.md"
if [ ! -f "$NOTES_FILE" ]; then
echo "::error::Missing release notes file: $NOTES_FILE"
exit 1
fi
{
echo 'body<<__RELEASE_NOTES__'
cat "$NOTES_FILE"
echo
echo '__RELEASE_NOTES__'
} >> "$GITHUB_OUTPUT"
# ── System dependencies (Linux) ──────────────────────────
- name: Install Linux dependencies
if: contains(matrix.platform, 'ubuntu')
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
curl \
wget \
file \
libxdo-dev \
libssl-dev \
libwebkit2gtk-4.1-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
patchelf \
libfuse2
# ── Bun ──────────────────────────────────────────────────
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
# ── Node.js (for tauri-action compatibility) ─────────────
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
# ── Rust ─────────────────────────────────────────────────
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.rust_target }}
- name: Rust cache
uses: swatinem/rust-cache@v2
with:
workspaces: 'desktop/src-tauri -> target'
shared-key: ${{ matrix.rust_target }}
# ── Install dependencies ─────────────────────────────────
- name: Install root dependencies
run: bun install
- name: Install desktop dependencies
working-directory: desktop
run: bun install
- name: Install adapter dependencies
working-directory: adapters
run: bun install
# ── Build sidecars ───────────────────────────────────────
- name: Build sidecars
working-directory: desktop
env:
TAURI_ENV_TARGET_TRIPLE: ${{ matrix.rust_target }}
run: bun run build:sidecars
# ── Build Tauri app ──────────────────────────────────────
- name: Build Tauri app
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
with:
projectPath: desktop
tauriScript: bunx tauri
tagName: v__VERSION__
releaseName: 'Claude Code Haha v__VERSION__'
releaseBody: ${{ steps.release_notes.outputs.body }}
releaseDraft: ${{ github.event_name == 'workflow_dispatch' && inputs.draft || false }}
prerelease: false
updaterJsonPreferNsis: false
releaseAssetNamePattern: ${{ matrix.asset_name_pattern }}
args: ${{ matrix.tauri_args }} --config src-tauri/tauri.release-ci.json