Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .github/workflows/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,13 +7,20 @@

| Secret | 用途 | 说明 |
|---|---|---|
| `MACOS_SIGNING_P12_BASE64` | 签名证书包 | **必须包含私钥!** `base64 < 含私钥的证书.p12` 的结果 |
| `MACOS_SIGNING_P12_BASE64` | 签名证书包(Application) | **必须包含私钥!** `base64 < 含私钥的证书.p12` 的结果 |
| `MACOS_SIGNING_P12_PASSWORD` | p12 导出密码 | 导出 p12 时设置的密码 |
| `MACOS_SIGNING_IDENTITY` | 签名身份名称(可选) | `.app` 签名用 `Developer ID Application: ... (TEAMID)`(electron-builder 从 p12 自动发现);pkg 签名自动检测 `Developer ID Installer` 身份,无需填此值 |
| `MACOS_INSTALLER_IDENTITY` | Installer 身份(可选,双 p12 方案) | `Developer ID Installer: ... (TEAMID)`,Sign pkg 优先用此值 |
| `MACOS_INSTALLER_P12_BASE64` | Installer p12(可选,双 p12 方案) | 含 Developer ID Installer 证书+私钥的 p12 的 base64;配置后 Import step 会额外导入它 |
| `MACOS_INSTALLER_P12_PASSWORD` | Installer p12 密码(可选,双 p12 方案) | 导出 Installer p12 时设置的密码 |
| `APPLE_ID` | Apple ID(公证) | notarytool 使用的 Apple ID 邮箱 |
| `MACOS_NOTARY_APP_PASSWORD` | App 专用密码 | Apple ID → 登录与安全 → App 专用密码 |
| `MACOS_NOTARY_TEAM_ID` | Team ID | 开发者账号 Team ID |

**两种方案**(rant 2026-08-06T15:26 起支持):
- **单 p12 方案**(默认):只配 `MACOS_SIGNING_*`,p12 内含双证书(Application + Installer),`security export -t identities` 导出
- **双 p12 方案**(宿主已采用):`MACOS_SIGNING_*` 含 Application,另配 `MACOS_INSTALLER_*` 含 Installer——CI Import step 分别导入两个 p12,Sign pkg 优先用 `MACOS_INSTALLER_IDENTITY`

## ⚠️ p12 必须包含两种证书(Application + Installer)

**`.app` 签名**需要 **Developer ID Application** 证书;**pkg 签名**(`productsign`)需要 **Developer ID Installer** 证书——两者是独立的证书类型,缺一不可:
Expand Down
40 changes: 31 additions & 9 deletions .github/workflows/build-release.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,6 +42,11 @@ jobs:
MACOS_SIGNING_P12_BASE64: ${{ secrets.MACOS_SIGNING_P12_BASE64 }}
MACOS_SIGNING_P12_PASSWORD: ${{ secrets.MACOS_SIGNING_P12_PASSWORD }}
MACOS_SIGNING_IDENTITY: ${{ secrets.MACOS_SIGNING_IDENTITY }}
# Installer 证书(rant 2026-08-06T15:26:双 p12 方案,宿主已配置 3 个新 Secret;
# 未配置时降级为单 p12 方案——Install 证书在 MACOS_SIGNING_P12_BASE64 内)
MACOS_INSTALLER_IDENTITY: ${{ secrets.MACOS_INSTALLER_IDENTITY }}
MACOS_INSTALLER_P12_BASE64: ${{ secrets.MACOS_INSTALLER_P12_BASE64 }}
MACOS_INSTALLER_P12_PASSWORD: ${{ secrets.MACOS_INSTALLER_P12_PASSWORD }}
# 公证(P2 后半,rant 2026-08-06T10:06:55):APPLE_ID 等 Secret 未配则跳过降级
APPLE_ID: ${{ secrets.APPLE_ID }}
MACOS_NOTARY_APP_PASSWORD: ${{ secrets.MACOS_NOTARY_APP_PASSWORD }}
Expand DownExpand Up@@ -80,20 +85,33 @@ jobs:
echo "::error::MACOS_SIGNING_P12_BASE64 未包含可签名私钥(security import 仅导入证书链)。请从 Keychain Access 导出含私钥的 p12(证书右键 → 导出 → 勾选\"包含私钥\"),重新 base64 后更新 GitHub Secret。import 输出:${IMPORT_OUTPUT}"
exit 1
fi
# 双 p12 方案(rant 2026-08-06T15:26):若配置了独立的 Installer p12
# Secret,则导入它(含 Developer ID Installer 证书+私钥),覆盖单 p12 方案。
# 未配置时降级为单 p12 方案(Installer 证书必须在 MACOS_SIGNING_P12_BASE64 内)。
if [ -n "${MACOS_INSTALLER_P12_BASE64:-}" ]; then
echo "==> 双 p12 方案:导入 Installer p12"
echo "$MACOS_INSTALLER_P12_BASE64" | base64 --decode > /tmp/installer.p12
INSTALLER_IMPORT="$(security import /tmp/installer.p12 -k /tmp/ci.keychain -P "$MACOS_INSTALLER_P12_PASSWORD" \
-T /usr/bin/codesign -T /usr/bin/productsign 2>&1)"
echo "$INSTALLER_IMPORT"
if [[ ! "$INSTALLER_IMPORT" =~ identit(y|ies)\ imported ]]; then
echo "::error::MACOS_INSTALLER_P12_BASE64 未包含可签名私钥(security import 仅导入证书链)。请重新导出含私钥的 Installer p12 后更新 GitHub Secret。import 输出:${INSTALLER_IMPORT}"
exit 1
fi
fi
# 双证书存在性校验(v0.2.7 第 7 次构建根因:p12 只有 Developer ID
# Application 证书——签 .app 成功,但 productsign 签 pkg 需要独立的
# Developer ID Installer 证书,缺失报 "An installer signing identity (not
# an application signing identity) is required" 的 cryptic 错误)。
# 对称地,若只导出 Installer 而漏掉 Application,则 electron-builder
# codesign .app 会找不到身份(跳过签名 → 公证失败)。因此两种证书
# 必须同时存在(developer.apple.com → Certificates 分别创建,导出 p12
# 时用 `security export -t identities` 一并导出全部身份)。
# find-certificate 不受 policy 限制。
# 支持两种方案(rant 2026-08-06T15:26):
# 单 p12 方案:MACOS_SIGNING_P12_BASE64 同时含 Application + Installer
# 双 p12 方案:MACOS_SIGNING_P12_BASE64 含 Application,MACOS_INSTALLER_P12_BASE64 含 Installer
# 两种证书必须同时存在。find-certificate 不受 policy 限制。
# ⚠️ 必须用输出判空而非退出码:实测 find-certificate 无匹配证书时
# 也返回 exit 0(正反两态验证,#455 教训)。
for CERT_NAME in "Developer ID Application" "Developer ID Installer"; do
if [ -z "$(security find-certificate -c "$CERT_NAME" -a /tmp/ci.keychain 2>/dev/null)" ]; then
echo "::error::MACOS_SIGNING_P12_BASE64 缺少 $CERT_NAME 证书(签名必需)。Developer ID Application 用于签 .app(electron-builder codesign),Developer ID Installer 用于签 pkg(productsign),两张证书缺一不可。请在 developer.apple.com → Certificates 分别创建(或确认已创建),用 \`security export -t identities\` 连同私钥一并导出 p12 后更新 GitHub Secret。"
echo "::error::keychain 缺少 $CERT_NAME 证书(签名必需)。Developer ID Application 用于签 .app(electron-builder codesign),Developer ID Installer 用于签 pkg(productsign),两张证书缺一不可。单 p12 方案:用 \`security export -t identities\` 连同私钥一并导出;双 p12 方案:检查 MACOS_INSTALLER_P12_BASE64 是否正确配置。"
exit 1
fi
done
Expand DownExpand Up@@ -166,16 +184,20 @@ jobs:
# ⚠️ productsign 需要 Developer ID Installer 身份(非 Application 身份)——
# 实测 #462:MACOS_SIGNING_IDENTITY 配 Application 身份报
# "An installer signing identity (not an application signing identity) is required"。
# 从 p12 自动检测 Installer 身份,缺失则明确报错指引宿主补证书。
# 优先用宿主配置的 MACOS_INSTALLER_IDENTITY(rant 2026-08-06T15:26 双 p12 方案),
# 未配置则从 keychain 自动检测 Installer 身份(单 p12 方案,#462)。
- name: Sign pkg (macOS only)
if: runner.os == 'macOS' && env.MACOS_SIGNING_P12_BASE64 != ''
shell: bash
run: |
PKG="$(find dist/artifacts -maxdepth 1 -name 'EMRG-*-macos-*.pkg' | head -1)"
if [ -z "$PKG" ]; then echo "no pkg found, skipping"; exit 0; fi
INSTALLER_ID="$(security find-identity -v /tmp/ci.keychain | grep 'Developer ID Installer' | head -1 | sed -E 's/.*"([^"]+)".*/\1/')"
INSTALLER_ID="${MACOS_INSTALLER_IDENTITY:-}"
if [ -z "$INSTALLER_ID" ]; then
INSTALLER_ID="$(security find-identity -v /tmp/ci.keychain | grep 'Developer ID Installer' | head -1 | sed -E 's/.*"([^"]+)".*/\1/')"
fi
if [ -z "$INSTALLER_ID" ]; then
echo "::error::pkg 签名需要 Developer ID Installer 证书(productsign 不接受 Application 身份)。请在 Apple Developer 后台生成 Developer ID Installer 证书,下载导入钥匙串后随 p12 一并导出(security export -t identities 含全部证书+私钥),更新 MACOS_SIGNING_P12_BASE64。"
echo "::error::pkg 签名需要 Developer ID Installer 证书(productsign 不接受 Application 身份)。请配置 MACOS_INSTALLER_IDENTITY + MACOS_INSTALLER_P12_BASE64(双 p12 方案),或用 security export -t identities 导出含 Installer 的 p12 到 MACOS_SIGNING_P12_BASE64(单 p12 方案)。"
exit 1
fi
productsign --sign "$INSTALLER_ID" "$PKG" "${PKG}.signed"
Expand Down
Loading