Apple notarization CI 失败怎么排查?2026 修复指南

本文帮助负责 macOS 发布的工程师和企业 IT 团队判断 CI 公证失败发生在哪一阶段。按状态、签名、最终制品、票据装订与交付验收逐类排查,避免无依据地重签或重跑整条流水线。

Apple 官方文档列出 4 类可提交公证的制品:macOS 应用、非应用程序包、UDIF 磁盘映像和扁平安装包;这意味着 CI 报错时,不能只看“上传成功”,还要确认实际提交的制品类型、处理状态和最终交付文件。结论:先查提交状态与 Apple 公证日志,再按签名与权限、制品结构、网络提交或票据装订分别修复;不要一看到失败就重签或重跑整条流水线。(Apple 公证流程与可提交制品说明)

✅ 适合:负责 macOS 应用发布、Developer ID 签名、公证步骤或远程 Mac CI 节点验收的团队,尤其适合需要把排障记录纳入发布审计的 IT 与平台工程人员。
❌ 不适合:只在 App Store 分发、并非在处理 Developer ID 公证的团队;App Store 审核与公证不是同一流程。

00Apple notarization CI 失败:先判定失败阶段

在 Mac CI 排障中,第一步不是换证书,而是明确失败发生在哪个环节。把流水线输出拆成“签名完成、提交上传、Apple 处理、状态接受、票据装订、最终验证”几段,记录具体失败命令、退出码和该阶段产生的提交 ID。

Apple 的公证服务会检查 Developer ID 签名软件并返回处理结果;上传请求获得提交标识后,还需要查询状态,并在处理完成后检查对应日志。公证也不是 App Review:流水线应以本次提交状态和制品验证结果为依据,而不是把“上传命令返回成功”当作发布准入。

建议先收集这些证据:

  • [ ] 保留 notarytool submit 的完整输出,确认是否生成提交 ID。
  • [ ] 用该 ID 查询请求状态;状态未完成时不要把“日志暂不可用”解释成制品通过。
  • [ ] 处理完成后下载公证日志,保留 JSON 原件、文件名和构建版本关联。
  • [ ] 核实提交的文件确实是本次准备分发的导出制品,而非中间归档或旧构建产物。
  • [ ] 标记流水线失败的阶段,避免把签名、认证、Apple 服务处理和本地验证归成一个“公证失败”。

Apple 提供 notarytool 的提交、状态查询和日志工作流;自定义流水线也可参照 Notary API 的提交状态与日志说明核对对应请求。

01签名身份与提交凭证:分开核查

“签名证书错误”和“提交认证失败”是两个不同故障域。前者影响待公证软件的签名,后者影响 CI 是否能向公证服务提交请求;某个服务账号或 Keychain 权限错误,并不能直接证明应用二进制签错,也不能证明 Mac 节点故障。

按日志及失败命令分流:

  • 日志指出签名无效或签名身份不受支持:检查最终交付文件及嵌套可执行文件,而非只检查构建中间产物。Apple 要求使用适用于目标类型的 Developer ID 签名身份;例如,应用程序与扁平安装包对应的签名身份并不相同。核对签名验证输出、证书链和签名后是否又修改过 bundle。
  • 提交命令在上传前或认证环节失败:检查流水线实际调用的 notarytool、凭证配置是否匹配当前团队,以及 CI 服务账号对所需 Keychain 项目的访问是否成功。不要将认证凭证与给应用签名的身份混为一谈;Apple 的自定义工作流文档说明了凭证配置和 Keychain 引用方式。
  • 日志指出 Hardened Runtime 或 entitlement 问题:对照最终签名的程序逐项检查。Apple 的要求包括启用 Hardened Runtime;自定义构建还应检查 com.apple.security.get-task-allow,以及 entitlement 文件的编码与内容。不要为消除报错而盲目增加宽泛权限。

Apple 的代码签名说明解释了签名用于验证代码及检测改动;它和公证提交凭证承担不同职责。按错误信息核实证书类型、签名有效性和权限配置,比直接轮换证书更容易保留根因证据。

02制品结构与日志:只对最终待分发文件下结论

公证检查针对实际提交的文件。因此,CI 即使验证过归档阶段的应用,如果随后又改动签名内容、重新打包,或者提交了不同的容器,之前的检查结果也不能代替对最终制品的核验。Apple 文档说明,公证日志会列出问题消息、相关路径和严重级别;即使状态已接受,也建议查看日志中的警告。可参照 Apple 关于常见公证问题的说明核对具体报错,不要把所有失败都归为证书问题。

观察到的现象 优先检查 修复判断
日志指出二进制签名无效 问题路径对应的应用、工具、框架或嵌套可执行文件 若最终制品签名不完整或签名后有改动,修复构建与签名后再提交
日志指出 entitlement 或 Hardened Runtime 最终发布目标的签名配置和实际 entitlement 若配置不符合公证要求,修复目标配置;不要仅修改 CI 节点
提交状态未完成,日志尚不可用 提交 ID、状态响应、上传阶段及流水线上下文 先确认既有请求是否仍在处理中;不能用缺少日志推断公证通过
公证已接受,但装订或交付验证失败 文件格式、装订对象与最终重新打包的制品 按分发格式处理票据,并验证最终交付文件

如需确认容器封装或最终发布对象,可对照 Apple 的 Mac 软件打包与分发说明。对于 .app、ZIP、磁盘映像或安装包,提交对象与可直接装订的对象并不总是相同;先确认格式,再选相应处理方式。

⚠️ 提醒:若日志中没有解释根因,不要立刻对同一文件反复提交。先保存提交 ID、状态响应、日志获取结果及文件摘要;同时检查上传是否中断、提交请求是否已创建,以及流水线是否丢失了后续查询所需的 ID。Apple 服务状态可用于判断是否存在已知服务异常,但不能代替对制品和请求状态的核验。

03公证状态已接受:票据装订与最终验证分开验收

公证接受、stapling 和 Gatekeeper 验证不是同一个动作。公证服务接受提交后会生成票据;装订是把票据附加到支持的分发制品,使其在无法联网时也能携带票据。最终验收则应针对实际要交付的文件,而不是只看公证服务的 Accepted 状态。

重点留意格式边界:Apple 说明 ZIP 可提交公证,但不能直接对 ZIP 文件执行 stapler;应按文档对其中适用的项目处理票据,再重新生成交付 ZIP。磁盘映像和扁平安装包可按对应方式装订。交付前,用 Apple 文档所述 stapler validate 验证适用制品,并保留命令输出;对于 ZIP,最终验收还应记录其内部项目和重打包文件对应关系。

按证据选择下一步

  • 若提交 ID 存在且状态尚未完成:保留请求与状态输出,等待状态更新或按 Apple 文档查询;不要因暂时没有日志就重签。
  • 若状态已拒绝,且日志指向签名、entitlement 或制品内容:修复被指出的最终制品,再重新签名或打包并提交新制品。
  • 若上传阶段失败,且没有已创建的有效提交:先修复认证、Keychain 或网络提交问题,再重新提交。
  • 若状态已接受,但票据装订失败:不要重新签名;先检查制品格式、目标文件是否可写及网络访问,再执行适用于该格式的装订与验证。
  • 若装订完成但最终文件验证失败:回查是否验证了正确的交付文件、是否在装订后又改动或重新打包,并重新验收实际发布对象。

04企业 FAQ:把状态证据留在发布记录中

如何定位日志里的签名错误?

先检查日志中的 path 和 message,确定是哪个二进制、框架或安装包触发问题,再对照同一构建产物的签名验证输出。Developer ID 类型不匹配、签名后修改 bundle、Hardened Runtime 缺失及 entitlement 配置,都可能是需要按日志核实的方向;不能仅凭 CI 节点报错断定某个方向成立。

日志还没生成时,应该反复提交吗?

不应只因日志暂不可用就重复提交。先确认请求是否已创建、提交 ID 是否保存,以及查询的是否为同一请求;同时区分“上传未完成”“请求仍处理中”和“处理结果已返回但日志获取异常”。不要推测固定处理时长;若状态证据仍不足,保留输出并进一步检查服务状态或提交上下文。

ZIP 发布前怎样证明票据验收完成?

记录公证状态与提交 ID,并保留对 ZIP 内适用项目执行装订后的命令输出。Apple 明确说明 ZIP 本身不能直接装订,因此不能把对 ZIP 执行装订命令的结果当作内部应用已带票据的证据。重新打包后,应确认交付文件就是本次验收的那一份,并按适用的验证方式保存结果。

05Mac CI 发布验收:建立可追溯的证据闭环

可以把下面的项目作为流水线验收记录;若某项失败,先按对应故障域处理,不要以节点“在线”或命令“上传成功”替代发布准入。

  • [ ] 签名:保存最终待分发文件的签名验证结果,记录签名身份与问题路径。
  • [ ] 提交:保留 notarytool 提交输出、提交 ID 和提交文件名称。
  • [ ] 处理:记录请求状态与公证日志;如果日志暂不可用,明确标记请求尚未完成核实。
  • [ ] 装订:记录采用的分发格式、装订对象及命令结果。
  • [ ] 最终文件:保存对实际交付制品的验证输出,并确认它与提交、装订的制品一致。
  • [ ] 凭证使用:说明 CI 服务账号如何访问凭证与 Keychain 项目;不要把密钥或密码写入可公开读取的构建日志。

如果失败只出现在提交认证或 Keychain 访问阶段,再检查 CI 服务账号权限、Keychain 解锁与访问控制;如果上传或票据下载失败,再核对出站网络是否允许工作流依赖的服务连接。Apple 的自定义公证工作流文档列出 notarytool 与 stapler 所需的网络访问说明,适合用于出口策略核查。若请求已提交但长时间没有可解释的状态或日志,应先保存证据并查看 Apple Developer 系统状态,不要把服务端处理异常误判成证书问题。

当根因落在临时构建环境、CI 账号或节点配置,且团队需要复现远程签名、公证与最终文件验收时,租用真实 Mac 可以作为自购设备之外的短期验证选择;它不能替代凭证治理,也不能让未经验证的制品自动获得发布准入。NUKCLOUD 提供按周、月或季度使用远程 Mac 的方式,可通过 VNC、SSH 或网页控制台访问;可先从NUKCLOUD 远程 Mac 服务信息了解方案,再按需要查看NUKCLOUD 套餐与下单入口。若团队已有稳定、长期满载且必须接入专用物理设备的流水线,自购节点可能更合适;若只是为排障、发布试运行或短期扩容准备 macOS 环境,则应以真实流水线是否完成“签名—提交—状态—装订—最终验证”闭环作为选择依据。

FAQ常见问题

notarytool 显示上传成功,但公证状态不是 Accepted,先查什么?
先保留本次提交 ID,再通过 notarytool 查询该请求的状态;处理已经完成时,使用同一提交 ID 获取 JSON 公证日志。上传成功只证明文件已提交,不能证明 Apple 已完成处理或接受制品。若状态仍在处理中、日志暂不可用,不要据此重签;先确认请求上下文仍在,并查看 Apple 服务状态。
Apple notarization CI 日志里哪些内容更可能指向签名问题?
重点看日志中的问题路径和具体错误消息,例如二进制签名无效、没有有效 Developer ID 身份、缺少 Hardened Runtime 或含有不适合发布的 get-task-allow entitlement。再对照最终导出的应用及嵌套可执行文件检查签名;若错误落在安装包,则另行核对安装包签名身份。不要仅凭 CI 节点报错就认定证书过期或节点损坏。
公证状态已接受,ZIP 发布前还要 stapler 吗?
Accepted 表示公证服务已接受提交,不等于本地交付文件已经完成票据装订和验收。ZIP 本身不能直接 stapler;应按 Apple 文档对 ZIP 内可装订的项目处理,再重新打包,并针对最终发布的 ZIP 或其内部制品执行适用验证。还应保留 stapler 与最终验证的命令输出,避免把提交状态当成交付证明。
公证失败后该重签、重新上传,还是只修复打包?
以公证日志和提交阶段决定:若最终文件签名无效、entitlements 错误或签名后又改动了 bundle,应修复构建或签名,再针对新制品提交;若日志指向容器格式或损坏,则修复制品封装后重新提交。若只是上传或状态查询上下文丢失,先找回既有提交 ID 并确认处理结果,不要盲目新建请求。