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

Github Actions中执行bundle exec fastlane beta编译Flutter iOS项目时Archive失败问题排查

解决Github Actions中Flutter iOS项目bundle exec fastlane beta编译失败(Exit status 65)的问题

首先啊,Exit status 65是Xcode构建脚本执行失败的典型报错,结合你本地能跑通但CI环境直接挂掉的情况,大概率是CI环境的依赖、权限或者证书配置和本地不一致导致的。下面是针对你的情况的排查和修复步骤,你可以一步步试:

一、调整CocoaPods和依赖安装的顺序与权限

看你的Actions脚本,在ios目录下先装了CocoaPods又跑了bundle install,但这里可能有两个坑:一是CI环境下装gem如果不加--user-install很容易碰到权限报错;二是直接用pod install可能没用到Gemfile里指定的版本,导致依赖不一致。

我建议你修改这两步:

  1. 把Gem安装命令改成这样,避免权限问题:
    gem install cocoapods -v 1.10.1 --user-install
    gem install fastlane -v 2.177.0 --user-install
    
  2. 把Install tools里的pod install换成bundle exec pod install,确保用的是bundle管理的版本:
    - name: Install tools
      run: |
        flutter precache
        flutter pub get
        cd ./ios
        bundle exec pod install
    

二、给Flutter构建脚本添加执行权限

那个失败的Script-9740EEB61CF901F6004384FC.sh是Flutter自动生成的构建脚本,CI环境下有时候会丢失执行权限,导致跑不起来。你可以在Actions里加一步专门处理:
在Install tools步骤之后,新增:

- name: Fix Flutter build script permissions
  run: |
    cd ./ios
    chmod +x "$(find . -name "flutter_build_script.sh" -o -name "Script-*.sh")"

这行命令会自动找到所有Flutter相关的脚本并赋予执行权限,比手动写路径靠谱多了。

三、优化Keychain和证书配置

你的fastlane里已经创建了keychain,但CI环境下有时候解锁不彻底,导致证书没法被Xcode访问到。我建议你在create_keychain之后加一行解锁命令:

unlock_keychain(
  name: ENV['MATCH_KEYCHAIN_NAME'],
  password: ENV["MATCH_KEYCHAIN_PASSWORD"]
)

另外,在match的配置里加上force_for_new_devices: true,确保新的CI机器能正确导入证书:

match(
  app_identifier: ENV["APP_IDENTIFIER"],
  git_url: ENV["GIT_URL"],
  type: "adhoc",
  readonly: is_ci,
  keychain_name: ENV['MATCH_KEYCHAIN_NAME'],
  keychain_password: ENV["MATCH_KEYCHAIN_PASSWORD"],
  force_for_new_devices: true
)

四、调整Xcode构建参数,提升CI稳定性

在build_app里加几个适配CI环境的参数:

build_app(
  workspace: "Runner.xcworkspace",
  scheme: "Runner",
  export_method: "ad-hoc",
  clean: true, # 先清缓存再构建,避免旧文件干扰
  use_legacy_build_api: false, # 针对Xcode12+的适配
  export_options: {
    signingStyle: "manual",
    provisioningProfiles: {
      ENV["APP_IDENTIFIER"] => "你的AdHoc描述文件名" # 这里可以填match生成的描述文件名,或者直接指定
    }
  }
)

另外,你还可以给Flutter和CocoaPods加缓存,既省时间又避免重复安装的问题:

- name: Cache Flutter & CocoaPods dependencies
  uses: actions/cache@v2
  with:
    path: |
      ~/.pub-cache
      ios/Pods
    key: ${{ runner.os }}-flutter-${{ hashFiles('pubspec.lock') }}-cocoapods-${{ hashFiles('ios/Podfile.lock') }}

五、移除多余的环境变量

看你的Actions里传递了FLUTTER_ROOT,但subosito/flutter-action这个action已经帮你设置好正确的FLUTTER_ROOT了,手动传反而可能导致冲突,建议把这一行删掉。

最后,如果还是不行,一定要看详细日志

Github Actions的构建日志里,那个失败的PhaseScriptExecution步骤下面有详细的报错信息,比如找不到Flutter命令、证书无效、某个依赖缺失之类的,这才是定位问题最关键的线索,别只看Exit status 65这个表面报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 10:32:36