news 2026/9/7 17:51:52

Remotion flake 技能实战:在 Tracker Issue 中记录 CI 不稳定失败并自动恢复测试套件

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Remotion flake 技能实战:在 Tracker Issue 中记录 CI 不稳定失败并自动恢复测试套件

Remotion flake 技能实战:在 Tracker Issue 中记录 CI 不稳定失败并自动恢复测试套件

【免费下载链接】remotion🎥 Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotion

Remotion 仓库为 Agent 提供了一组内部技能(internal skills),存放于.agents/skills/目录下。其中 flake 技能 专门解决一类高频但棘手的工程问题:CI 检查"看起来"失败,实际是 flaky(不稳定/偶发)失败。读完本文,你将掌握一套完整的 flake 处理流程——如何用ghCLI 定位失败的 PR、workflow run、job 与日志,如何判定一个失败是否真的是 flake,如何生成稳定的失败签名(signature),如何把失败登记进 tracker issue 的 Markdown 表格,以及如何选择正确的重跑(rerun)策略让受影响的测试套件恢复绿灯。

flake 技能的定位与适用场景

根据 skill-locations 技能 的约定,Remotion 把"仅内部 Agent 使用"的技能放在.agents/skills/<skill-name>/SKILL.md,把可分发的公共技能放在packages/skills/skills/下。flake 属于前者:它是维护者内部的工作流剧本(playbook),触发条件是"一个 Remotion CI 检查失败且看起来是 flaky",或用户显式请求执行/flake

技能 frontmatter 中声明的核心职责有三件事:

  1. 跟踪 Remotion 的 CI flake,统一登记在 tracker issue #8375;
  2. 对重复出现的失败签名(signature)累加计数;
  3. 在未给出 PR 时,主动发现失败的 PR 检查,并重跑 flaky 的 GitHub Actions job。

技能的总体目标可以概括为一句话:把 flaky 失败记录进 issue #8375,并让受影响的测试套件重新跑通。对每一个"已确认或疑似"的 flake,标准动作是三步:

  1. 定位 PR、workflow run、job、失败的 step,并提炼简洁的失败签名;
  2. 更新 tracker issue:签名已存在则累加其Count,是新签名则追加一行(计数1、workflow/job、首次出现日期、证据 URL);
  3. 重跑 flaky 的 job 或全部失败 job。

定位失败:gh 命令集

技能明确要求优先使用ghCLI 而不是 GitHub App,原因是 GitHub App 可能无法暴露完整的 Actions 日志和写入权限。针对不同的输入上下文,给出了四组命令。

场景一:用户提供了 PR 编号

gh pr view <pr-number> --repo remotion-dev/remotion --json number,title,headRefName,statusCheckRollup gh pr checks <pr-number> --repo remotion-dev/remotion --watch=false

第一条拿到 PR 的基础信息和完整的 check rollup(所有检查项的状态汇总),第二条直接列出各 check 的通过/失败明细,--watch=false避免阻塞等待。

场景二:用户提供了 workflow run 或 job URL

gh run view <run-id> --repo remotion-dev/remotion --json databaseId,attempt,displayTitle,event,headBranch,headSha,status,conclusion,workflowName,createdAt,updatedAt,url,jobs gh api repos/remotion-dev/remotion/actions/jobs/<job-id>/logs

注意attempt字段的含义——同一个 run 重跑后会形成多个 attempt,这直接决定了下一条命令的选择。第二条用 raw API 拉取指定 job 的完整日志,用于阅读失败 step 的实际输出。

场景三:没有 PR 上下文

当用户只说"CI 挂了"而没有给 PR 时,需要主动扫描最近的开放 PR 和最近的失败 run:

gh pr list --repo remotion-dev/remotion --state open --limit 30 --json number,title,headRefName,statusCheckRollup gh run list --repo remotion-dev/remotion --workflow "Install and Test" --status failure --limit 20 --json databaseId,displayTitle,event,headBranch,headSha,conclusion,createdAt,url,workflowName

这里筛选的 workflow 名称"Install and Test"在仓库中是真实存在的:它定义在 .github/workflows/push.yml 中(name: Install and Test),由 push 到 main 和 pull_request 事件触发。该 workflow 的结构也解释了为什么它容易产生 flake:它先用一个affectedjob 通过bun .github/scripts/ci.ts plan查询 Turborepo 任务图来裁剪出受影响的测试子集(lambda、nextjs、ssr、browser、webrenderer 等矩阵 job),再按输出条件执行对应的集成测试 job。测试矩阵被裁剪、并发取消(concurrency+cancel-in-progress)都会让超时类失败更具偶发性。

场景四:针对重跑过的 run,先查原始 attempt

一个常见陷阱:run 已经 rerun 过一次,直接看当前 attempt 的日志可能全是绿的,无法判断第一次失败是不是 flake。技能要求在判定前检查第一次 attempt:

gh api repos/remotion-dev/remotion/actions/runs/<run-id>/attempts/1/jobs --paginate gh api repos/remotion-dev/remotion/actions/jobs/<failed-job-id>/logs

即:拉取 attempt 1 的 job 列表,再取其中失败 job 的日志。如果同一 run/job/step 在无代码改动的情况下重跑后成功了,这正是判定 flake 的第一条判据(见下一节)。

flake 判定标准

技能给出了明确的判定规则——满足以下至少一条即可视为 flake:

  • 重跑验证:同一个 run、job 或失败 step 在没有代码改动的情况下重跑后成功了;
  • 基础设施/网络类故障:例如fetch failed、连接被重置(connection reset)、包管理器下载失败、缓存服务故障、runner 供给错误(provisioning error);
  • 与 PR 改动无关的偶发失败:超时、竞态(race)、浏览器断连、端口冲突、外部服务间歇性故障,且该 PR 的改动"不可能"触及出问题的区域。

同时给出了反例边界:不要把确定性的类型错误(type error)、lint 错误、snapshot 不匹配、或"由源码行为变更导致的测试断言失败"记入 tracker,除非有证据表明它们在重试后能通过。这条边界很重要——tracker 的价值在于把"噪声失败"与"真实回归"分开,误登记会把真实的 bug 淹没在 flake 表格里。

仓库中自带的 flake 缓解机制

判定标准不是凭空而来的。以 flake 文档示例中反复出现的@remotion/it-tests#testssr为例,packages/it-tests/package.json 里定义了"testssr": "bun src/run-ssr-tests.ts"。而这个脚本本身就是一个精心设计的防 flake 包装器:packages/it-tests/src/run-ssr-tests.ts 对每个测试文件最多尝试 2 次,用Bun.spawn在独立子进程中运行bun test <file> --timeout 40000,并设置了 90 秒看门狗——超时先发SIGTERM,2 秒后再补SIGKILL(非 Windows 下直接 kill 整个进程组);第一次超时会在干净进程中重试并打印timed out. Retrying in a clean process.,第二次才超时则抛出timed out twice

从源码结构看,这正是 flake 文档里"timeout / race / browser disconnect"那类判据的现实来源:单个测试文件首次超时时,CI 未必会失败(脚本会自动重试一次),而"两次都超时"才会真正让 job 失败——这类失败在负载较高的 runner 上确实具有偶发性,是 tracker 表格的典型登记对象。同理,oven-sh/setup-bun@v2.1.2 failed with TypeError: fetch failed这类签名对应的是 push.yml 中每个 job 都会执行的setup-bunaction 拉取失败(bun 版本固定为 1.3.3),属于典型的网络类基础设施故障,与 PR 代码无关。

签名(Signature)规则

签名是 tracker 表格中"把重复失败归为一组、又足够具体以便处理"的关键。技能的规则:

  • 能给出 package 或 suite 名就给,例如@remotion/it-tests#testssr
  • 能给出测试名就给
  • 包含根因错误文本,但要剥离时间戳、文件路径、随机 ID、端口号、行号、ANSI 颜色码——这些是"同一次签名、不同次实例"的主要噪声来源;
  • workflow/job 信息单独放在 tracker 行的对应列里,除非不放进签名就无法区分,否则不要混入签名。

文档给出的两个"好签名"示例:

  • `oven-sh/setup-bun@v2.1.2` failed with `TypeError: fetch failed`
  • `delayRender()` timeout while running `Render video with browser instance not open` in `@remotion/it-tests#testssr`

两个示例分别代表"基础设施类"和"测试超时类"两种典型 flake:前者签名锚定在失败的 action 版本上,后者锚定在"渲染模式 + 包#suite + 根因"上。第二个示例中的测试名Render video with browser instance not open确实存在于 it-tests 的 SSR 测试中(如 packages/it-tests/src/ssr/render-media.test.ts),说明签名规则是贴着真实测试套件写的。

更新 Tracker Issue

登记环节围绕 tracker issue #8375 的正文展开。先读取当前正文:

gh issue view 8375 --repo remotion-dev/remotion --json body --jq .body

操作时有两条硬性约束:

  • 编辑完整正文、保留表格结构——不能只贴增量;
  • 替换后的 Markdown 必须写入临时文件并用--body-file提交,不要内联传递多行 Markdown(避免 shell 转义把表格弄坏)。

tracker 表格的格式:

| Count | Signature | Workflow / job | First seen | Evidence | | ---: | --- | --- | --- | --- | | 1 | `signature` | `Workflow` / `Job` | YYYY-MM-DD | <对应 Actions run 的 URL> |

累加已有行的规则:

  • 除非旧证据链接已失效、或新链接比旧链接更有用,否则只改Count
  • First seen始终保持最早一次出现的日期。

追加新行的规则:

  • 证据列优先使用 GitHub Actions 的job URL(比 run URL 更能直接定位失败步骤);
  • 首次出现日期以日志中的时间戳为准,而不是本地机器日期——CI 日志时间戳与操作者本地时区可能不一致,用日志时间戳能保证跨维护者登记的一致性。

编辑完成后必须回读验证:

gh issue view 8375 --repo remotion-dev/remotion --json body --jq .body

这一步能捕获表格被破坏、行被重复追加等静默错误。

重跑策略

技能按三种情况给出了从轻到重的重跑手段:

只重跑失败 job(首选)——大多数 flake 场景用这一条就够了:

gh run rerun <run-id> --repo remotion-dev/remotion --failed

run 已结束、只有一个已知 flaky job 需要重跑时,用 raw API 直接重跑单个 job,避免整个 run 重来:

gh api --method POST repos/remotion-dev/remotion/actions/jobs/<job-id>/rerun

flaky 的 suite 仍在运行中、继续等待会阻塞当前任务时,先取消再重跑:

gh run cancel <run-id> --repo remotion-dev/remotion gh run watch <run-id> --repo remotion-dev/remotion --exit-status gh run rerun <run-id> --repo remotion-dev/remotion --failed

这里有一个容易踩坑的细节:取消会使 run 的最终状态变成 failure,因此gh run watch可能以非零状态退出——技能明确要求此时继续执行后面的 rerun 步骤,不要被非零退出码误导而中断流程。

收尾汇报

技能规定处理结束后向用户汇报三项内容:

  • tracker issue 中新增或累加了哪一行;
  • 采取的重跑动作,附 run 或 job URL;
  • 还有哪些仍在运行的检查项是刻意没有动的(避免误杀正在进行中的正常 job)。

这一收尾设计保证了每次 flake 处理都是可审计的:登记动作、重跑动作、保留动作三件事都有据可查,tracker 表格随着时间累积后,本身就成为该仓库 CI 稳定性的观测数据——哪些签名Count高、集中在哪个 workflow/job,就是下一步修复(比如调整测试超时、加固缓存或升级 action 版本)的优先级依据。

小结

flake 技能的价值在于把"CI 挂了"这个模糊事件拆解成一条可复现的操作链:定位(四组 gh 命令覆盖有无 PR、有无重跑的不同上下文)→ 判定(三条阳性判据 + 一条排除边界)→ 签名(去噪后的稳定标识)→ 登记(body-file 全量编辑 + 回读验证)→ 重跑(failed-only、单 job API、cancel 后重跑三档策略)→ 汇报。配合仓库中 run-ssr-tests.ts 这类内置重试脚本和 push.yml 的任务图裁剪机制,它构成了 Remotion 这个大型 monorepo 处理偶发 CI 失败的完整闭环。

【免费下载链接】remotion🎥 Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotion

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

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

3个月掌握新中地GIS系统:从数据处理到二次开发全攻略

1. 新中地系统学习3个月能实现什么效果&#xff1f;第一次接触新中地系统是在去年帮朋友解决一个GIS项目时。当时看到他用这个国产GIS平台处理空间数据的速度和稳定性&#xff0c;完全颠覆了我对国产地理信息软件的认知。经过3个月的集中学习和实战&#xff0c;我发现这套系统远…

作者头像 李华
网站建设 2026/9/7 17:47:20

基于SpringCloud+Layui+AI的智能政务微服务审批系统设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 17:47:04

gcc hello.c背后:从预处理到链接的编译全流程解析

“hello.c”几乎是我见过的第一段C代码&#xff0c;而gcc hello.c也是我敲下的第一条编译命令。当时只觉得这条命令神奇&#xff1a;一个文本文件&#xff0c;敲一下回车&#xff0c;就变成了能运行的程序。后来折腾的东西多了才发现&#xff0c;这短短一条命令背后藏着一整套工…

作者头像 李华
网站建设 2026/9/7 17:44:59

动画制作中的版本管理与文件命名规范解析

1. 项目概述&#xff1a;解密"dragonballz_e159-2"的创作逻辑这个看似随机的字符串组合&#xff0c;实际上蕴含着动画创作领域的典型版本管理智慧。作为从业15年的动画制片人&#xff0c;我见过太多类似"dragonballz_e159-2"这样的版本代号——它们就像动画…

作者头像 李华
网站建设 2026/9/7 17:44:31

前端BUG、后端BUG、环境BUG如何快速区分?一套定位方法论

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 17:43:32

校园网断网环境下远程访问实验室电脑的解决方案

1. 校园网断网远程访问的核心痛点校园网环境下远程访问实验室或宿舍电脑的需求非常普遍&#xff0c;但经常遇到三个典型问题&#xff1a;首先是校园网IP地址动态分配且不固定&#xff0c;一旦路由器重启就会导致远程连接失效&#xff1b;其次是校园网防火墙通常会屏蔽3389等常见…

作者头像 李华