Files
capcut-mate/.github/workflows/desktop-client-dev.yml
2026-09-14 11:12:03 +08:00

333 lines
12 KiB
YAML

name: Build
on:
push:
tags:
- 'v*' # 仅在推送 v 开头的 tag 时触发打包
jobs:
# tag 推送时官方不评估 paths,用门禁 job 对比上一 v* tag
changes:
runs-on: ubuntu-latest
outputs:
desktop: ${{ steps.check.outputs.desktop }}
steps:
- name: 准备代码
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: 检查 desktop-client 是否有变更
id: check
run: |
CURRENT="${{ github.ref_name }}"
PREV=$(git tag -l 'v*' --sort=-v:refname | grep -vxF "$CURRENT" | head -n1 || true)
if [ -z "$PREV" ]; then
echo "No previous v* tag; will build."
echo "desktop=true" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "Comparing $PREV..$GITHUB_SHA for desktop-client/ and workflow"
if git diff --quiet "$PREV" "$GITHUB_SHA" -- \
desktop-client/ \
.github/workflows/desktop-client-dev.yml; then
echo "No changes in desktop-client/ or workflow; skip build."
echo "desktop=false" >> "$GITHUB_OUTPUT"
else
echo "desktop-client/ or workflow changed; will build."
echo "desktop=true" >> "$GITHUB_OUTPUT"
fi
build-windows:
needs: changes
if: needs.changes.outputs.desktop == 'true'
runs-on: windows-2022
steps:
- name: 准备代码
uses: actions/checkout@v4
- name: 设置Node.js环境
uses: actions/setup-node@v4
with:
node-version: '22.14.0'
cache: 'npm'
cache-dependency-path: desktop-client/package-lock.json
- name: 安装依赖并构建
working-directory: ./desktop-client
shell: bash
run: |
npm ci
npm --prefix web ci
npm --prefix web run build
node scripts/update-version.js
env:
GITHUB_REF: ${{ github.ref }}
- name: 创建 Windows 安装包
working-directory: ./desktop-client
shell: bash
run: npm run build-win-installer
timeout-minutes: 45
- name: 上传 Windows 安装包
uses: actions/upload-artifact@v4
with:
name: windows-installer
path: desktop-client/dist/capcut-mate-windows-x64-installer.exe
if-no-files-found: error
build-mac-arm64:
needs: changes
if: needs.changes.outputs.desktop == 'true'
runs-on: macos-14
steps:
- name: 准备代码
uses: actions/checkout@v4
- name: 设置Node.js环境
uses: actions/setup-node@v4
with:
node-version: '22.14.0'
cache: 'npm'
cache-dependency-path: desktop-client/package-lock.json
- name: 安装依赖并构建
working-directory: ./desktop-client
run: |
npm ci
npm --prefix web ci
npm --prefix web run build
node scripts/update-version.js
env:
GITHUB_REF: ${{ github.ref }}
- name: 导入 macOS 签名证书
env:
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
run: |
set -euo pipefail
CERTIFICATE_PATH="$RUNNER_TEMP/signing-cert.p12"
KEYCHAIN_PATH="$RUNNER_TEMP/app-signing.keychain-db"
KEYCHAIN_PASSWORD="$(openssl rand -base64 32)"
echo "$CSC_LINK" | openssl base64 -d -A -out "$CERTIFICATE_PATH"
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security import "$CERTIFICATE_PATH" -P "$CSC_KEY_PASSWORD" \
-A -t cert -f pkcs12 -k "$KEYCHAIN_PATH" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security set-key-partition-list \
-S apple-tool:,apple:,codesign: \
-s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security list-keychains -d user -s "$KEYCHAIN_PATH" $(security list-keychains -d user | sed 's/"//g')
security find-identity -v -p codesigning "$KEYCHAIN_PATH"
echo "KEYCHAIN_PATH=$KEYCHAIN_PATH" >> "$GITHUB_ENV"
echo "KEYCHAIN_PASSWORD=$KEYCHAIN_PASSWORD" >> "$GITHUB_ENV"
rm -f "$CERTIFICATE_PATH"
- name: 准备 App Store Connect API Key
env:
APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }}
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
run: |
set -euo pipefail
if [ -z "${APPLE_API_KEY_BASE64:-}" ] || [ -z "${APPLE_API_KEY_ID:-}" ] || [ -z "${APPLE_API_ISSUER:-}" ]; then
echo "Missing required secrets: APPLE_API_KEY_BASE64 / APPLE_API_KEY_ID / APPLE_API_ISSUER"
exit 1
fi
API_KEY_PATH="$RUNNER_TEMP/AuthKey_${APPLE_API_KEY_ID}.p8"
echo "$APPLE_API_KEY_BASE64" | openssl base64 -d -A -out "$API_KEY_PATH"
chmod 600 "$API_KEY_PATH"
if ! grep -q "BEGIN PRIVATE KEY" "$API_KEY_PATH"; then
echo "Decoded APPLE_API_KEY_BASE64 is not a valid .p8 private key"
exit 1
fi
echo "APPLE_API_KEY=$API_KEY_PATH" >> "$GITHUB_ENV"
echo "API key ready: $API_KEY_PATH"
- name: 创建 macOS arm64 安装包
timeout-minutes: 120
working-directory: ./desktop-client
env:
CSC_IDENTITY_AUTO_DISCOVERY: 'true'
NOTARIZE_REQUIRE_API_KEY: '1'
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
MAC_BUILD_MAX_ATTEMPTS: '3'
run: |
chmod +x scripts/ci-build-mac.sh
scripts/ci-build-mac.sh build-mac-installer
- name: 清理 macOS 凭据
if: always()
run: |
if [ -n "${KEYCHAIN_PATH:-}" ]; then
security delete-keychain "$KEYCHAIN_PATH" || true
fi
if [ -n "${APPLE_API_KEY:-}" ]; then
rm -f "$APPLE_API_KEY" || true
fi
- name: 上传 macOS arm64 安装包
uses: actions/upload-artifact@v4
with:
name: macos-arm64-installer
path: desktop-client/dist/capcut-mate-macos-arm64-installer.dmg
if-no-files-found: error
# 等 arm64 公证结束后再跑 x64,降低同时打 Apple 公证接口导致超时的概率
build-mac-x64:
needs: [changes, build-mac-arm64]
if: |
always() &&
needs.changes.outputs.desktop == 'true' &&
needs.build-mac-arm64.result != 'cancelled'
runs-on: macos-15-intel
steps:
- name: 准备代码
uses: actions/checkout@v4
- name: 设置Node.js环境
uses: actions/setup-node@v4
with:
node-version: '22.14.0'
cache: 'npm'
cache-dependency-path: desktop-client/package-lock.json
- name: 安装依赖并构建
working-directory: ./desktop-client
run: |
npm ci
npm --prefix web ci
npm --prefix web run build
node scripts/update-version.js
env:
GITHUB_REF: ${{ github.ref }}
- name: 导入 macOS 签名证书
env:
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
run: |
set -euo pipefail
CERTIFICATE_PATH="$RUNNER_TEMP/signing-cert.p12"
KEYCHAIN_PATH="$RUNNER_TEMP/app-signing.keychain-db"
KEYCHAIN_PASSWORD="$(openssl rand -base64 32)"
echo "$CSC_LINK" | openssl base64 -d -A -out "$CERTIFICATE_PATH"
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security import "$CERTIFICATE_PATH" -P "$CSC_KEY_PASSWORD" \
-A -t cert -f pkcs12 -k "$KEYCHAIN_PATH" \
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security set-key-partition-list \
-S apple-tool:,apple:,codesign: \
-s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security list-keychains -d user -s "$KEYCHAIN_PATH" $(security list-keychains -d user | sed 's/"//g')
security find-identity -v -p codesigning "$KEYCHAIN_PATH"
echo "KEYCHAIN_PATH=$KEYCHAIN_PATH" >> "$GITHUB_ENV"
echo "KEYCHAIN_PASSWORD=$KEYCHAIN_PASSWORD" >> "$GITHUB_ENV"
rm -f "$CERTIFICATE_PATH"
- name: 准备 App Store Connect API Key
env:
APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }}
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
run: |
set -euo pipefail
if [ -z "${APPLE_API_KEY_BASE64:-}" ] || [ -z "${APPLE_API_KEY_ID:-}" ] || [ -z "${APPLE_API_ISSUER:-}" ]; then
echo "Missing required secrets: APPLE_API_KEY_BASE64 / APPLE_API_KEY_ID / APPLE_API_ISSUER"
exit 1
fi
API_KEY_PATH="$RUNNER_TEMP/AuthKey_${APPLE_API_KEY_ID}.p8"
echo "$APPLE_API_KEY_BASE64" | openssl base64 -d -A -out "$API_KEY_PATH"
chmod 600 "$API_KEY_PATH"
if ! grep -q "BEGIN PRIVATE KEY" "$API_KEY_PATH"; then
echo "Decoded APPLE_API_KEY_BASE64 is not a valid .p8 private key"
exit 1
fi
echo "APPLE_API_KEY=$API_KEY_PATH" >> "$GITHUB_ENV"
echo "API key ready: $API_KEY_PATH"
- name: 创建 macOS x64 安装包
timeout-minutes: 120
working-directory: ./desktop-client
env:
CSC_IDENTITY_AUTO_DISCOVERY: 'true'
NOTARIZE_REQUIRE_API_KEY: '1'
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
MAC_BUILD_MAX_ATTEMPTS: '3'
run: |
chmod +x scripts/ci-build-mac.sh
scripts/ci-build-mac.sh build-mac-x64-installer
- name: 清理 macOS 凭据
if: always()
run: |
if [ -n "${KEYCHAIN_PATH:-}" ]; then
security delete-keychain "$KEYCHAIN_PATH" || true
fi
if [ -n "${APPLE_API_KEY:-}" ]; then
rm -f "$APPLE_API_KEY" || true
fi
- name: 上传 macOS x64 安装包
uses: actions/upload-artifact@v4
with:
name: macos-x64-installer
path: desktop-client/dist/capcut-mate-macos-x64-installer.dmg
if-no-files-found: error
release:
needs: [changes, build-windows, build-mac-arm64, build-mac-x64]
if: |
always() &&
startsWith(github.ref, 'refs/tags/v') &&
needs.changes.outputs.desktop == 'true' &&
needs.build-windows.result == 'success' &&
needs.build-mac-arm64.result == 'success' &&
needs.build-mac-x64.result == 'success'
runs-on: ubuntu-latest
steps:
- name: 下载全部安装包
uses: actions/download-artifact@v4
with:
path: release-assets
- name: 整理发布文件
run: |
set -euo pipefail
mkdir -p dist
find release-assets -type f \( -name '*.exe' -o -name '*.dmg' \) -print -exec cp {} dist/ \;
ls -lh dist/
- name: 发布到 GitHub Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ github.ref_name }}
name: Release ${{ github.ref_name }}
files: |
dist/capcut-mate-windows-x64-installer.exe
dist/capcut-mate-macos-arm64-installer.dmg
dist/capcut-mate-macos-x64-installer.dmg
overwrite: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}