GitHub Actions 为何在 Pods 中查找 pubspec.yaml?
结论
Pods 不是 Flutter 项目的根目录,里面也不该有 pubspec.yaml。日志中的路径说明,构建进入 Xcode/CocoaPods 的脚本阶段后,某个 Dart 进程误把当前工作目录当成了 package 根目录。
从现有日志判断,这个问题与迁移到 rive_native 后启用 native assets/build hooks 有关。眼下更直接的故障是 CI 中的 Dart 环境不完整:
ProcessException: No such file or directory
Command: dart pub workspace list
rive_native:setup 由 Flutter fork 内的 Dart 启动,之后又通过命令名 dart 拉起子进程。CI 的 PATH 很可能找不到这个 dart。本地环境通常已经将 Dart 或 Flutter 加入 PATH,所以运行相同脚本时不会失败。
如果系统能找到 dart,只是当前版本不支持 pub workspace,通常会报“未知命令或子命令”,而非 ProcessException: No such file or directory。排查时应先修复 PATH,再确认 Flutter fork 自带的 Dart 版本是否兼容。
为什么错误路径会是 macos/Pods
flutter build macos 最终会调用 Xcode。Xcode 执行 CocoaPods target 或 Run Script build phase 时,当前工作目录可能是:
<main-package>/macos/Pods
升级后的 rive_native 会参与 native assets/build hooks。如果 hook 或 setup 脚本没有正确取得 package 根目录,就可能退回 Directory.current,继而从 Pods 目录查找 pubspec.yaml。
这并不表示顶层 build.sh 执行过 cd macos/Pods。顶层脚本和 Xcode 子进程可以使用不同的工作目录。
日志中还有这些警告:
Run script build phase 'Run Script' will be run during every build...
no rule to process file ... PrivacyInfo.xcprivacy
它们通常不是此次构建失败的直接原因。构建退出是因为 build hooks 阶段找不到 package,随后 PhaseScriptExecution 返回了非零状态。
先确认 CI 实际使用了哪个 Dart
只检查 ./flutterw dart --version 还不够。这条命令只能证明 wrapper 知道内置 Dart 的位置,不能证明 rive_native 启动的子进程也能通过 PATH 找到它。
运行 setup 前加入以下检查:
set -euxo pipefail
pwd
test -f pubspec.yaml
echo "PATH=$PATH"
command -v dart || true
command -v flutter || true
type -a dart || true
type -a flutter || true
./flutterw --version
./flutterw doctor -v
./flutterw dart --version
接着找到 Flutter fork 中实际使用的 Dart。假设 fork 位于仓库根目录的 .flutter:
FLUTTER_ROOT="$(cd ../../.flutter && pwd)"
DART_SDK_BIN="$FLUTTER_ROOT/bin/cache/dart-sdk/bin"
test -x "$DART_SDK_BIN/dart"
"$DART_SDK_BIN/dart" --version
export FLUTTER_ROOT
export PATH="$DART_SDK_BIN:$FLUTTER_ROOT/bin:$PATH"
command -v dart
dart --version
dart pub workspace list --help
这里的 ../../.flutter 只是根据问题中的目录关系举例,需要替换为 CI 中 Flutter fork 的实际路径。
如果最后一条命令能显示帮助信息,说明这个 Dart 支持 pub workspace list。如果提示不存在 workspace 子命令,说明 Flutter fork 内置的 Dart 版本太旧,或者 fork 缺少相关改动。
GitHub Actions 中要同时处理当前步骤和后续步骤
GitHub Actions 的每个 run 步骤都会启动新的 shell。在某个步骤中执行 export PATH=...,不会自动影响后续步骤,因此还要写入 $GITHUB_PATH:
- name: Configure Flutter fork
working-directory: packages/<main-package>
shell: bash
run: |
set -euxo pipefail
FLUTTER_ROOT="$(cd ../../.flutter && pwd)"
DART_SDK_BIN="$FLUTTER_ROOT/bin/cache/dart-sdk/bin"
test -x "$DART_SDK_BIN/dart"
export FLUTTER_ROOT
export PATH="$DART_SDK_BIN:$FLUTTER_ROOT/bin:$PATH"
echo "$DART_SDK_BIN" >> "$GITHUB_PATH"
echo "$FLUTTER_ROOT/bin" >> "$GITHUB_PATH"
command -v dart
dart --version
dart pub workspace list --help
写入 $GITHUB_PATH 的目录要到下一个 workflow step 才会生效,所以当前步骤仍需执行 export PATH=...。
不建议在 runner 上另装一套无关的系统 Dart 来绕过报错。rive_native、Flutter 和 native assets 最好共用 Flutter fork 自带的 Dart SDK,否则还可能引入版本不一致的问题。
正确执行 macOS setup
第一次尝试执行的是:
dart run rive_native:setup --verbose --platform ios,android
这条命令不会配置 macOS。在 monorepo 根目录运行时,它也未必能找到 main package。
应进入包含目标 pubspec.yaml 的目录,并确保直接调用的 dart 指向 fork 内置 SDK:
set -euxo pipefail
cd packages/<main-package>
test -f pubspec.yaml
FLUTTER_ROOT="$(cd ../../.flutter && pwd)"
export FLUTTER_ROOT
export PATH="$FLUTTER_ROOT/bin/cache/dart-sdk/bin:$FLUTTER_ROOT/bin:$PATH"
command -v dart
dart --version
dart pub workspace list --help
./flutterw pub get
dart run rive_native:setup --verbose --clean --platform macos
./flutterw build macos \
--no-codesign \
--target "$dart_main" \
--dart-define="FLAVOR=$type" \
--build-number="$BUILD_NUMBER" \
--build-name="$VERSION"
是否需要手动执行 rive_native:setup,要看项目锁定的 rive_native 版本及其自动 hook 行为。现有日志已经表明 rive_native:setup 无法在该环境中完成,因此可以先把 setup 跑通,再继续排查。
如果 Dart 不支持 pub workspace
先分别记录 CI 和本地的完整版本信息:
./flutterw --version
./flutterw dart --version
dart --version
dart pub workspace list --help
然后逐项比较:
- 本地和 CI 检出的 Flutter fork commit;
pubspec.lock中锁定的rive与rive_native版本;rive_native自身pubspec.yaml中的 Dart SDK 约束;- Flutter fork 内置 Dart 是否包含
pub workspace; - CI 是否恢复了旧的 Flutter、Pub Cache、
.dart_tool或 Pods 缓存。
现有信息不足以确定 rive_native 0.1.2 要求的精确最低 Dart 版本,不宜凭猜测写死版本号。应以 CI 中这两条命令的实际结果为准:
dart --version
dart pub workspace list --help
如果当前 Dart 确实不支持该命令,有两个可靠的处理方向:
- 更新 Flutter fork,使其包含符合当前
rive_native要求的 Dart SDK 和 native-assets 实现; - 将
rive/rive_native固定到与现有 Flutter fork 兼容的版本。
不要为了消除报错,随意在根 pubspec.yaml 中加入 workspace:。仓库是否采用 Dart pub workspace,应根据现有项目结构和所用 Dart 版本决定。
清理 CI 中的旧状态
从日志路径看,CI 可能使用了 self-hosted runner。此类 runner 会保留上一次构建生成的 Pods、.dart_tool 和缓存,容易出现“本地正常、CI 异常”的情况。
确认版本和 PATH 后,可以在 main package 中执行一次干净构建:
./flutterw clean
rm -rf .dart_tool build macos/Pods macos/Flutter/ephemeral
./flutterw pub get
cd macos
pod install
cd ..
dart run rive_native:setup --verbose --clean --platform macos
./flutterw build macos --no-codesign
是否删除 macos/Podfile.lock 应遵循项目的依赖管理策略。通常不应在 CI 中无条件删除它。
仍然从 Pods 查找时检查什么
如果 dart 已正确加入 PATH,dart pub workspace list 也能运行,但构建仍从 Pods 目录查找 pubspec.yaml,接下来应检查 Flutter fork,不必继续调整 GitHub Actions 的工作目录:
./flutterw build macos -v 2>&1 | tee flutter-build.log
重点搜索以下内容:
grep -nE 'Running build hooks|pubspec.yaml|rive_native|PhaseScriptExecution|PWD|FLUTTER_ROOT' flutter-build.log
还需要比较该 fork 与其对应的官方 Flutter 版本,查看 native assets、hooks runner 和 macOS Flutter Assemble 脚本之间有哪些差异。问题是在迁移到 rive_native 后出现的,原因可能是此前没有 package 走过这条 native-assets 路径,直到这次才暴露出 fork 中较旧或不完整的实现。
根据现有证据,应先修复 CI 中 Dart 的 PATH。setup 脚本内部直接调用 dart,不会使用 ./flutterw 的定位方式。修复后,再根据 dart pub workspace list --help 的结果决定继续配置 macOS setup,还是升级 Flutter fork或回退 Rive 依赖。
备注:内容仅供参考。
