tauri build 基础
# 构建当前平台的安装包
npm run tauri build
# 指定安装包格式
npm run tauri build -- --bundles nsis # Windows NSIS 安装向导
npm run tauri build -- --bundles msi # Windows MSI
npm run tauri build -- --bundles dmg # macOS DMG
npm run tauri build -- --bundles appimage # Linux AppImage
npm run tauri build -- --bundles deb # Debian/Ubuntu .deb
# 调试构建(不启用优化,保留符号)
npm run tauri build -- --debug
# 构建产出目录
# src-tauri/target/release/bundle/
# ├── macos/ → .app, .dmg
# ├── nsis/ → *-setup.exe
# ├── msi/ → *.msi
# └── appimage/ → *.AppImage
tauri.conf.json 打包配置
{
"bundle": {
"active": true,
"targets": "all",
"identifier": "com.mycompany.myapp",
"publisher": "My Company",
"copyright": "Copyright © 2024 My Company",
"category": "DeveloperTool",
"shortDescription": "My awesome desktop app",
"longDescription": "A longer description for app stores",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
],
"windows": {
"wix": { "language": "zh-CN" },
"nsis": {
"languages": ["SimpChinese", "English"],
"installMode": "currentUser"
}
},
"macOS": {
"signingIdentity": "Developer ID Application: My Company (XXXXXXXXXX)",
"entitlements": "entitlements.plist",
"minimumSystemVersion": "10.15"
},
"linux": {
"deb": {
"depends": ["libwebkit2gtk-4.1-0", "libayatana-appindicator3-1"]
}
}
}
}
macOS 代码签名与公证
# 本地 macOS 签名所需环境变量
export APPLE_CERTIFICATE="base64编码的p12证书"
export APPLE_CERTIFICATE_PASSWORD="证书密码"
export APPLE_SIGNING_IDENTITY="Developer ID Application: My Company (XXXXXXXXXX)"
# 公证所需(使用 App Store Connect API Key)
export APPLE_API_ISSUER="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
export APPLE_API_KEY="XXXXXXXXXX"
export APPLE_API_KEY_PATH="/path/to/AuthKey_XXXXXXXXXX.p8"
# tauri build 会自动读取这些环境变量完成签名+公证
npm run tauri build
Windows 代码签名
# Windows 签名所需环境变量
# 方式1:使用 .pfx 证书文件
export TAURI_SIGNING_PRIVATE_KEY="base64编码的pfx"
export TAURI_SIGNING_PRIVATE_KEY_PASSWORD="证书密码"
# 方式2:使用 Azure Trusted Signing(推荐,无需本地存储证书)
# 在 tauri.conf.json 中配置 signtool 选项
GitHub Actions 跨平台矩阵构建
# .github/workflows/release.yml
name: Release
on:
push:
tags: ['v*']
jobs:
release:
permissions:
contents: write
strategy:
fail-fast: false
matrix:
include:
- platform: macos-latest
args: '--target aarch64-apple-darwin' # Apple Silicon
- platform: macos-latest
args: '--target x86_64-apple-darwin' # Intel Mac
- platform: ubuntu-22.04
args: ''
- platform: windows-latest
args: ''
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4
- name: Install Linux dependencies
if: matrix.platform == 'ubuntu-22.04'
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev \
build-essential curl wget file \
libxdo-dev libssl-dev \
libayatana-appindicator3-dev librsvg2-dev
- uses: actions/setup-node@v4
with:
node-version: lts/*
cache: npm
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
- uses: Swatinem/rust-cache@v2
with:
workspaces: 'src-tauri -> target'
- run: npm install
- uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# macOS 签名
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
APPLE_API_KEY_PATH: ${{ secrets.APPLE_API_KEY_PATH }}
with:
tagName: ${{ github.ref_name }}
releaseName: 'v__VERSION__'
releaseBody: 'See CHANGELOG.md for release notes.'
releaseDraft: true
prerelease: false
args: ${{ matrix.args }}
tauri-apps/tauri-action GitHub Action 会自动完成前端构建、Rust 编译、代码签名、公证、生成安装包,并将产物上传到 GitHub Release,是最简单的发布方式。使用 tagName 中的 __VERSION__ 占位符会自动替换为 tauri.conf.json 中的版本号。
同时构建 Apple Silicon (arm64) 和 Intel (x86_64) 两个版本是最佳实践,而非合并为 Universal Binary——这样可以减小每个安装包的体积,用户按自己的架构下载对应版本。在矩阵中分别指定 --target aarch64-apple-darwin 和 --target x86_64-apple-darwin。
代码签名的技术原理
为什么需要代码签名?
代码签名不只是"为了绕过系统警告",而是现代操作系统安全体系的重要组成部分:
GitHub Actions 签名的安全实践
签名 Secrets 的安全管理:
绝不要:
✗ 把证书文件(.p12, .pfx)提交到 git 仓库
✗ 在 Actions 日志中打印证书密码
✗ 把私钥存储在公开 Secrets(用 repository secrets,非 environment secrets)
推荐做法:
✓ 证书用 base64 编码后存储到 GitHub Secrets
base64 -i certificate.p12 | pbcopy (macOS)
✓ 限制 Actions workflow 只能在特定分支(main/release/*)触发
✓ 为 Release 构建单独创建 GitHub Environment(production),
限制只有特定 reviewers 能审批才会使用签名 Secrets
✓ 使用 GitHub OIDC + Apple Notary Tool(避免存储 Apple ID 密码)
苹果公证的新方式(推荐):
旧方式(altool):需要存储 Apple ID + app-specific password
新方式(notarytool + API Key):只需要存储 API Key(可以随时吊销)
格式:APPLE_API_KEY_ID + APPLE_API_ISSUER + APPLE_API_KEY(私钥文件)
代码签名证书通常有效期 1-2 年。证书过期后,已经签名的旧版本仍然有效(签名时的时间戳被公证服务器记录),但新版本无法再签名,必须续期。建议在 Tauri 项目的 README 中记录证书过期时间,并在日历中设置提前 30 天的提醒,以免影响正常发布。
构建缓存优化
Tauri 的 CI 构建主要耗时在 Rust 编译上,合理配置缓存可以将构建时间从 20 分钟缩短到 3-5 分钟:
# GitHub Actions 缓存配置
- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
workspaces: 'src-tauri -> target'
# 仅缓存 release profile 的依赖
cache-on-failure: true
- name: Cache Node modules
uses: actions/cache@v4
with:
path: node_modules
key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
sccache(Shared Compilation Cache)是 Mozilla 开发的编译缓存工具,可以在不同 CI job 之间共享 Rust 编译缓存,存储到 S3 或 GitHub Actions 缓存中。对于 Tauri 项目,sccache 可以将矩阵中各平台的编译时间都大幅缩短,特别是当 Rust 依赖没有变化时。
Linux 包格式选择
本章小结
- 代码签名是生产发布的必要条件:macOS 未签名应用在 12+ 版本无法打开,Windows 未签名触发 SmartScreen 警告;开发阶段可忽略,发布前必须完成。
- macOS 需要"签名+公证"两步:签名(Keychain 证书)证明来源,公证(Apple 服务器扫描)证明无恶意;使用 App Store Connect API Key 替代 Apple ID 密码更安全。
- Windows EV vs OV 证书:EV 需要硬件令牌但立即获得 SmartScreen 信任;OV 价格低但需积累信任分数,发布初期仍有警告;根据用户量和预算选择。
- GitHub Actions 是最便捷的 CI 发布方案:
tauri-apps/tauri-action自动处理构建、签名、公证、上传;Swatinem/rust-cache 大幅缩短构建时间。 - Secrets 安全管理:证书 base64 编码存 Secrets;限制 workflow 只在 tag/release 分支触发;对生产环境使用 GitHub Environment 保护规则。
- Linux 包格式选择:AppImage 通用性最好;.deb 适合 Ubuntu 用户;企业环境提供 .rpm;根据用户群选择发布格式,或同时提供多种格式。