mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-17 13:13:35 +08:00
The local desktop build path already proved that AppImage packaging needs libfuse2 and that macOS artifacts may be directories rather than plain files. This commit aligns the GitHub workflows with those realities so remote validation matches the local release path more closely. Constraint: GitHub-hosted Linux runners do not guarantee AppImage runtime deps unless we install them explicitly Rejected: Leave release workflow unchanged and trust local macOS build only | would not validate Linux packaging path at all Rejected: Upload only DMG/installer files in dev workflow | hides the macOS .app artifact users expect for local testing Confidence: high Scope-risk: narrow Reversibility: clean Directive: Keep dev and release desktop dependency lists in sync when packaging requirements change Tested: git diff --check; YAML parse of both workflow files; manual inspection of artifact collection and Linux dependency steps Not-tested: Live GitHub Actions execution on repository runners
211 lines
8.9 KiB
YAML
211 lines
8.9 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"},{"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"},{"platform":"windows-latest","rust_target":"x86_64-pc-windows-msvc","tauri_args":"","bundles":"nsis,msi","label":"Windows-x64","artifact_name":"windows-x64"},{"platform":"ubuntu-22.04","rust_target":"x86_64-unknown-linux-gnu","tauri_args":"","bundles":"deb,appimage","label":"Linux-x64","artifact_name":"linux-x64"},{"platform":"ubuntu-22.04-arm","rust_target":"aarch64-unknown-linux-gnu","tauri_args":"","bundles":"deb,appimage","label":"Linux-ARM64","artifact_name":"linux-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:
|
||
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 "*.exe" -o -name "*.msi" -o \
|
||
-name "*.deb" -o -name "*.AppImage" -o -name "*.zip" \
|
||
\) \) -o \
|
||
\( -type d -name "*.app" \) | while read -r f; do
|
||
echo " Copying: $(basename "$f")"
|
||
cp -R "$f" "$STAGING/"
|
||
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
|