关于 diagnosing-ci-and-merge-bottlenecks
这是面向工程团队和自主 Agent 的 CI 与合并瓶颈诊断技能,通过命名的 MCP 工具分析 PR 生命周期、工作流健康度和测试失败情况。它侧重聚合流水线状况,并明确数据的覆盖范围与局限。
主要功能
- 01查看开放及近期关闭的 PR
- 02比较 CI 工作流成功率与耗时
- 03追踪单个 PR 的生命周期
- 04筛选测试健康队列中的问题
- 05关联工作流、PR 与生命周期分析
- 06说明数据截断、延迟与缺失限制
适用场景
- 01发现运行缓慢或不稳定的 CI 工作流
- 02筛选 CI 失败或待处理的开放 PR
- 03定位 PR 生命周期中耗时的阶段
- 04评估测试隔离候选及影响
MCP 相关
该技能通过命名的 MCP 工具读取 GitHub 工程分析数据,包括 `pull-requests`、`workflow-health`、`pr-lifecycle` 和测试健康队列;使用者调用这些工具,而非编写 SQL。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ posthog/ skills --skill diagnosing-ci-and-merge-bottlenecks安装后在 Claude Code 中输入/diagnosing-ci-and-merge-bottlenecks确认已加载。
详细介绍
诊断 CI 和合并瓶颈
工程分析将拉取请求视为产品分析中的用户:PR 会经过一条流水线
(opened → CI → review → merged → deployed),任务是找出它在哪个环节变慢。表层是命名的
MCP 工具——调用即可,无需编写 SQL。已在 PostHog/posthog 上进行自用验证;同一套工具也适用于
自主 Agent(例如 PostHog Desktop),帮助它们分析自己的 PR。范围是流水线整体健康状况:
若要将某个失败的测试或红色运行追查至得出结论,请切换到 investigating-ci-failures 技能。
工具
pull-requests— PR 工作主力。列出开放的 PR,以及自date_from(默认为-30d)以来已合并或关闭的 PR,按时间倒序排列。每行包含author(嵌套对象:handle、display_name、is_bot)、repo(嵌套对象:owner、name)、state、is_draft、labels、open_to_merge_seconds、ready_to_merge_seconds, 以及通过 head-SHA 联接汇总的ci(runs/passing/failing/pending)。可解答大多数 PR 层面的问题:哪些 PR 的 CI 失败或仍在等待、哪些 PR 开放时间最长、按作者或仓库进行分类,以及合并耗时统计(自行对返回的已合并行计算中位数和 p95,绝不要计算平均值;若ready_to_merge_seconds非空则优先使用,因为它不包含草稿时间)。workflow-health— 统计一个时间窗口内各工作流的 CI 健康状况(date_from/date_to,默认最近 24 小时):run_count、success_rate、p50_seconds、p95_seconds、last_failure_at。可解答“CI 正在变快还是变慢”,以及“哪个工作流耗时长或不稳定,成为瓶颈”。此功能不内置趋势分析——请针对两个相邻时间窗口分别调用并进行比较。success_rate统计成功或以明确失败状态(failure、timed_out、startup_failure或stale)结束的运行,不包括跳过、取消、中性或需要采取操作的运行。p50_seconds/p95_seconds仅统计成功的运行,因为取消和失败的运行会提前结束,从而导致时长趋势产生偏差。如果时间窗口内没有符合条件的运行,这些值均为null——比较两个时间窗口前请先处理null(某个工作流可能在一个窗口内有运行,在另一个窗口内则没有)。run_scope=pull_request将范围限定为归属于 PR 的运行,不包括 master/main(仅限同一仓库的 PR——来自 fork 的运行没有 PR 归属信息)。pr-lifecycle— 单个 PR 的时间线:一个标题,以及按顺序排列的事件——开放、转为可供评审和转为草稿(当 issue-events 表已同步时),接着是每次工作流运行对应的一对 CI 开始/结束事件(多工作流仓库中会有多组,按时间交错排列),最后是合并/关闭。可解答“PR N 卡在哪个环节”。metric_quality为partial(不包含评审或评论事件)。engineering-analytics-flaky-tests— 根据逐测试的 CI 区间,在一个时间窗口内统计活跃的测试健康队列(date_from默认为-7d,最多 30 天)。证据按每次 CI 运行计数,绝不按区间或运行尝试计数。只有在证据能够证明存在非确定性时,classification才为confirmed_flake(same_commit_recovery_run_count > 0:同一提交在同一个矩阵任务中既未通过测试又通过了测试,例如通过“Re-run failed jobs”尝试后测试转为绿色,或通过任务内重试;在不同任务中通过,例如 FOSS 通过而 EE 未通过,不算恢复);quarantined表示在屏蔽期间记录了一个可容忍的失败;suspected_regression表示只记录了失败,这只是缺乏证据,并非真实故障的证据。符合以下任一条件的测试会进入队列:同一提交出现恢复、出现隔离失败、master/main 上出现任何失败,或至少在min_failed_prs个不同 PR 上失败(failed_pr_count)。可解答“这个失败的测试让我们付出了什么代价”,并筛选隔离候选项。它无法回答“哪些测试不稳定”:此队列只能检测主 Backend pytest 和 Frontend Jest 测试套件,且只有在有人重新运行失败的任务(或 pytest 测试被手动标记为@pytest.mark.flaky(reruns=N))后,才能获得恢复证据。计数是绝对信号,而非比率:大多数通过的运行都不会被记录,因此不存在可信的分母。CI 配置故障会排除该次尝试的所有测试记录,而不仅仅是失败记录:如果某次运行尝试中有 3 个或更多任务的测试报错,或涉及 3 个或更多所属团队,或者某次任务尝试中有 100 个或更多不同的测试失败或报错。 影响范围如此广泛的真实故障也会被排除,因此当整个测试套件或任务都变红时,请查看workflow-health,不要把空队列误认为状态健康。engineering-analytics-sources:团队已连接的 GitHub 来源和仓库。如果有多个来源或仓库,请先调用此工具,并将所选条目的source_id和repo传给pull-requests、workflow-health、pr-lifecycle和team-ci-health。只传source_id会读取该来源的默认仓库,而不是你所选的仓库。只有一个来源和仓库时,工具会默认使用它们。
没有汇总的合并耗时工具,也没有“计数”工具——请从 pull-requests 中推算这些数据(卡住或失败的数量、合并耗时百分位数)。
每次回答都必须说明的注意事项
这些是当前快照数据的结构性限制——请如实说明,不要掩盖。
open_to_merge_seconds粒度较粗。 它将 草稿 时间和 准备好供审查 时间合并为一个数值。请称其为“从打开到合并”,切勿称为“周期时间”或“审查时间”。如果长期处于草稿状态的 PR 拉高了数值,请明确指出。ready_to_merge_seconds是更精确的对应指标:从最后一次观察到的准备好供审查状态转换时间到merged_at的时长(只计算最后一次草稿/准备就绪状态切换),或者对于可确认从未进入草稿状态的已合并 PR,计算从created_at到merged_at的时长。Null 表示“未观察到”(PR 的整个生命周期未完全落在已同步的问题事件窗口内,或该表尚未同步),绝不表示零。因此,只能对非 null 行进行汇总,并说明有多少行可观察。- CI 状态可能过时。 CI 来源按水位线同步,较新运行记录到达后,不会刷新随后才完成的运行(
workflow_runwebhook 推出前都是如此)。请将pending数量视为尚未定论,而非已确认的失败;先说明状态,不要急于下结论。 - PR 的 CI 关联只通过头部 SHA 连接。
ci汇总仅反映最新提交的运行记录。PR 与其检查项之间没有其他关联方式。 - 选择延后读取审查数据。 GitHub
reviews端点会同步审查提交及其时间戳,但在楔形工具需要之前,读取操作会保持延后。请勿根据缺少这些数据推断审查行为。pr-lifecycle因同样原因标记为partial。 - 部署指标位于
engineering-analytics-dora,数据来自 GitHub 部署表(已同步时由deploy_data_available表示)。其中的变更失败和恢复用时字段是部署状态的代理指标(未关联事件),请使用其准确字段名报告,切勿将其称为真正的 DORA 定义。 pull-requests输出中包含机器人和草稿 PR,但按惯例会排除。 对吞吐量/合并耗时问题,请过滤掉author.is_bot(嵌套在author下,不是行级字段)和is_draft;对机器人影响问题,则应保留它们。pull-requests返回的页面有上限。 最多返回 1000 行,按最新优先排序:这是固定的服务端上限,会在响应中以limit回显,任何参数都无法提高此上限。当truncated为true时,你推算出的任何百分位数或计数都只涵盖最新页面,而非整个时间窗口。请说明这一点,然后缩小范围,直到实际数据集能完整纳入:author可筛选单个账号,source_id/repo可筛选单个仓库,date_from可缩短时间窗口。
选择工具
| 问题 | 工具 | 使用方法 |
|---|---|---|
| CI 是否变慢了?哪个工作流耗时最长? | workflow-health | 在两个相邻时间窗口内调用(例如,先用 date_from=-14d,再用 date_from=-28d 和 date_to=-14d);比较每个工作流的 p50_seconds 和 p95_seconds。优先看中位数,但始终要单独检查 p95——两者的变化并不相关。 |
| 哪些未关闭的 PR 有失败或待处理的 CI? | pull-requests | 保留 ci.failing > 0 或 ci.pending > 0 的行。pending 表示尚未结束(或已过时),并非已确定失败。 |
| 哪些 PR 开启后停留的时间最长? | pull-requests | 保留 state = open、is_draft 为否且 author.is_bot 为否的行;按 created_at 升序排列(最早的在前)。 |
| PR 合并需要多长时间?按作者统计呢? | pull-requests | 对已合并的行(merged_at 已设置、非机器人、非草稿),汇总非空的 ready_to_merge_seconds(若为空,则使用 open_to_merge_seconds,并标注为粗略值),计算中位数和 p95。按 author.handle 分组,以了解各群组的情况,而非进行排名(对开发者进行监控明确不在目标之列)。调用时使用两个 date_from 时间窗口即可查看趋势。 |
| PR N 卡在哪个环节? | pr-lifecycle | 按顺序查看事件:opened → ready_for_review(存在状态转换事件时可得草稿耗时)、CI 阶段(首次开始 → 最后完成;每个工作流一组)、last CI finished → merged。最大间隔就是瓶颈。如果从就绪到合并耗时很长,但 CI 很快,说明时间花在审查或等待上;目前 partial 数据还无法细分这些耗时——请明确说明。 |
| 一次测试失败造成了多大损失?哪些测试应隔离? | engineering-analytics-flaky-tests | 默认时间窗口为 -7d;各行已按影响范围排序(先列主干分支失败,再列影响到的不同 PR 数量)。报告数量,绝不报告比率。关于“是否为不稳定测试”,只有 confirmed_flake 行有确凿证据(同一个矩阵任务中,同一次提交既失败又通过**:重跑后通过,或任务内重试后恢复)。 |
高价值调查链路
模仿人工调查流程:汇总信号 → 确认问题 → 定位到具体 PR。
workflow-health (find the slow/flaky long-pole workflow)
→ pull-requests (confirm it's dragging merge time; list the affected PRs)
→ pr-lifecycle (open a representative stuck PR and show the gap)
“CI 中位数上升是因为 e2e-playwright 的 p95 翻了一倍;该工作流是 PR #1234 的耗时瓶颈,该 PR 在 CI 中停留了 47 分钟才合并。”
输出预期
- 首行给出结论,然后列出支持结论的数据。
- 只要区分有意义,就注明数据粗略、部分缺失或可能过时。
- 比较多个时间窗口或工作流时,优先使用简短表格,而不是文字说明。并列报告中位数和 p95 — 切勿将二者合并成一个“平均值”。
不要这样做
- 不要将
open_to_merge_seconds称为周期时间或评审时间 — 它是粗略的从打开到合并耗时;ready_to_merge_seconds才是周期时间数据,且仅在值非空时适用。 - 当
pending > 0时,不要将 CI 数量报告为已确定的失败 — 结果可能尚未确定或已过时。 - 不要推断评审或批准情况 — 在某个切入工具需要评审读取能力之前,评审读取仍暂不支持。不要推断单项检查的数量。部署数据来自
engineering-analytics-dora,不能靠推断得出。 - 不要将按作者划分的数据桶做成排行榜 — 它们用于发现卡住的工作,而不是给人员排名。
- 不要使用这些工具来获取原始 PR 内容或差异 — 它们提供的是流水线信号,而不是 PR 讨论串。
持久化答案
这些工具用于临时读取;无法将结果保存为洞察或订阅。当用户想将相同数据保存为洞察、仪表板磁贴或定时邮件 / Slack 投递时,请切换到
turning-engineering-analytics-into-insights 技能:底层数据仓库表
(<prefix>github_pull_requests / <prefix>github_workflow_runs,前缀来自 engineering-analytics-sources)可直接使用 HogQL 查询;该技能包含经过整理的列语义,以及创建洞察 / 创建订阅的工作流。
DORA 环境默认包含所有标记为生产环境或名称中包含 production 的持久环境。读取 selected_environments,以确认经过验证的确切范围。DRF 会根据真实名称验证显式筛选条件,包括临时环境。它会修剪并去重有效名称,对于空白或未知名称则返回 400 响应。省略筛选条件即可使用默认值。每个区域部署单独计数;前置时间会按每个 PR 在任一所选环境中的首次成功部署计算一次。