ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Next.js CI 分诊工作流:从 pr-status.js 报告到 Review Thread 闭环的处理手册

Next.js CI 分诊工作流:从 pr-status.js 报告到 Review Thread 闭环的处理手册 Next.js CI 分诊工作流从 pr-status.js 报告到 Review Thread 闭环的处理手册【免费下载链接】next.jsThe React Framework项目地址: https://gitcode.com/GitHub_Trending/next/next.js本篇基于 Next.js 仓库中 pr-status-triage 技能的 workflow.md 展开讲清楚一个 PR 在 CI 出现构建、Lint、类型或测试失败时的标准分诊路径按什么优先级排障、如何判定“真失败”而非 flaky、每类失败对应哪些本地修复命令以及如何在处理完 Review 意见后用 scripts/pr-status.js 完成“回复—解决”线程的闭环。读完后你可以直接套用这套流程处理本仓库中任意一个失败 PR并理解 scripts/pr-status.js 生成的报告文件是如何支撑这一流程的。技能定位workflow.md 在 pr-status-triage 中的角色Next.js 仓库通过 .agents/skills 目录维护一组按需加载的 Agent 技能文档。pr-status-triage 技能由三个文件组成SKILL.md — 入口给出完整 7 步工作流与快速命令workflow.md — 本文主体定义优先级顺序、失败判定规则、常见失败模式与线程解决规程local-repro.md — 本地复现指南覆盖 dev/start 模式与 CI 环境变量对齐。workflow.md 的适用场景是当 CI 报告出现失败 job 或 PR 上出现未解决的 Review 线程时按既定规程逐一处理。它的上游输入是node scripts/pr-status.js生成的报告目录scripts/pr-status/results/其中index.md是总入口job-{id}.md是单个失败 job 的详情thread-N.md是单条 Review 线程的详情。优先级顺序先阻断项后评论workflow.md 定义了严格的全局优先级Build failures构建失败Lint failuresLint 失败Type failures类型检查失败Test failures测试失败Review commentsReview 评论且在 CI 阻断项之后这条顺序的原则是“blocker-first”越靠前的失败越会阻断后续所有环节构建不过则无产物可跑测试因此必须先解决。SKILL.md 中的快速命令支持从当前分支或指定 PR 号拉取状态node scripts/pr-status.js # 当前分支的 PR node scripts/pr-status.js number # 指定 PR node scripts/pr-status.js [PR] --wait # 后台模式等待 CI 完成 node scripts/pr-status.js --skip-flaky-check # 跳过 flaky 测试检测从源码看scripts/pr-status.js 的runAnalysis流程会先清理scripts/pr-status/输出目录再依次拉取分支信息、最新的 build-and-test workflow run、失败 job 元数据、job 日志与 PR 评论数据见 main 与 runAnalysis。--wait模式在 CI 仍在跑时会执行gh run watch run-id --compact等待结束后重新分析L1728-L1741这正对应 SKILL.md 中“后台运行超时 1 分钟然后读index.md”的工作流第 1 步。失败处理规则默认“有罪推定”workflow.md 的三条判定规则是分诊行为的核心约束把每个失败 job 当作“由当前改动引起”来调查Investigate each failing job as if it is caused by the current changes不要默认假设它是 flakyDo not assume flakiness by default如果 job 输出里存在 Known Flaky Tests 一节只把它作为历史上下文而不是自动免责的理由。这三条规则在 scripts/pr-status.js 中有明确的实现对应Known Flaky Tests 一节的生成逻辑generateIndexMd会在index.md中输出标题为### Known Flaky Tests (failing on 2 branches)的小节并明确注释“These tests also failed in recent CI runs across multiple different branches and are likely pre-existing flakes, not caused by this PR”L851-L862。注意措辞是likely——报告本身也只给概率性提示最终判定权仍在调查者手里这与“不作为自动免责理由”的规则一致。flaky 判定算法getFlakyTests会抓取最近 5 次其他分支的失败 run并行拉取其中失败 job 的日志统计“在 2 个及以上不同分支上都失败过”的测试路径只有满足该条件才进入 flaky 集合L1270-L1391。其中还有两个保护性细节单次 run 失败 job 超过 20 个时视为系统性故障而非 flakyL1315-L1316当前 PR 所在分支被排除以免自我匹配L1297。失败结论的认定范围脚本把failure、timed_out、startup_failure三种结论都计入失败FAILED_CONCLUSIONSL266即超时与启动失败同样进入 blocker 队列不存在被静默放过的情况。常见失败模式与修复命令workflow.md 针对三类高频失败给出了具体命令。以下逐条结合仓库实际说明。rust check / build失败适用场景Turbopack 等 Rust 侧代码在 CI 的 rust check/build job 中失败。cargo fmt -- --check # 检查格式 cargo fmt # 修复格式从源码结构看Rust 侧的 CI job 定义在 .github/workflows/build_and_test.yml 中例如rust-checkjob 通过afterBuild: pnpm dlx turbo run rust-check触发L340另有test-cargo-unit对应单测L305。格式问题是最常见的 rust check 失败原因本地跑cargo fmt -- --check即可快速定位若检查通过而 CI 仍失败则应按“有罪推定”原则继续读job-{id}.md中的报错段落。lint / build失败适用场景JS/TS 侧的 lint、Prettier 或构建 job 失败。pnpm prettier --write file # 修复指定文件的格式 # 如需进一步修复运行仓库的 lint 命令package.json 中的lint脚本是聚合入口实际包含 TypeScript 类型检查、Prettier 检查、ESLint、AST 扫描等多个子任务L74lint-fix则串联了 Prettier 与 ESLint 的修复L75。因此 CI 上名为 lint 的失败可能真正来自其中任意一个子任务定位时建议先看index.md失败 job 表格中该 job 的链接再进入job-{id}.md的失败段落。test failures失败workflow.md 给出两条规则本地运行与 CI 完全一致的失败测试文件dev 与 start 模式必须与 CI job 对齐。本仓库的测试入口由 scripts/run-jest.sh 封装package.json 中四种组合分别为test-dev-webpack: scripts/run-jest.sh --modedev --bundlerwebpack --headless --, test-dev-turbo: scripts/run-jest.sh --modedev --bundlerturbo --headless --, test-start-webpack: scripts/run-jest.sh --modestart --bundlerwebpack --headless --, test-start-turbo: scripts/run-jest.sh --modestart --bundlerturbo --headless --L26-L39“dev 模式”指直接对开发服务器做断言“start 模式”指先next build再next start后对产物做断言两者在模块解析、缓存行为上可能产生差异模式不匹配时的本地通过/失败结论都不可信。进一步地CI job 往往还叠加了特性开关环境变量。scripts/pr-status.js 的getJobEnvVarsFromWorkflow会解析 .github/workflows/build_and_test.yml 中每个 job 的afterBuild块提取其中的export VARvalue语句并按 job 显示名前缀匹配后写入index.md的### Job Environment Variables小节L154-L209、L829-L849。本地复现时必须镜像这些变量local-repro.md 给出的示例是IS_WEBPACK_TEST1 __NEXT_USE_NODE_STREAMStrue __NEXT_CACHE_COMPONENTStrue NEXT_TEST_MODEstart其中IS_WEBPACK_TEST1强制 webpack 模式本地默认是 Turbopack而NEXT_SKIP_ISOLATE1会跳过包隔离——验证模块解析或编译期修复时绝不应带这个变量。报告结构从哪里找到“失败的那个测试文件”“本地运行确切的失败测试文件”这一规则依赖报告提供的定位信息。scripts/pr-status.js 对每个失败 job 的日志做三层解析结构化测试 JSON从日志中的--test output start-- {...} --test output end--块提取 Jest 结果extractTestOutputJsonL541-L558生成每个 job 的job-{id}.md内含Test Results统计与Failed Tests表格Test File / Test Name / Error 三列L1067-L1096逐测试文件详情mergeRawTestOutputs会把结构化结果与##[group]❌ test/...原始日志块按测试路径合并为每个失败测试生成job-{id}-test-path.md包含多次尝试含重试内容与失败断言全文L642-L663、L1111-L1160日志分段extractSections按 GitHub Actions 的##[group]边界切分日志并标记含##[error]的段落落盘到scripts/pr-status/intermediate/供按段排查构建类失败L665-L730。因此标准动线是index.md的 Failed Jobs 表格确定 job →job-{id}.md的 Failed Tests 表格确定测试文件与断言名 → 用pnpm test-dev-turbo test/path/to/test.ts或对应模式本地复现。解决 Review 线程先回复后解决workflow.md 的最后一节规定了 Review 线程的处理规程当完成了评论要求的代码改动或确认当前代码已满足该评论时先回复线程说明所采取的动作node scripts/pr-status.js reply-thread threadNodeId Done -- description of changes再解决resolve线程node scripts/pr-status.js resolve-thread threadNodeId也可以一步完成回复并解决node scripts/pr-status.js reply-and-resolve-thread threadNodeId Done -- description of changesworkflow.md 特别强调解决之前必须先回复动作描述让 Reviewer 知道改了什么。这里的threadNodeId无需手动查找每次运行pr-status.js时generateThreadMd会为每个线程生成scripts/pr-status/results/thread-N.md文件底部的## Commands一节直接写入了填好真实thread.id的三条现成命令L1231-L1255——这正是 workflow.md 中“ready-to-use commands ... at the bottom of eachthread-N.mdfile”的出处。从实现看两个子命令背后的 API 路径不同值得注意回复replyToThreadL430-L496先用 GraphQL 按线程 node ID 反查出 PR 编号与首条评论的databaseId再走 REST 的POST /pulls/{pr}/comments/{commentId}/replies。源码注释解释了原因该 REST 端点会立即发布回复而 GraphQL 的addPullRequestReviewThreadReply可能把回复挂到未提交的草稿 review 上。回复正文会被自动加上:robot:前缀标识机器人身份。解决resolveThreadL498-L535走 GraphQL 的resolveReviewThread变更并回读isResolved校验结果失败时打印警告而非静默。闭环flaky-only 失败时的重跑策略当排障结论是“剩余失败全部为 Known Flaky Tests 且无需代码改动”时SKILL.md 给出的收尾动作是gh run rerun run-id --failed仅重跑失败 job等待约 5 分钟后回到第 1 步重新运行pr-status.js分析该循环最多重复 5 次。配合 workflow.md 的“flaky 只是历史上下文”规则完整的判定链是index.md的 Known Flaky Tests 小节跨 2 分支的历史失败→ 确认本 job 失败项与之重合且无代码改动必要性 → 重跑验证 → 若仍失败则按真实失败继续调查。小结环节动作依据/工具拉取状态node scripts/pr-status.js [--wait] [PR]生成scripts/pr-status/results/index.md及 job/thread 明细定优先级build → lint → types → tests → reviewworkflow.md 优先级节判定 flaky只看 Known Flaky Tests 小节作参考不自动免责getFlakyTests跨分支统计scripts/pr-status.js#L1270-L1391rust 失败cargo fmt -- --check/cargo fmtworkflow.md 常见模式节lint 失败pnpm prettier --write file 仓库 lint 命令package.json#L74-L75测试失败本地跑同一测试文件模式/环境变量与 CI 对齐package.json#L26-L39、local-repro.mdReview 线程先reply-thread说明改动再resolve-thread或一步reply-and-resolve-thread现成命令见results/thread-N.md底部scripts/pr-status.js#L1231-L1255flaky-only 收尾gh run rerun run-id --failed最多循环 5 次SKILL.md 第 7 步整套流程的设计意图是把“CI 红”从一个模糊状态拆成可枚举的动作报告文件给出全部定位信息workflow.md 给出判定纪律与命令而 scripts/pr-status.js 作为唯一事实来源持续刷新状态保证每次决策都基于最新的 job 与线程数据。【免费下载链接】next.jsThe React Framework项目地址: https://gitcode.com/GitHub_Trending/next/next.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表