第 46 章 CI/CD 多平台打包与代码签名
本章目标
- GitHub Actions 三平台矩阵构建。
- macOS 公证(notarization)。
- Windows 代码签名。
- Linux
.deb、.rpm、AppImage。 - 产物上传到 Releases 并自动生成
latest.json。
一、Workflow 骨架
.github/workflows/release.yml:
name: Release
on:
push:
tags: ["v*"]
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- { platform: "macos-14", args: "--target aarch64-apple-darwin" }
- { platform: "macos-14", args: "--target x86_64-apple-darwin" }
- { platform: "windows-latest", args: "" }
- { platform: "ubuntu-22.04", args: "" }
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: "20", cache: "pnpm" }
- uses: pnpm/action-setup@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with: { workspaces: "./src-tauri -> target" }
- name: install (linux)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev
- run: pnpm install --frozen-lockfile
- name: Build & sign
uses: tauri-apps/tauri-action@v0
env:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PASSWORD }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERT }}
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERT_PASSWORD }}
with:
tagName: ${{ github.ref_name }}
releaseName: "CloudTone ${{ github.ref_name }}"
releaseBody: "See CHANGELOG.md"
releaseDraft: true
args: ${{ matrix.args }}
二、macOS 公证
- 在 Apple Developer 后台申请 "Developer ID Application" 证书。
- 导出 .p12,用 base64 放
APPLE_CERTIFICATE。 - 创建 app-specific password,放
APPLE_ID_PASSWORD。 APPLE_TEAM_ID= 10 位字符。
tauri.conf.json:
"bundle": {
"macOS": {
"minimumSystemVersion": "11.0",
"entitlements": "./entitlements.plist",
"hardenedRuntime": true,
"providerShortName": "XXXXXXXXXX",
"signingIdentity": "Developer ID Application: Your Name (XXXXXXXXXX)"
}
}
entitlements.plist 至少包含:
<plist><dict>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/>
<key>com.apple.security.device.audio-input</key><false/>
</dict></plist>
tauri-action 会在有对应 env 时自动 notarize。
三、Windows 代码签名
- 个人开发者:EV 证书贵 ($300/年),普通 OV 也行但 SmartScreen 要积累信誉。
- 生成
.pfx,base64 放 secret。 tauri.conf.json:
"bundle": {
"windows": {
"certificateThumbprint": null,
"digestAlgorithm": "sha256",
"timestampUrl": "http://timestamp.sectigo.com"
}
}
tauri-action 会用证书签 .exe 和 .msi。
四、Linux
三种产物:
.deb(Debian/Ubuntu):cargo tauri build自动生成。.rpm(Fedora/RHEL):需要 rpmbuild。.AppImage:Tauri 默认生成。
如果没有 code signing,至少发 SHA256 摘要文件。
五、生成 latest.json
tauri-action 输出每个平台的 signature。用后置步骤拼接:
collect:
needs: build
runs-on: ubuntu-22.04
steps:
- uses: actions/download-artifact@v4
- run: node scripts/compose-latest-json.js
- uses: softprops/action-gh-release@v2
with:
files: latest.json
scripts/compose-latest-json.js 读取各平台的 .sig,输出合并后的 JSON(第 43 章的结构)。
六、稳定 vs 预发
- 分支
main自动 build 但releaseDraft: true,只上传 artifact。 - 打 tag
v1.2.3走 stable endpoint。 - 打 tag
v1.2.3-beta.1走 beta endpoint。
args: ${{ matrix.args }} ${{ startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-beta') && '' || '--config src-tauri/tauri.beta.conf.json' }}
七、加速构建
Swatinem/rust-cache@v2缓存 target。pnpm store缓存 node_modules。- macOS runner 用
macos-14(Apple Silicon,速度快 2-3x)。 - Windows 用 sccache:
- uses: mozilla-actions/sccache-action@v0.0.3
- run: echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV
八、供应链安全
- Secret 只加在需要它的 job 上,用
environment审核。 - 用
cargo-audit+npm audit每周跑一次。 - 生成 SBOM(
cargo sbom+cyclonedx-bom)。
本章小结
- Tauri-action 封装了 80% 的打包细节。
- 签名和公证是"门槛成本",搞定一次终身受益。
- 矩阵构建 + 缓存 = CI 20 分钟内出四平台包。
动手时刻
- 打一个 v0.1.0,手动下载每平台包验证能启动。
-
macOS 包装后用
spctl -a -v检查公证。
下一章:发布、分发、监控。