mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-18 13:23:33 +08:00
Windows GitHub runners keep the checkout and Bun install cache on different drives, which can trip Bun's baseline compile-target extraction before Tauri packaging starts. Point desktop sidecar builds at the runner temp cache so dev and release workflows can still use the Windows x64 baseline runtime needed for older CPUs. Constraint: Bun upstream still has an open Windows cross-drive extraction issue for compile target downloads. Rejected: Revert to bun-windows-x64 | would reintroduce the older-CPU Illegal Instruction failure class. Confidence: high Scope-risk: narrow Directive: Keep desktop dev and release sidecar build cache handling aligned until Bun's Windows extraction fix is released and verified in Actions. Tested: bun test scripts/pr/release-workflow.test.ts; cd desktop && bun run test -- --run scripts/build-sidecars.test.ts; bun run check:policy; cd desktop && BUN_INSTALL_CACHE_DIR=/tmp/cc-haha-bun-install-cache TAURI_ENV_TARGET_TRIPLE=x86_64-pc-windows-msvc bun run build:sidecars Not-tested: GitHub Actions Windows runner rerun after push.
247 lines
10 KiB
YAML
247 lines
10 KiB
YAML
name: Build Desktop (Dev)
|
||
|
||
# 开发阶段构建 — 不创建 Release,只上传 Artifacts 供下载测试
|
||
on:
|
||
workflow_dispatch:
|
||
inputs:
|
||
platforms:
|
||
description: 'Build platforms'
|
||
required: true
|
||
default: 'all'
|
||
type: choice
|
||
options:
|
||
- all
|
||
- macos-arm64
|
||
- macos-x64
|
||
- windows-x64
|
||
- linux-x64
|
||
- linux-arm64
|
||
|
||
permissions:
|
||
contents: read
|
||
|
||
concurrency:
|
||
group: build-desktop-dev-${{ github.ref }}
|
||
cancel-in-progress: true
|
||
|
||
jobs:
|
||
# ── 动态生成构建矩阵 ──────────────────────────────────────
|
||
prepare:
|
||
runs-on: ubuntu-latest
|
||
outputs:
|
||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
||
steps:
|
||
- id: set-matrix
|
||
run: |
|
||
ALL='[{"platform":"macos-latest","rust_target":"aarch64-apple-darwin","tauri_args":"--target aarch64-apple-darwin","bundles":"app,dmg","label":"macOS-ARM64","artifact_name":"macos-arm64","asset_platform":"macos","asset_arch":"arm64"},{"platform":"macos-latest","rust_target":"x86_64-apple-darwin","tauri_args":"--target x86_64-apple-darwin","bundles":"app,dmg","label":"macOS-x64","artifact_name":"macos-x64","asset_platform":"macos","asset_arch":"x64"},{"platform":"windows-latest","rust_target":"x86_64-pc-windows-msvc","tauri_args":"","bundles":"msi","label":"Windows-x64","artifact_name":"windows-x64","asset_platform":"windows","asset_arch":"x64"},{"platform":"ubuntu-22.04","rust_target":"x86_64-unknown-linux-gnu","tauri_args":"","bundles":"deb","label":"Linux-x64","artifact_name":"linux-x64","asset_platform":"linux","asset_arch":"x64"},{"platform":"ubuntu-22.04-arm","rust_target":"aarch64-unknown-linux-gnu","tauri_args":"","bundles":"deb","label":"Linux-ARM64","artifact_name":"linux-arm64","asset_platform":"linux","asset_arch":"arm64"}]'
|
||
|
||
SELECTED="${{ inputs.platforms }}"
|
||
if [ "$SELECTED" = "all" ]; then
|
||
MATRIX=$(echo "$ALL" | jq -c '{include: .}')
|
||
else
|
||
MATRIX=$(echo "$ALL" | jq -c --arg sel "$SELECTED" '{include: [.[] | select(
|
||
($sel == "macos-arm64" and .label == "macOS-ARM64") or
|
||
($sel == "macos-x64" and .label == "macOS-x64") or
|
||
($sel == "windows-x64" and .label == "Windows-x64") or
|
||
($sel == "linux-x64" and .label == "Linux-x64") or
|
||
($sel == "linux-arm64" and .label == "Linux-ARM64")
|
||
)]}')
|
||
fi
|
||
echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"
|
||
|
||
# ── 构建 ────────────────────────────────────────────────────
|
||
build:
|
||
needs: prepare
|
||
strategy:
|
||
fail-fast: false
|
||
matrix: ${{ fromJson(needs.prepare.outputs.matrix) }}
|
||
|
||
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 "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||
|
||
# ── 系统依赖 (Linux) ─────────────────────────────────────
|
||
# libfuse2 是 AppImage 运行时依赖:linuxdeploy 工具链本身是 AppImage 格式,
|
||
# 运行时需要 libfuse2,Ubuntu 22.04 默认未安装。
|
||
- 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 ──────────────────────────────────────────────
|
||
- 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 }}
|
||
|
||
# ── 安装依赖 ─────────────────────────────────────────────
|
||
- 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
|
||
|
||
# ── 构建 sidecars ────────────────────────────────────────
|
||
- name: Build sidecars
|
||
working-directory: desktop
|
||
env:
|
||
BUN_INSTALL_CACHE_DIR: ${{ runner.temp }}/bun-install-cache
|
||
TAURI_ENV_TARGET_TRIPLE: ${{ matrix.rust_target }}
|
||
run: bun run build:sidecars
|
||
|
||
# ── 构建 Tauri (无签名、无 updater) ──────────────────────
|
||
- name: Build Tauri app
|
||
working-directory: desktop
|
||
env:
|
||
TAURI_ENV_TARGET_TRIPLE: ${{ matrix.rust_target }}
|
||
run: |
|
||
# 开发构建: 禁用 updater artifacts (不需要签名密钥)
|
||
echo '{"bundle":{"createUpdaterArtifacts":false}}' > /tmp/dev-build.json
|
||
|
||
ARGS=(bunx tauri build --bundles ${{ matrix.bundles }} --ci --config /tmp/dev-build.json)
|
||
|
||
if [ -n "${{ matrix.tauri_args }}" ]; then
|
||
ARGS+=(${{ matrix.tauri_args }})
|
||
fi
|
||
|
||
"${ARGS[@]}"
|
||
shell: bash
|
||
|
||
# ── 收集产物 ─────────────────────────────────────────────
|
||
- name: Collect artifacts
|
||
id: collect
|
||
shell: bash
|
||
run: |
|
||
BUNDLE_DIR="desktop/src-tauri/target/${{ matrix.rust_target }}/release/bundle"
|
||
FALLBACK_DIR="desktop/src-tauri/target/release/bundle"
|
||
|
||
# 优先使用带 target 的路径
|
||
if [ -d "$BUNDLE_DIR" ]; then
|
||
SEARCH_DIR="$BUNDLE_DIR"
|
||
else
|
||
SEARCH_DIR="$FALLBACK_DIR"
|
||
fi
|
||
|
||
STAGING="desktop/build-artifacts/ci-Claude-Code-Haha-v${{ steps.version.outputs.version }}-${{ matrix.artifact_name }}"
|
||
mkdir -p "$STAGING"
|
||
|
||
echo "Searching for artifacts in: $SEARCH_DIR"
|
||
if [ -d "$SEARCH_DIR" ]; then
|
||
find "$SEARCH_DIR" \
|
||
\( -type f \( \
|
||
-name "*.dmg" -o -name "*.msi" -o \
|
||
-name "*.deb" -o -name "*.AppImage" -o -name "*.zip" \
|
||
\) \) -o \
|
||
\( -type d -name "*.app" \) | while read -r f; do
|
||
base="$(basename "$f")"
|
||
bundle="artifact"
|
||
ext=""
|
||
|
||
case "$base" in
|
||
*.app)
|
||
bundle="app"
|
||
ext=".app"
|
||
;;
|
||
*.dmg)
|
||
bundle="dmg"
|
||
ext=".dmg"
|
||
;;
|
||
*.msi)
|
||
bundle="msi"
|
||
ext=".msi"
|
||
;;
|
||
*.deb)
|
||
bundle="deb"
|
||
ext=".deb"
|
||
;;
|
||
*.AppImage)
|
||
bundle="appimage"
|
||
ext=".AppImage"
|
||
;;
|
||
*.zip)
|
||
bundle="zip"
|
||
ext=".zip"
|
||
;;
|
||
*)
|
||
ext=""
|
||
;;
|
||
esac
|
||
|
||
target="Claude-Code-Haha_${{ steps.version.outputs.version }}_${{ matrix.asset_platform }}_${{ matrix.asset_arch }}_${bundle}${ext}"
|
||
echo " Copying: ${base} -> ${target}"
|
||
cp -R "$f" "$STAGING/$target"
|
||
done
|
||
fi
|
||
|
||
echo "staging_dir=$STAGING" >> "$GITHUB_OUTPUT"
|
||
echo "=== Collected artifacts ==="
|
||
ls -lh "$STAGING/" 2>/dev/null || echo "(empty)"
|
||
|
||
# ── 上传为 GitHub Artifact ───────────────────────────────
|
||
- name: Upload artifacts
|
||
uses: actions/upload-artifact@v4
|
||
with:
|
||
name: Claude-Code-Haha-v${{ steps.version.outputs.version }}-${{ matrix.artifact_name }}
|
||
path: ${{ steps.collect.outputs.staging_dir }}
|
||
retention-days: 7
|
||
if-no-files-found: warn
|
||
|
||
# ── 构建完成汇总 ────────────────────────────────────────────
|
||
summary:
|
||
needs: build
|
||
runs-on: ubuntu-latest
|
||
if: always()
|
||
steps:
|
||
- name: Build summary
|
||
run: |
|
||
echo "## Desktop Dev Build Summary" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
echo "| Platform | Status |" >> $GITHUB_STEP_SUMMARY
|
||
echo "|----------|--------|" >> $GITHUB_STEP_SUMMARY
|
||
echo "Branch: \`${{ github.ref_name }}\`" >> $GITHUB_STEP_SUMMARY
|
||
echo "Commit: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
echo "📦 Artifacts are available for download from the **Artifacts** section above." >> $GITHUB_STEP_SUMMARY
|
||
echo "Artifacts will be retained for **7 days**." >> $GITHUB_STEP_SUMMARY
|