小玩具最近 Vibe Coding 上头,把之前买的Mac mini m4 (上车上的早,没想到成理财产品了),又翻出来玩玩。
但是升级到 MacOS 26 后发现,如果不签名。进行 App 分发举步维艰。于是就有了本文。
提示:关于开发者申请部分,请参考 Apple 官方文档。Mac OS 的应用分发 99 档即可。
1. 前期准备
- 一个开发者账号
- 代码签名:使用 Developer ID Application 证书及其私钥,通常保存为 P12;
- Apple 公证:使用 App Store Connect API Key,包含 P8、Key ID 和 Issuer ID。
关于 p12 证书是否导入钥匙串:
| 场景 | Tauri | Electron(electron-builder) |
|---|---|---|
| 本地 Mac | 建议把 P12 导入登录钥匙串 | 建议把 P12 导入登录钥匙串 |
| 干净 CI | 通常由 CI 脚本导入临时钥匙串 | 可设置 CSC_LINK,由 electron-builder 处理 |
| P12 已在钥匙串 | 设置签名 identity | 可自动发现,CSC_NAME 可选 |
P8 不需要导入代码签名钥匙串,只需以文件形式提供给公证工具。
warning:
在同时对 Tauri 和 Electron,进行签名和公正时,请注意环境变量问题,尤其是
在同时对 Tauri 和 Electron,进行签名和公正时,请注意环境变量问题,尤其是
APPLE_API_KEY 的含义完全不同。Tauri: APPLE_API_KEY = Key ID
Electron: APPLE_API_KEY = P8 文件路径
Tauri
先把 P12 导入登录钥匙串
先把 P12 导入登录钥匙串,我的证书中。中途会要求输入 P12 证书密码。
添加证书到钥匙串然后检查签名身份
security find-identity -v -p codesigning配置环境变量
p8 证书需要配置权限 600
配置环境变量如下
# 签名
export APPLE_SIGNING_IDENTITY="Developer ID Application: Your Name (ABCDE12345)"
# 公正
# Tauri 中 APPLE_API_KEY 表示 Key ID。
export APPLE_API_KEY="KEYID12345"
export APPLE_API_ISSUER="00000000-0000-0000-0000-000000000000"
export APPLE_API_KEY_PATH="$HOME/.private_keys/AuthKey_KEYID12345.p8"
配置环境变量也可以把签名身份写入 tauri.conf.json:
{
"bundle": {
"macOS": {
"signingIdentity": "Developer ID Application: Your Name (ABCDE12345)"
}
}
}构建和验证
然后执行 pnpm tauri build 进行构建就可以了。
构建使用命令验证签名和公正结果
# 验证代码签名
codesign -v --verbose <需要验证的APP>
# 验证公证票据
xcrun stapler validate <需要验证的APP>
签名和公正成功到此部分,Tauri部分就搞定了~
Electron
Electron 和 Tauri 不同之处在于,Electron 不强制要求 p12 证书必须放到钥匙串中。只需要指定证书位置和证书密码就行。
配置环境变量
签名环境变量:
# 导入到钥匙串,指定证书名
export CSC_NAME="Developer ID Application: Your Name (ABCDE12345)"
# 没有导入钥匙串
export CSC_LINK="<P12 证书路径 / P12 证书URL / P12 证书 Base64内容>"
export CSC_KEY_PASSWORD="<P12 证书密码>"公证环境变量:
p8 证书需要配置权限 600
# APPLE_API_KEY 表示 P8 文件路径,且和p8证书ID对应
export APPLE_API_KEY="$HOME/.private_keys/AuthKey_KEYID12345.p8"
export APPLE_API_KEY_ID="KEYID12345"
export APPLE_API_ISSUER="00000000-0000-0000-0000-000000000000"electron-builder 配置
package.json:
{
"build": {
"forceCodeSigning": true,
"mac": {
"target": ["dmg", "zip"],
"hardenedRuntime": true,
"notarize": true,
"entitlements": "build/entitlements.mac.plist",
"entitlementsInherit": "build/entitlements.mac.inherit.plist"
}
}
}
### 构建&验证
构建 Electron App
pnpm exec electron-builder --mac dmg zip
使用命令验证签名和公正结果
验证代码签名
codesign -v --verbose <需要验证的APP>
验证公证票据
xcrun stapler validate <需要验证的APP>