内容提要
文章介绍了在GitHub Actions中使用Xcode云签名发布Safari扩展时遇到的两个陷阱:一是CI runner每次新建证书导致证书数量超限,需手动导入.p12证书;二是App Store Connect API Key需Admin角色,否则报错。解决方案是预先配置证书和密钥,并清理孤儿证书。
延伸解读
无状态 CI 与苹果签名工具链的冲突
文章指出,两个陷阱的根源在于 GitHub Actions 的 runner 是无状态的,每次构建都会创建全新的 keychain,而苹果的签名工具链假设开发者使用长期存在的开发机。这种假设的错位导致云签名在 CI 环境中行为异常:它会在证书缺失时自动创建新证书,但私钥随 runner 销毁而丢失,最终积累大量孤儿证书并触发数量上限。理解这一根本原因,有助于开发者在使用云签名时提前采取措施,避免类似问题。
证书数量上限的隐蔽性
证书数量上限问题极具隐蔽性:在达到上限之前,每次构建都成功,开发者难以察觉异常。一旦达到上限,构建会永久失败,且报错信息含糊。文章建议通过手动创建证书并导入 CI 环境来避免自动创建,同时清理历史孤儿证书。这提醒开发者,在 CI 中依赖云签名自动管理证书存在风险,应主动管理证书生命周期。
API Key 角色权限的严格性
App Store Connect API Key 的角色权限在创建时固定,且云签名要求 Admin 角色,而 Developer 或 App Manager 角色会在签名阶段报出模糊的权限错误。文章强调,Admin 角色的 .p8 文件是整套流程中的真正机密,需妥善保管。这提示开发者,在配置 CI 时需仔细核对 API Key 的角色,并重视密钥的安全管理。
Q&A
在GitHub Actions中使用Xcode云签名发布Safari扩展时,遇到证书数量超限的错误是什么原因?
原因是GitHub Actions的runner每次启动都是全新的keychain,云签名在找不到签名身份时会自动为你的Apple Developer账号新建一张Distribution证书,但私钥随runner销毁而丢失,导致每次构建都消耗一张证书,最终达到苹果的证书数量上限。
如何解决GitHub Actions中云签名导致的证书数量超限问题?
手动创建一张Apple Distribution证书,导出为带密码的.p12文件,将证书和密码存入仓库secrets,并在CI job开始时导入keychain。这样云签名会复用已有的签名身份,不再新建证书。
在GitHub Actions中导入.p12证书的步骤是什么?
在CI job中,先解码base64的证书文件,然后创建并解锁keychain,使用security import命令导入.p12证书,并设置key partition list。具体命令包括:echo "$APPLE_CERTIFICATE_BASE64" | base64 --decode > certificate.p12,然后创建keychain、默认keychain、解锁,导入证书,最后设置key partition list。
为什么在GitHub Actions中云签名会报“Cloud signing permission error”?
因为App Store Connect API Key的角色权限不足。云签名要求API Key必须具有Admin角色,而Developer或App Manager角色的key虽然能通过身份认证,但在云签名时会出现权限错误。
如何修复GitHub Actions中的“Cloud signing permission error”?
需要重新生成一个具有Admin角色的App Store Connect API Key,因为角色在创建时固定,无法修改。在App Store Connect的Users and Access -> Integrations -> App Store Connect API中生成新的Admin key,并下载.p8文件。
在GitHub Actions中使用云签名时,哪些信息是真正的机密?
真正的机密是.p8文件和.p12文件,而issuer id、key id、team id等不是机密。
为什么GitHub Actions中的云签名会失败得又晚又含糊?
因为苹果的签名工具链假设使用长期存在的开发机,而无状态的CI runner打破了这一假设,导致错误在构建后期才出现,且报错信息不明确。