尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Electron PR 分诊工具 triage-prs 详解:基于 gh CLI 按 CI 状态分类 open PR 的完整实践

Electron PR 分诊工具 triage-prs 详解:基于 gh CLI 按 CI 状态分类 open PR 的完整实践 Electron PR 分诊工具 triage-prs 详解基于 gh CLI 按 CI 状态分类 open PR 的完整实践【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electron本文围绕 Electron 仓库内置的 triage-prs 技能 展开讲清这套 PR 分诊 工具如何通过ghCLI 加jq把海量 open PR 按 CI 检查状态归类为 green / failing / pending / none 四类如何与 PR Triage 项目看板联动标注评审进度以及默认的 GitHub Actions Completed 伞形检查umbrella check背后真实的 GitHub Actions 工作流实现。读完后你将能够独立运行该脚本完成 PR 分诊、按单个检查项如faraday/cage过滤、理解每一类判定结果的边界条件并根据源码自行解释输出结果中的每一列标记。一、工具定位与文件结构triage-prs是 Electron 仓库维护者工作流中的一个 AI 技能skill由两个文件组成均位于仓库根目录的.claude/skills/triage-prs/下SKILL.md技能说明书定义触发条件如用户说 faraday、failing prs 时自动执行、状态分类表和全部用法示例triage-prs.sh真正执行分诊的 Bash 脚本约 258 行仅依赖ghCLI 和jq通过 GitHub REST 与 GraphQL API 拉取数据。两者通过文件头部的 front-matter 关联SKILL.md中的name: triage-prs与description字段让 AI 助手在用户请求 triage PRs、列出绿色/可合并 PR、找出 CI 失败或仍在跑的 PR 时触发本技能。该技能由 提交 db65df8492 引入仓库chore: add triage-prs skill and script。它要解决的实际问题很具体Electron 是一个高频接收 PR 的大型开源项目单个检查项如构建矩阵中的macos-x64 / build / build有成百上千个状态组合维护者需要快速回答三个问题——哪些 PR 的 CI 全绿可以优先合并哪些 PR 的 CI 挂了需要作者修复哪些 PR 还卡在排队或运行中本工具就是围绕这三个问题设计的命令行分诊器。二、前置条件gh CLI、jq 与 read:project 权限运行脚本前需要满足以下环境要求脚本在 第 81 行至第 88 行 会显式检查并给出报错安装并认证 GitHub CLIgh auth login。gh是脚本访问 GitHub 的唯一通道。安装jq并保证在PATH中。脚本用jq解析gh返回的 JSON状态汇总、标题、URL、标签、看板字段。可选如需展示 PR Triage 看板 Status 列ghtoken 需要read:project权限。缺失时用以下命令补授gh auth refresh -s read:project值得注意的是脚本并不会因为缺少该权限而整体失败。第 95 行至第 107 行 的实现逻辑是先用一条 GraphQL 查询探测能否读取项目title这是需要read:project的最小操作若返回INSUFFICIENT_SCOPES则打印一次性提示并自动关闭 Status 列TRIAGE0其余分诊功能照常运行。这种降级而非报错的设计保证了核心分诊能力不受权限影响。三、四类状态模型green / failing / none / pending这是本技能的核心概念。每个被扫描的 open PR 都会被归入且仅归入以下四类之一状态图标含义green✅所有检查通过SUCCESS/NEUTRAL/SKIPPED。failing❌至少一个检查失败FAILURE/ERROR/CANCELLED/TIMED_OUT/…。pending检查存在但部分仍在运行PENDING/IN_PROGRESS/…。none⚪完全没有检查在跑。这四个类别不是脚本凭空定义的而是严格映射到 GitHub API 返回的statusCheckRollup条目上。脚本通过一段内嵌的jq程序完成归类其判定链值得逐行理解第 168 行至第 215 行第一步把每个检查条目归一化为一个状态值state_of函数。statusCheckRollup里混着两种数据结构GitHub Actions 的CheckRun条目带.status和.conclusion字段和旧版StatusContext条目只有.state字段。state_of的处理顺序是if (.status ! null and .status ! COMPLETED) then .status elif ((.conclusion // ) ! ) then .conclusion elif ((.state // ) ! ) then .state else PENDING end这里有一个源码注释里特别点明的坑未完成的CheckRun其.conclusion是空字符串而非 null所以必须先按.status判断否则会把运行中的检查误判为已完成。若所有字段都取不到值兜底为PENDING。第二步把状态值列表收敛为四个类别之一classify函数。优先级是失败优先其次等待最后全绿if ($s | length) 0 then null elif any($s[]; . FAILURE or . ERROR or . CANCELLED or . TIMED_OUT or . ACTION_REQUIRED or . STARTUP_FAILURE or . STALE) then failing elif any($s[]; . PENDING or . EXPECTED or . IN_PROGRESS or . QUEUED or . REQUESTED or . WAITING) then pending else green end可以看到failing覆盖了 7 种失败态包括STALE和STARTUP_FAILUREpending覆盖了 6 种等待态既无失败也无等待的剩余组合SUCCESS/NEUTRAL/SKIPPED等归为green空列表返回null在调用侧再转成none。四、默认评估范围GitHub Actions Completed 伞形检查默认情况下脚本并不逐一看 PR 上的所有检查而是只看一个名为GitHub Actions Completed的检查。这不是一个普通检查而是 Electron 构建工作流专门设计的伞形检查umbrella check它在 build.yml 中定义为gha-donejobgha-done: name: GitHub Actions Completed runs-on: ubuntu-latest permissions: contents: read needs: [docs-only, checkout-macos, checkout-linux, checkout-windows, macos-x64, macos-arm64, linux-x64, linux-x64-asan, linux-x64-ubsan, linux-arm64, build-siso-macos, build-siso-linux, build-siso-windows, windows-x64, windows-arm64] if: always() github.repository electron/electron steps: - name: Fail if any needed job failed or was cancelled if: contains(needs.*.result, failure) || contains(needs.*.result, cancelled) run: exit 1从源码结构看这个 job 的作用是把十几个平台构建/测试 jobmacOS x64/arm64、Linux x64/asan/ubsan/arm64、Windows x64/arm64 等的结果聚合成一个对 PR 而言的二元信号只要needs中任一 job 结果为failure或cancelled就exit 1。if: always()保证即使上游 job 失败它也会运行并发出失败状态。这样分诊脚本只需盯着一个检查就能判断整条 CI 流水线的最终结果显著减少误判面。若想改用其它评估口径脚本提供--check参数# 评估 PR 上的全部检查 .claude/skills/triage-prs/triage-prs.sh --check # 只看某一个具体检查 .claude/skills/triage-prs/triage-prs.sh --check macos-x64 / build / build五、关键设计SKIPPED 的伞形检查不算通过这是整套分诊逻辑中最微妙、也最能体现 Electron CI 特点的一条规则第 205 行至第 211 行当--check指定的单个检查默认即伞形检查结果为SKIPPED时脚本不将其视为通过而是回退到 PR 的完整检查集重新分类以找出真实状态。原因在 Electron 的 CI 中很具体当某个必需的上游 job 失败时GitHub Actions Completed 伞形检查可能被跳过skip此时它的SKIPPED状态并不代表 CI 通过只代表这个聚合 job 没有真正跑完。对应源码elif any($s[]; . SKIPPED) then # A SKIPPED umbrella is NOT a pass; fall back to the full check set. ( classify($allStates) // green )另外还有一个相关的边界规则当指定检查在statusCheckRollup中根本不存在时第 200 行至第 204 行脚本区分两种情况——PR 一个检查都没有length 0才判none若 PR 上有其它检查、只是伞形检查尚未发出则判pending。这条规则解释了为什么默认口径下一个 PR 在自己的各项检查还在跑、而伞形检查还没贴出来时会被读作pending等伞形检查贴出后才翻转为green/failing。六、完整用法参数、环境变量与输出格式6.1 命令行示例继承自 SKILL.md 全部示例在仓库根目录下运行# 绿色 PR默认扫描 electron/electron 最近 200 个 open PR .claude/skills/triage-prs/triage-prs.sh # 按不同状态过滤 .claude/skills/triage-prs/triage-prs.sh --status failing .claude/skills/triage-prs/triage-prs.sh --status none .claude/skills/triage-prs/triage-prs.sh --status pending # 分类所有被扫描的 PR 并逐一显示状态 .claude/skills/triage-prs/triage-prs.sh --status all # 少扫一些 PR 以加快结果 .claude/skills/triage-prs/triage-prs.sh --status failing --limit 50 # 指向其它仓库或改变检查口径 .claude/skills/triage-prs/triage-prs.sh --repo electron/forge --limit 50 .claude/skills/triage-prs/triage-prs.sh --check # 评估全部检查 .claude/skills/triage-prs/triage-prs.sh --check macos-x64 / build / build # 定位到单个命名检查例如找 faraday/cage 还在 pending 的 PR .claude/skills/triage-prs/triage-prs.sh --check faraday/cage --status pending .claude/skills/triage-prs/triage-prs.sh --check faraday/cage --status failing # Triage 看板 Status 列 .claude/skills/triage-prs/triage-prs.sh --no-triage # 隐藏 Status 列 .claude/skills/triage-prs/triage-prs.sh --triage-project PR Triage # 读取另一个看板6.2 参数与默认值对照从 脚本第 48 行至第 53 行 可以直接确认全部默认值且六个参数都支持同名环境变量作为默认值、再被命令行参数覆盖参数环境变量默认值说明--status sSTATUSgreen取值为green/failing/pending/none/all非法值会报错退出--check nameCHECK_NAMEGitHub Actions Completed只评估该命名检查传空字符串则评估全部检查--triage/--no-triageTRIAGE1开启显示或隐藏 PR Triage 看板的 Status 列--triage-project nTRIAGE_PROJECTPR Triage读取 Status 的看板名称--repo owner/nameREPOelectron/electron目标仓库--limit nLIMIT200扫描的 open PR 数量上限--help的实现也很讲究第 58 行至第 60 行 用awk动态提取脚本头部从 shebang 之后到第一个非注释行之间的注释块作为帮助文本而不是写死行号范围这样头部注释扩充后帮助文本自动保持同步。6.3 输出格式每个 PR 输出一行条目图标、PR 编号的可点击超链接OSC 8 终端超链接、标题、各类标记第二行给出裸 URL 以便纯文本终端使用第 247 行至第 248 行✅ #52533 feat: support restrictOwnAudio constraint [PR Triage: Needs Review] https://github.com/electron/electron/pull/52533其中[new-pr]标记当 PR 带new-pr标签时追加的判定逻辑见 第 226 行至第 229 行由于实际标签名以new-pr开头并带后缀标签全名含尾部 emoji脚本用前缀匹配startswith(new-pr)来识别避免硬编码完整标签名而失配。七、与 PR Triage 项目看板的联动除 CI 状态外脚本还会为每个 PR 标注它在 PR Triage GitHub 项目看板ProjectV2上的Status字段例如[PR Triage: Needs Review]。实现上分两步拉取 Status 值第 110 行至第 133 行对每个 PR 发一条 GraphQL 查询pullRequest.projectItems(first:20)取出每个projectItem所属项目的title和名为Status的字段值ProjectV2ItemFieldSingleSelectValue再用jq过滤出title $TRIAGE_PROJECT的那一条。一个 PR 可能同时挂在多个项目看板上因此按看板名精确匹配是必要的。过滤 WIP第 237 行至第 240 行如果 Status 值包含WIP子串该 PR 被静默排除——它被视为尚未准备好评审不出现在结果里也不计入总数。这里有一个重要的副作用--no-triage会跳过全部看板查询此时 WIP PR会被包含在结果中因为过滤依赖看板数据。也就是说--no-triage的输出集合与默认输出集合在 WIP 维度上并不可比这一点在汇总结果时必须向用户说明。八、两个快捷入口faraday 与 failingSKILL.md 定义了面向维护者的两个高频快捷指令faraday——当用户只说 faraday或 faraday prs、pending faraday时运行.claude/skills/triage-prs/triage-prs.sh --check faraday/cage --status pending列出faraday/cage检查仍在 pending 的 open PR。faraday 是 Electron 使用的 PR 信任/审查机器人其仓库内配置文件 faraday.yml 定义了 trusted-bots如trop[bot]、electron-roller[bot]等回滚/回移机器人只需 1 个 maintainer 审批与 trusted-reviewers文档审查 bot 仅在改动全部位于docs/**时计数。faraday/cage是它发出的 CI 检查维护者常需要知道哪些 PR 还卡在 faraday 排队中。failing——当用户只说 failing prs或 PR 分诊语境下的 failing ci时运行.claude/skills/triage-prs/triage-prs.sh --status failing列出检查失败的 open PR。九、运行时长与 API 消耗不要误判脚本挂起SKILL.md 的 Runtime 一节给出了必须了解的运行特性每个 PR 最多触发两次gh调用一次gh pr view取statusCheckRollup/标题/URL/标签一次 GraphQL 查看板 Status且串行执行因此在默认--limit 200下一次完整扫描需要数分钟并消耗数百次 API 请求执行时应显式使用较长超时10 分钟是安全值或用更小的--limit做快速局部扫描不要假设脚本挂起——长时间无输出属于正常现象。主循环结构第 250 行至第 251 行先用一条gh pr list一次性取回 open、非草稿 PR 的编号列表再逐个gh pr view这是 API 调用量的主要来源。十、如何正确解读输出结果这是 SKILL.md 中 Interpreting results 一节的全部要点逐条对应源码行为两类 PR 在所有运行中被静默排除且不计入总数汇总时必须说明输出并非 open PR 全集Draft PR在gh pr list阶段就被select(.isDraft | not)过滤第 251 行看板 Status 含WIP的 PR视为未准备好评审第 237 行至第 240 行注意--no-triage跳过看板查询此时 WIP PR会被包含。带状态过滤默认green时只列出分类匹配的 PR其余被省略。none表示该 PR真的一个检查都没有什么都还没触发这与pending检查存在但未完成有本质区别。由于默认评估口径是 GitHub Actions Completed 伞形检查一个 PR 在其各项检查运行期间会被读作pending直到伞形检查发出状态才翻转为green/failing只有零检查的 PR 才会是none。想按全部检查判断就用--check 。伞形检查SKIPPED不视为通过见第五节脚本会回退到完整检查集找真实状态。十一、汇总结果的报告规范SKILL.md 的 Reporting results 一节规定了把脚本输出转述给使用者时的两条格式约定每个 PR 渲染成 Markdown 链接使其在聊天界面可点击例如[PR #52533](https://github.com/electron/electron/pull/52533) — feat: support restrictOwnAudio constraint。脚本输出中每条目的第二行就是该 PR 的 URL直接取用即可当 PR 带new-pr标签脚本输出[new-pr]标记时汇总中用纯文本[new-pr]表示而不是 emoji。十二、小结triage-prs 技能是 Electron 仓库把 PR 分诊 这一重复性维护工作沉淀下来的典型范例SKILL.md 声明触发词、状态语义与用法triage-prs.sh 用ghjq实现严格的四态分类并与仓库自身的 CI 设计深度耦合——评估口径默认锚定 build.yml 中聚合十几个平台 job 的 GitHub Actions Completed 伞形检查针对SKIPPED伞形检查回退全量检查、区分none与pending、静默排除 Draft/WIP PR 等规则全部对应 Electron CI 的真实行为而非通用假设。理解这套实现既能直接复用该脚本完成日常分诊也为在其它大型 CI 矩阵仓库中设计类似的 按检查状态批量分诊 PR 工具提供了可参考的完整样本。【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electron创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表