diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 62df6b7c..e5d244d8 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -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** 证书——两者是独立的证书类型,缺一不可: diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 09847ec4..5fd11e7e 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -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 }} @@ -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 @@ -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"