PR合并慢,别再只看平均时长:GitHub把等待拆成了三段

一个 PR 花两天才合并,问题可能是没人点开,也可能是修改来回拉扯,或批准后一直搁置。只看总时长会把三种病混成一个数。GitHub 新增的分段指标,让团队能用中位数和 P90 判断该加审查人、缩小 PR,还是改自动合并规则。

这次API增加了什么

GitHub 9 月 25 日宣布,企业和组织的仓库级 Copilot 使用报告新增 pull_request_review_times 数组。每个条目把 PR 生命周期拆成三段:从 ready for review 到第一次审查、第一次到最后一次审查、最后一次审查到合并;每段都提供中位数和第 90 百分位(P90),单位为分钟。

口径非常关键。当前只统计由人创建、且至少被另一名人类审查后合并的 PR;Copilot、其他机器人和作者自己的审查不计入。数据按合并日归属,9 月 21 日之前进入 ready 状态的 PR 不纳入该分段,而且没有历史回填。安静的一天返回空数组 [],不是零。

flowchart LR A[PR标记Ready] -->|等待首次响应| B[第一次人工审查] B -->|修改与复审| C[最后一次人工审查] C -->|批准后等待| D[合并] B -.P50/P90.-> E[响应能力] C -.P50/P90.-> F[协作复杂度] D -.P50/P90.-> G[发布与权限流程]

为什么一定要同时看P50和P90

中位数 P50 代表典型 PR,P90 代表最慢的那一成。若 P50 很短、P90 很长,说明大多数流程没问题,但某些仓库、时区或高风险改动缺少兜底;若两者都长,才更像系统性产能不足。

我的核心判断是:这些指标是排队系统的症状,不是开发者绩效分。拿 P90 给个人排名,会鼓励快速点"批准"、拆成没有意义的小 PR,甚至绕过审查。正确用法是按仓库和变更类型找瓶颈,再验证干预是否降低尾部等待。

最小实践:下载并读取日报

官方接口先返回短时有效的 NDJSON 下载链接,再从报告行里读取数组。下面脚本使用当前文档要求的 2026-03-10 API 版本,密钥只从环境变量读取。

javascript 复制代码
async function main() {
  const token = process.env.GITHUB_TOKEN;
  const org = process.env.GITHUB_ORG;
  const day = process.argv[2] ?? "2026-09-26";
  if (!token || !org) throw new Error("缺少GITHUB_TOKEN或GITHUB_ORG");

  const headers = {
    Accept: "application/vnd.github+json",
    Authorization: `Bearer ${token}`,
    "X-GitHub-Api-Version": "2026-03-10",
  };

  const metaUrl = `https://api.github.com/orgs/${org}/copilot/metrics/` +
    `reports/organization-1-day?day=${day}`;
  const meta = await fetch(metaUrl, { headers });
  if (!meta.ok) throw new Error(`GitHub API ${meta.status}`);

  const { download_links: links = [] } = await meta.json();
  for (const link of links) {
    const text = await (await fetch(link)).text();
    for (const line of text.trim().split("\n").filter(Boolean)) {
      const row = JSON.parse(line);
      for (const item of row.pull_request_review_times ?? []) {
        console.log(JSON.stringify({
          repo: row.repository_name, merged: item.total_merged,
          firstReviewP90: item.p90_minutes_ready_to_first_review,
          reworkP90: item.p90_minutes_first_to_final_review,
          mergeP90: item.p90_minutes_final_review_to_merge,
        }));
      }
    }
  }
}
main().catch((error) => { console.error(error); process.exitCode = 1; });

运行环境需 Node.js 18 以上:GITHUB_TOKEN=... GITHUB_ORG=... node pr-metrics.mjs 2026-09-26。令牌需要组织 Copilot metrics 只读权限,且组织必须启用相应策略。本次无目标组织权限和真实令牌,示例未在本次任务中实际运行;已使用 Node.js 26.7 做静态语法检查。

三种指标对应三种动作

首次审查慢:设置代码所有者和轮值审查人,给高风险目录明确响应时限,而不是群里反复催人。

首次到最终审查慢:查看 PR 尺寸、测试反馈速度和需求是否频繁变化。一个 3000 行 PR 的问题通常不是审查人不努力,而是交付单元太大。

最终审查到合并慢:检查分支保护、部署窗口、必需检查和自动合并。批准后等待很长,往往是机器或权限流程而非代码讨论。

汇总时别把百分位再平均

API 按仓库和作者、审查者类型给出聚合值。把多个仓库的 P90 简单取平均,得不到整个组织的 P90:小仓库的一条慢 PR 会获得与大仓库数百条 PR 相同的权重。若拿不到原始时长,至少按 total_merged 做加权展示,并明确它仍是近似值;更稳妥的是保留仓库维度,分别观察趋势。

还应把"速度"和"质量"并排。审查变快但回滚率、线上缺陷或二次修复上升,不是有效改进。可以为每个仓库同时记录变更失败率、紧急回滚、PR 大小和必需检查耗时。这样才能分辨是审查人响应慢,还是 CI 队列把人类等待伪装成协作问题。

一个可执行的四周实验是:第一周只采集基线;第二周为高 P90 目录设置主备审查人;第三周开启批准后的自动合并;第四周比较三段指标、样本数和失败率。不要同时改十项规则,否则即使数值下降,也无法知道哪项措施有效。

对跨时区团队,分钟数还要结合工作时间解释。周五晚提交、周一审查在日历上很慢,却未必违反团队约定。若产品不提供工作时段口径,可以在自建分析中为每个团队计算"营业分钟",但要公开时区和节假日规则,避免用不透明修正制造漂亮数字。

风险与适用边界

数据刚开始积累且没有回填,早期样本很薄;单次审查的 PR,"首次到最终"会是 0;total_merged 通常低于仓库全部合并数。小团队每日只有一两个 PR 时,按天的 P90 会剧烈跳动,至少应看四周滚动窗口,并同时保留样本数。

这套指标适合诊断人类参与的审查流程,不适合衡量纯机器人 PR、未合并 PR 的积压,也不能直接证明 Copilot 提升了研发效率。建议先记录四周基线,再一次只改变一项流程,观察三段中哪一段真的下降。

仪表盘之外还要保留定性复盘。每月抽查几条极慢与极快的 PR,问清等待原因、是否有人绕过流程、合并后是否返工。数字负责指出异常,工程师负责解释因果;两者缺一,优化就容易变成追逐指标。

你们团队最慢的一段通常是等第一次审查、反复修改,还是批准后没人合并?

关注「蜗牛聊AI」,一起看懂技术变化背后的真正机会。


本文首发于 java4u.cn,转载请注明出处。

相关推荐
知几蜗牛1 小时前
AI眼镜把记忆放上云,怎样证明云端也看不见?
人工智能
知几蜗牛1 小时前
训练数据越多越好吗?用LeRobot讲清数据质量与版本化
人工智能
知几蜗牛1 小时前
AI账单失控前,团队真正缺的不是更便宜的模型
人工智能
清桔1 小时前
Agent调用流程
人工智能
吴佳浩1 小时前
Agent 可观测性(Observability):分布式追踪、链路诊断与 Token 成本精细化核算
人工智能·agent·ai编程
武子康1 小时前
Agent 能接进 IDE,为什么还不能随意互换?
人工智能·llm·agent
IT_陈寒1 小时前
我的JavaScript代码为啥在forEach里没按预期执行?
前端·人工智能·后端
知几蜗牛1 小时前
AI修过一次漏洞还会再犯吗?关键不只是“记住”
人工智能
老马识码1 小时前
Function Calling 与工具设计
人工智能