Mastra 仓库 GitHub Actions CI 失败修复实战:从 gh pr checks 到全量验证的系统化排查流程
【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra
本指南以 Mastra(现代 TypeScript AI 应用与 Agent 框架)仓库的.cursor/commands/gh-fix-ci.md命令为骨架,面向在本地或 Agent 环境中接到"当前分支关联 PR 的 CI 红了"这一任务时的完整应对流程:先用 GitHub CLI 定位 PR 与检查状态,再对失败进行深度分类分析,随后实施修复并用本地测试验证,最后推回远端确认全部检查通过。读完本文,你将掌握一套可复用的 CI 故障处置方法论,并了解 Mastra 仓库真实 CI 拓扑(Prebuild、Quality assurance、Changed Test Gate、E2E 等),从而能快速判断一次失败到底是 flaky、真 bug 还是环境问题。
预备知识:先理解 Mastra 仓库的 CI 全景
在动手修复之前,先弄清楚"失败的是什么检查"比盲目看日志更高效。从源码结构看,Mastra 是一个 pnpm + turbo + vitest 的大型 monorepo(根目录package.json、pnpm-workspace.yaml、turbo.json、vitest.config.ts都在仓库根部),其 CI 由.github/workflows/下数十个工作流文件组成。与日常 PR 最相关的几组是:
- prebuild.yml:PR 触发(
opened / synchronize / reopened,分支main、0.x),先由changesjob 判断是否涉及代码,再依次跑 Build、affected-tests 计算,并根据路由结果调用 test-suite、e2e-tests、mastracode-e2e、combined-stores-tests、workspace-tests、memory-test 等下游工作流; - lint.yml:名为 "Quality assurance",包含
pnpm lint、check-bundle(构建后校验产物是否被提交,见.github/scripts/check-clean-worktree.bash)、示例校验、AGENTS.md 校验、README 校验、peer 依赖校验(scripts/validate-peerdeps.mjs)与 package.json 校验等多个 job; - test-suite.yml:以
workflow_call方式被 prebuild 复用,把单测拆成 4 个 shard 并行,另含 affected 单测、按包分组的 E2E 与报告合并; - changed-test-gate.yml:一个很有特点的"突变门",它把 PR 新增/修改的测试文件恢复到 base 分支上运行,期望其失败,以证明测试确实覆盖了新代码。
这些工作流都通过 setup-pnpm-node 这个复合动作安装 Node.js 24.18.0 与 pnpm,并带有 pnpm store 损坏自愈逻辑。知道这些后,看到"哪个 job 红了"就能立刻联想到对应的职责范围。
第一步:定位 PR 并检查 CI 状态
命令文档给出的起点非常明确:先识别当前分支关联的 PR,再看它的检查状态。
gh pr status gh pr checks在非交互环境中(例如 Agent 执行),建议用GH_PAGER=cat避免进入分页器导致命令挂起——这与仓库中同主题的.github/prompts/gh-fix-ci.prompt.md的写法一致:
GH_PAGER=cat gh pr status GH_PAGER=cat gh pr checksgh pr status会列出当前分支关联的 PR(或提示当前分支没有关联 PR),并给出每个 PR 的合并状态、检查概览与 review 状态;gh pr checks会以清单形式列出该 PR 上的全部 CI 检查项及其结论(pass / fail / pending),是确定"到底挂了哪些 job"的最直接手段。
拿到失败项列表后,如果 PR 不在当前分支上,也可以用gh pr checks <PR_NUMBER>(仓库的.github/prompts/gh-bulk-issues.prompt.md中即有该用法)显式指定 PR 编号。
第二步:深度分析失败——错误消息、模式与根因分类
文档要求"think deeply about the failures",并给出了四个递进的分析动作。以 Mastra 仓库的实际 CI 为例,逐条展开:
1. 分析错误消息与失败测试输出
点击失败 job 展开日志,按错误类型归类。仓库中最常见的几类失败形态:
- 测试断言失败:vitest 输出会明确标出
FAIL的测试文件与断言位置。这类失败大多对应真实行为变化,是修复的主战场; - 类型检查失败:单测 job 同时运行
--project 'unit:*' --project 'typecheck:*'(见 test-suite.yml),类型错误与运行期失败混在同一报告里,需要在分析时先区分; - 构建失败:
pnpm turbo build失败往往源于依赖图内的编译错误或产物不完整; - 产物校验失败:
check-bundlejob 构建后执行check-clean-worktree.bash,如果生成了未提交的产物文件,CI 会直接失败——这类失败与测试逻辑无关,属于"忘记提交生成物"; - 依赖安装失败:pnpm store 缓存损坏在自托管 runner 上是已知风险,setup-pnpm-node 专门实现了自愈:检测到 SQLite 索引损坏(
database disk image is malformed)或内容哈希不匹配(ERR_PNPM_MODIFIED_DEPENDENCY)时只删除 store 索引、保留内容寻址文件,必要时在 install 时追加--force。看到这类报错可以判断为环境/缓存问题而非代码问题。
2. 识别跨失败的共同模式
不要逐个 job 孤立地看,而是横向扫描:
- 多个包同时失败且报错相似(如同一依赖的导入路径错误),通常指向共享代码或 monorepo 内依赖关系被破坏;
- 只有新增测试文件失败,可能指向测试环境配置(vitest config、fixtures)缺失——changed-test-gate.yml 里专门有一段"为 base 分支上的新包补回
package.json/vitest.config.ts"的逻辑,正说明新包测试常因缺少支撑文件而失败; - 失败集中在某个 shard,可先怀疑该 shard 内的资源竞争或超时。
3. 判断失败类型:flaky、真 bug 还是环境问题
这是整个流程中最关键的一步,文档明确要求区分三类:
| 类型 | 特征 | 处置方向 |
|---|---|---|
| Flaky(不稳定测试) | 相同 commit 重跑有时过有时挂,失败点常是网络请求、时间敏感断言、并发资源 | 重跑确认,必要时记录并单独修复测试本身,而非改业务代码 |
| 真 bug | 稳定复现、断言与实现预期确实不符 | 修改业务代码或补正测试期望,进入正式修复流程 |
| 环境问题 | 安装失败、store 缓存损坏、service 容器未就绪、runner 超时 | 重跑或清理缓存,一般无需改动代码 |
判断 flaky 与真 bug 的最直接办法是:在不改任何代码的前提下,对同一 commit 重新触发一次 CI(例如gh pr checks --watch或重新 push 空提交)。若失败消失,则高度怀疑 flaky。
4. 制定系统性修复计划
文档强调"create a systematic plan to address each failure type"。建议按"先环境、后 flaky、再代码"的优先级排序:先重跑/清理环境类失败,排除噪音;再对 flaky 做复现确认;最后集中火力处理真 bug,并把相同根因的失败归并到同一次修复中,避免边修边 push 造成 CI 反复排队。
第三步:实施修复——改动、本地验证与提交
1. 做出必要的代码修改
根据分析结果修改代码。Mastra 仓库的测试分布在packages/*、stores/*、workspaces/*、e2e-tests/*等目录,不同位置的测试失败对应不同的源码模块。修改时注意:只修与失败相关的代码,不要顺手做无关重构,以免扩大 CI 验证面。
2. 在本地尽可能复现并验证
文档要求 "run tests locally if possible to verify fixes"。Mastra 仓库提供了极有针对性的本地工具 scripts/affected-tests.mjs:它先用 madge 构建全量模块图并反转成反向依赖索引,再对每个变更的源文件做反向 BFS,找出所有传递依赖到该文件的测试。典型用法:
# 显式指定变更的源文件,找出受影响的测试 node scripts/affected-tests.mjs packages/core/src/storage/index.ts # 自动从 git diff 检测变更文件,并直接交给 vitest 执行 node scripts/affected-tests.mjs --git | xargs pnpm vitest run # 输出结构化 JSON(CI 中 prebuild.yml 使用的正是这个模式) node scripts/affected-tests.mjs --git --json支持--verbose(展示依赖链)、--symbol-aware(按符号级依赖遍历 barrel 文件,默认开启)、--file-level(回退到文件级遍历)等选项。这与 CI 中prebuild.yml的 affected-tests job 使用的是同一套逻辑——本地跑通它,就基本等价于在 CI 的最小验证面上跑通。
对于大型测试,CI 使用分片运行(--shard=${{ matrix.shard }}/4)、blob 报告合并(--reporter=blob)与--reporter=github-actions(把失败直接渲染为 GitHub Actions 注解,见 test-suite.yml)。本地复现时可以只跑目标文件,例如:
pnpm vitest run packages/memory/src/__tests__/xxx.test.ts如果失败源于 lint 或格式,本地执行pnpm lint;如果源于构建产物未提交,本地执行pnpm turbo build后再确认工作区是否干净。
3. 用清晰的提交信息提交全部改动
提交信息应直接说明修了什么 CI 问题,便于后续回溯。例如:
git add -A git commit -m "fix(ci): resolve failing memory integration tests on pgvector service ... "从仓库现有的工作流命名(fix(ci):风格在 Mastra 的 changeset 与提交实践中常见)可以推断,一条"fix(ci): + 具体失败项"的提交信息最容易被维护者与自动化工具理解。若改动涉及对外发布行为(版本号、依赖声明),还需按仓库惯例补充.changeset,否则peerdeps-check等 job 会检测到版本不一致而失败。
第四步:验证修复——推送并监控新的 CI 运行
修复后的闭环是文档的最后一步:push 并确认所有检查通过。
git push origin <branch> gh pr checks --watch值得注意的几个 Mastra 特有验证点:
- Changed Test Gate 会"反着"验证你的测试:changed-test-gate.yml 会把新增测试放到 base 分支上运行并期望失败("Changed tests failed against the base branch as expected")。如果你新增的测试在 base 上居然通过了,说明它没有真正覆盖新代码,CI 会显式报错拦截。因此写测试时务必保证它确实依赖新实现;
- Prebuild 的 fail-closed 设计:
prebuild.yml中如果 GitHub Compare API 调用失败或返回超过 300 个文件,会保守地按"有代码变更"处理并跑全量构建(prebuild.yml),避免漏检; - 路由决定验证范围:不是每次 push 都会全量跑。
affected-testsjob 会按变更文件计算受影响测试,命中超过 50% 阈值才切到全量模式;stores、workspaces、memory、mastracode、e2e 各有独立路由(涉及pnpm-lock.yaml、e2e-tests/、packages/server/等路径时会强制触发对应 E2E,见 prebuild.yml)。所以确认"哪些 job 被触发"同样重要——如果改动文件本应触发某类测试但对应 job 没跑,本身就是一种 CI 配置层面的异常。
附:一份可复用的 CI 修复检查清单
综合以上流程,收尾前逐项核对:
GH_PAGER=cat gh pr status/gh pr checks确认失败 job 清单;- 按"错误消息 → 模式 → 根因分类(flaky / bug / 环境)"完成分析,环境类优先重跑排除;
- 用
node scripts/affected-tests.mjs --git计算受影响测试并本地跑通; - 需要时本地执行
pnpm lint、pnpm turbo build验证非测试类检查; - 以
fix(ci):风格提交清晰的修复信息(发布相关改动记得补 changeset); - push 后用
gh pr checks --watch监控,确认本次触发的全部检查通过,同时留意 Changed Test Gate 的"新测试必须在 base 上失败"这一反向约束。
这套方法论直接来源于仓库内 .cursor/commands/gh-fix-ci.md 命令,并被 .github/prompts/gh-fix-ci.prompt.md 以 Agent prompt 形式固化为可自动执行的流程。掌握它,你就能在 Mastra 这样的复杂 monorepo 中把一次 CI 红变绿从"试错"变成"可预期的系统工程"。
【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考