You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitHub Actions上传macOS App Bundle为产物后下载无法执行

问题根因

问题和签名、公证流程无关,核心是actions/upload-artifact的默认打包逻辑破坏了.app bundle的结构完整性:

  • actions/upload-artifact@v3及更早版本默认开启符号链接跟随,会将.app包内的所有相对符号链接替换为指向的实体文件副本,同时不会完整保留Unix文件权限位、macOS文件系统扩展属性。Avalonia应用的.app bundle、以及codesign写入的签名元数据强依赖包内的目录结构、符号链接关系和扩展属性,一旦结构被破坏,codesign校验时就会判定嵌套组件签名丢失或无效。
  • upload-artifact内置的zip打包实现未适配macOS应用签名的存储规则:macOS的部分签名信息存储在文件扩展属性中,普通zip打包逻辑如果没有专门做兼容,解压后签名信息会直接丢失。
  • 本地流程正常是因为本地操作不会经过这套非原生的打包解压流程,签名结构始终完整;执行chmod添加可执行权限无效也符合预期,因为问题本质是bundle结构损坏,不是权限缺失。
可落地修复方案

按优先级尝试以下方案:

  1. 升级upload-artifact到v4及以上版本,关闭符号链接跟随配置,让动作尽可能保留文件原始结构
    配置参考:
    - name: 上传签名完成的App Bundle
      uses: actions/upload-artifact@v4
      with:
        name: signed-macos-app
        path: ./path/to/your/AppName.app
        follow-symlinks: false
        retention-days: 30
    
  2. 如果升级动作后问题仍然存在,直接绕开upload-artifact的内置打包逻辑:上传前先用macOS原生工具打包成完整保留签名结构的zip包,再上传这个zip作为产物
    在上传步骤前增加打包命令:
    # 使用macOS原生ditto打包,完整保留资源分支、符号链接、权限、扩展属性和签名信息
    ditto -c -k --sequesterRsrc --keepParent AppName.app AppName_signed_notarized.zip
    
    后续upload-artifact直接指定上传生成的AppName_signed_notarized.zip即可,下载后用系统默认解压工具打开,得到的.app签名、公证、钉装信息全部完整,可以正常启动。
  3. 避坑:不要将.app放到多层嵌套的子文件夹后再让upload-artifact扫描整个文件夹打包,直接将.app或预打包好的zip作为path参数传入,减少文件遍历过程中破坏结构的概率。
流程校验方法

在工作流的上传步骤前增加本地校验环节,先确认runner环境内构建签名完成的应用本身是正常的,避免误判问题环节:

# 校验代码签名完整性
codesign -vvv --deep --strict AppName.app
# 校验公证有效性
spctl -a -vvv AppName.app
# 校验钉装状态
xcrun stapler validate AppName.app

如果以上命令全部执行通过,下载解压后校验失败,就可以确定是上传打包环节的结构破坏问题,直接用ditto预打包的方案即可100%解决。

内容的提问来源于stack exchange,提问作者sergevm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 10:01:52