news 2026/9/8 20:22:56

Metabase CI 失败报告实战:使用 `mage ci-report` 生成、分类并修复 PR 检查失败

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Metabase CI 失败报告实战:使用 `mage ci-report` 生成、分类并修复 PR 检查失败

Metabase CI 失败报告实战:使用mage ci-report生成、分类并修复 PR 检查失败

【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase

本指南针对 Metabase 开源仓库(当前为仓库根目录)内的 Claude Code 命令 .claude/commands/ci-report.md 及其底层实现 mage/src/mage/ci_report.clj(约 780 行 Clojure 任务),系统讲解如何为一个 PR(或分支、提交 SHA)一键生成 CI 失败报告,并给出后续的失败分类与处置工作流。读完本文,你将掌握./bin/mage ci-report的完整用法、参数与报告结构,理解其底层如何抓取 GitHub Checks/日志并解析 Trunk 测试报告,以及如何区分“真实失败 / 偶发(flaky)/ 基础设施问题”并采取正确的下一步动作。

1. 一条命令与一份“人类可读的失败清单”

Metabase 的 CI 由大量 GitHub Actions 工作流组成,一个 PR 动辄挂起几十上百个 check(后端 Clojure 测试、前端 Jest、Cypress E2E、Trunk.io 静态分析等)。直接逐个点击失败 check 的日志链接效率很低。仓库为此在mage任务体系中实现了ci-report,而 Claude Code 命令ci-report.md则把它与 Agent 的分析工作流绑定起来:

  • 人类(或 Agent)执行./bin/mage ci-report $PR_NUM_OR_URL生成报告;
  • 随后按固定三段流程处理:总结失败 → 归类失败 → 给出建议下一步

从源码看,该任务命名空间为mage.ci-report(mage/src/mage/ci_report.clj#L1-L8),其硬编码的远程仓库固定为metabase/metabase

(def ^:private repo "metabase/metabase")

也就是说,该命令面向 Metabase 上游仓库的 CI 数据查询,所有底层调用都经由 GitHub 官方ghCLI 完成(gh pr viewgh pr checksgh api)。

1.1 前置条件

  • 已安装并完成认证的 GitHub CLI(即gh),且当前凭据能访问metabase/metabase的 checks 与 Actions 日志接口;
  • 本地已可运行 mage 任务(仓库使用 babashka + Clojure 实现 mage 命令,入口脚本位于 bin/mage 与 mage/);
  • 若目标 PR 尚未有可用 check 数据,报告会提示 “No checks found… Try again in a minute”。

2. 命令语法与三类入参解析

完整用法(来自任务报错与帮助文本,mage/src/mage/ci_report.clj#L763):

./bin/mage ci-report [--detailed] [--attempt N] <pr-number|branch|sha>

入参可选。当不带任何参数时,任务先尝试用gh pr view --json number反查“当前分支对应的 PR”(get-current-branch-pr);如果当前分支没有 PR,则回退为按分支名解析其最近一次 CI 提交(git rev-parse --abbrev-ref HEAD拿到分支名)。

当带参数时,参数会被classify-arg按顺序判定为三类之一(classify-arg):

判定优先级参数形态示例解析结果
1形如github.com/.../pull/<数字>的 PR 链接https://github.com/metabase/metabase/pull/12345:pr,提取其中数字
2纯数字41234:pr
37–40 位十六进制字符a1b2c3d(提交 SHA):sha
4其余一切my-feature-branch:branch,通过 Actions runs API 解析为最新 CI 提交

三种类型最终汇入同一条流水线:PR 路径gh pr view+gh pr checks(run-pr-report!);分支/提交路径走 GitHub REST API 的check-runsactions/runs接口(run-commit-report!)。注意gh pr checks在失败时返回码非 0,因此实现用sh-nil包装这类“预期会失败但输出仍有效”的命令(sh-nil)。

3. 两个关键选项:--detailed--attempt N

任务入口generate-report!读取options中的:detailed:attempt(generate-report!):

3.1--detailed:带 expected/actual 的完整失败块

默认(Summary 模式)只提取日志中Trunk Test Report摘要段;--detailed则拉取失败 job 的全量日志,并按两类格式还原完整失败上下文:

  • Clojure 后端测试extract-failure-blocksFAIL inERROR in开行,遇到LONG TESTRan N tests in ...结束,输出整块堆栈/断言信息(mage/src/mage/ci_report.clj#L251-L311);
  • Cypress E2E 测试extract-cypress-failuresN) suite > nested > title编号失败块切分,到(Results)(Screenshots)(Video)、passing 汇总或长分隔线处收尾(mage/src/mage/ci_report.clj#L313-L361)。

报告中对应标注Mode: Detailed (with expected/actual)Mode: Summary(generate-report)。

3.2--attempt N:回溯某次重跑记录

GitHub Actions 允许对失败的 workflow run 重跑(rerun),每次重跑会递增run_attempt--attempt让报告定位到指定 attempt 的 job 状态。其解析逻辑非常实用(resolve-attempt):

  • 正数 N:绝对 attempt 序号;
  • 0:等于该提交的最大 attempt(最新一次重跑);
  • 负数 Nmax_attempt + N,因此-1表示“最新一次重跑之前的那一次”。

attempt-checks会先把 commit 关联的所有 workflow run 聚合,再按 attempt 过滤,并跳过总 attempt 数不足的 run(mage/src/mage/ci_report.clj#L632-L659);越界时会直接报错退出。

4. 报告长什么样:结构与判定逻辑

generate-report(mage/src/mage/ci_report.clj#L409-L521)最终打印一份可直接粘贴到 PR 评论的 Markdown,段落固定为:

  1. 标题# CI Report for PR #<number>: <title>(分支/SHA 模式则用# CI Report for <branch|sha>);
  2. Metadata:PR 链接、Branch、SHA、Mode、Attempt;
  3. Loading Data:用/记录的命令执行轨迹(便于审计各步骤耗时与结果);
  4. Summary 汇总表
| Status | Count | |--------|-------| | ✅ Passed | N | | ❌ Failed | N | | ⏳ Pending | N | | **Total** | **N** |
  1. 状态消息categorize-checks把每个 check 归一化为FAILURE / SUCCESS / PENDING / IN_PROGRESS / QUEUED等,categorize-checks),共四种结论:
    • ⚠️ No checks found.——CI 可能尚未启动或数据未就绪;
    • ✅ All checks passing!
    • ⏳ CI is still running... (N checks pending)
    • ⚠️ CI has failures and is still running (N failed, N pending)
  2. ❌ Failed Checks:按名称排序逐个列出失败的 job,附原始日志链接,然后在 Summary 模式下粘贴解析出的 Trunk 摘要,--detailed模式下粘贴完整失败块;没有可解析内容则输出_No test failures found in logs._
  3. ⏳ Pending Checks:尚未结束的 check 列表;
  4. 结尾附生成时间:_Generated by mage ci-report at ... UTC_

4.1 失败日志如何被“清洗”出来

从原始 job 日志到可读文本经历了多层处理,这是报告可信度的关键:

  • ANSI 清理:剥掉颜色转义序列(strip-ansi,mage/src/mage/ci_report.clj#L34-L41);
  • 回车覆盖还原:终端进度动画用\r覆盖行,解析时对每行只保留最后一个\r之后的内容(resolve-carriage-returns,mage/src/mage/ci_report.clj#L43-L53);
  • 时间戳剥离:去掉 GitHub Actions 日志行首的2026-02-06T02:38:25.1443042Z前缀(strip-timestamp,mage/src/mage/ci_report.clj#L166-L171);
  • 定位测试报告段:Summary 模式下以📚(Trunk Test Report 标题)、Total: N Pass:汇总行或trunk.io链接三种标记寻找报告起点,找不到则回退取末尾 2000 行(find-test-report-start);
  • Trunk 摘要结构还原parse-trunk-report📦 <package>、失败测试名、⤷ <trunk.io链接>…and N more failures等碎片拼回缩进清晰的分组失败清单(mage/src/mage/ci_report.clj#L173-L249)。

日志抓取本身带**最多 3 次指数退避重试(1s→2s)**与单请求 60 秒超时(job-logs-raw,mage/src/mage/ci_report.clj#L129-L150);多个失败 job 的日志用 Clojurefuture并行抓取,每个 job 同样有 60 秒上限,个别超时不会拖垮整个报告(fetch-failed-logs-parallel,mage/src/mage/ci_report.clj#L381-L407)。

5. 拿到报告后的三步工作流(命令核心)

命令正文规定了拿到报告后必须执行的三个动作,这正是把“机器生成的报告”升级为“可执行的结论”的关键一环:

5.1 Summarize the failures(总结失败)

以报告中的Failed ChecksSummary表为基础,说明:哪些测试失败了?在哪些 job 中失败?涉及 Clojure 单元/集成测试、前端测试还是 Cypress E2E?失败是否集中在某个包(📦 metabase.foo-test)或某条 spec 文件?

5.2 Categorize(归类:真实失败 / flaky / 基础设施)

类别特征信号处置方向
真实失败(real)断言错误、堆栈来自被测代码、与 PR 改动明显相关定位根因并提出修复
偶发(flaky)与改动无关的随机失败、超时类、或换一次重跑即通过建议重跑验证
基础设施(infrastructure)超时(timeout)、内存溢出(OOM)、网络错误、runner 故障记录问题类型并在报告中注明,通常不是代码缺陷

可以用--attempt N/--attempt -1对比历次重跑结果来辅助判断 flaky 与否——若某测试上一次 attempt 通过、本次失败,flaky 概率显著上升。

5.3 Recommend next steps(给出建议下一步)

  • 判为 flaky:建议执行 GitHub CLI 的失败项重跑:

    gh run rerun <run-id> --failed -R metabase/metabase

    其中<run-id>可在失败 check 的 Actions run 页面或gh run list中获取;

  • 判为真实失败:结合--detailed模式输出的完整FAIL in/ERROR in块或 Cypress 编号失败块定位根因,提出针对该测试或源码的修复建议;

  • 判为基础设施问题:明确标注是 timeout、OOM 还是 network,避免误当成代码问题处理。

5.4 全部通过时

命令明确要求:如果所有 check 都通过,简短确认即可(例如“CI 全部通过 ✅”),无需展开冗长分析。这与报告内部逻辑一致——All checks passing!时不会再有 Failed Checks 段落。

6. 如何查看帮助与完整任务列表

mage 任务基于 babashka + Clojure,入口为 mage/(含 mage/src/mage/cli.clj 的命令行解析与 malli schema 参数校验)。查看任务帮助可直接运行:

./bin/mage ci-report --help

帮助会打印 Task Name、Usages、Arguments、Options 与 Examples(mage/src/mage/cli.clj#L45-L80);参数不合法时也会自动打印帮助并退出。若希望了解该命令在 Agent 工作流中的定位,可对照阅读 .claude/commands/ci-report.md 及其它相关 bot/命令文档(如 .claude/commands/fix-pr.md、.claude/commands/qabot-report.md)。

7. 实践建议与注意事项

  • 先无参跑一次:在功能分支上直接执行./bin/mage ci-report即可得到当前分支所属 PR 的报告,比手输 PR 号更省事;它会自动走“当前分支 PR → 分支最新 CI 提交”的回退链。
  • 失败很多时优先用 Summary 模式:它只解析 Trunk 摘要,输出精炼;需要深入某一具体失败时再针对该 job 用--detailed
  • 重跑后对比 attemptgh run rerun ... --failed重跑完成后,用./bin/mage ci-report <pr> --attempt -1回溯上一轮,可快速确认某失败是否为 flaky。
  • 报告是只读的mage ci-report只查询 GitHub API 并输出 Markdown,不会改动任何仓库文件或 CI 配置;请放心在 CI 报错时反复调用。

【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 20:20:33

极空间NAS部署道理鱼:音乐/MV/有声书全栈媒体库完整指南

一直在折腾家里的极空间NAS&#xff0c;从最开始的纯文件存储&#xff0c;到后来跑Jellyfin看剧、部署各种自动化工具&#xff0c;慢慢感觉这台机器的功能越挖越深。前两天为了给车上的音乐库和跑步时候听的有声书找一个统一入口&#xff0c;盯上了一个叫『道理鱼』&#xff08…

作者头像 李华
网站建设 2026/9/8 20:19:51

FPGA 100G光口光模块测试实战:从GT配置到误码分析

1. 项目概述与测试目标拆解做FPGA开发这些年&#xff0c;凡是和高速接口沾边的项目&#xff0c;最终基本都会绕到光口上来。尤其是100G这个速率档位&#xff0c;从数据中心到仪器仪表&#xff0c;从通信设备到视频传输&#xff0c;几乎成了标配。我这段时间正好在调试一块带100…

作者头像 李华
网站建设 2026/9/8 20:16:44

从本地到Gitee:Git推送、仓库创建与高频问题全解

最近这几年&#xff0c;Git 基本成了程序员的“第二本能”&#xff0c;但话说回来&#xff0c;天天用 Git 的人里面&#xff0c;真正能一口气把项目从本地推到远端仓库、再顺利被同事拉下来的人&#xff0c;真没想象中那么多。尤其咱们在国内做开发&#xff0c;打交道最多的平台…

作者头像 李华
网站建设 2026/9/8 20:15:45

1 条命令跑通 IDEA 源码:intellij-community 构建实操

1 条命令跑通 IDEA 源码&#xff1a;intellij-community 构建实操 【免费下载链接】intellij-community IntelliJ IDEA & IntelliJ Platform 项目地址: https://gitcode.com/GitHub_Trending/in/intellij-community intellij-community 是 IntelliJ IDEA 与 Intelli…

作者头像 李华