GitHub Actions构建带Sparkle的macOS应用更新签名验证失败求助
问题分析与解决方案
问题背景
开发GitHub Action发布集成Sparkle自动更新的macOS应用,流程如下:
- 对master分支PR评论触发工作流
- 归档导出.app文件并压缩
- 从GitHub Secrets导入Sparkle私钥
- 用
generate_appcast更新appcast.xml并部署到GitHub Pages - PR合并后Pages重建,应用能检测到更新,但安装时提示:
The update is improperly signed and could not be validated. Please try again later or contact the app developer
移除应用内的SUPublicEDKey并手动创建不含sparkle:edSignature的appcast.xml后,更新可正常安装。
相关验证输出:
> codesign --deep -vvv --verify testSparkleRelease.app ... testSparkleRelease.app: valid on disk testSparkleRelease.app: satisfies its Designated Requirement > spctl -a -t exec -vv testSparkleRelease.app testSparkleRelease.app: rejected origin=Apple Development: Alexander Perathoner (K3WW8XS***)
尝试使用Apple Distribution证书导出归档,问题依旧,签名流程遵循GitHub官方指南。
核心原因
问题出在Sparkle的ED签名验证不匹配,以及苹果代码签名的公证/信任问题:
- Sparkle的私钥与应用内嵌的公钥不配对,导致
generate_appcast生成的edSignature无法被应用验证通过 - spctl拒绝说明应用未经过苹果公证,即使代码签名有效,系统会阻止运行(但移除ED签名后能安装,说明用户可能手动允许了未公证应用)
解决方案
1. 确认Sparkle密钥配对
- 确保GitHub Secrets中存储的Sparkle私钥,与应用
Info.plist或bundle中SUPublicEDKey的公钥是同一对(通过Sparkle官方的generate_keys工具生成) - 检查私钥导入到Runner时的格式:导出私钥时要完整保留PEM格式的换行,导入到Secrets时不要添加多余空格,工作流中写入文件时要确保格式正确,比如:
- name: Import Sparkle Private Key run: | echo "${{ secrets.SPARKLE_PRIVATE_KEY }}" > sparkle_private.pem chmod 600 sparkle_private.pem
2. 修复苹果代码签名与公证
- 确认归档导出时使用的是Apple Distribution证书,而非Apple Development证书(从spctl输出看当前用的是Development证书,即使选择了Distribution,可能Runner上的证书配置有误)
- 在GitHub Action中导出归档时,添加公证步骤:使用
xcrun notarytool提交应用到苹果公证,完成后再导出可分发的.app文件,确保spctl验证通过:xcrun notarytool submit testSparkleRelease.zip --keychain-profile "Notary Profile" --wait xcrun stapler staple testSparkleRelease.app - 验证公证结果:
正常输出应为spctl -a -t exec -vv testSparkleRelease.appaccepted而非rejected
3. 检查generate_appcast的使用
- 确保调用
generate_appcast时正确指定私钥参数,比如:generate_appcast --private-key sparkle_private.pem ./path/to/appcast/dir - 生成appcast.xml后,检查
sparkle:edSignature字段是否存在,且与应用公钥匹配(可通过Sparkle的验证工具检查)
4. 额外排查点
- 检查应用的
Info.plist中是否正确配置了SUPublicEDKey,没有多余空格或换行 - 确认压缩.app文件时使用的是Sparkle推荐的
zip命令(避免压缩工具破坏签名):zip -r testSparkleRelease.zip testSparkleRelease.app
内容的提问来源于stack exchange,提问作者AlexPera
相关产品推荐
相关产品推荐

