Prhub

#27785 Fix PR-close cancellation skipping workflows beyond the first 30

原始 PR 作者 hnyls2002 合并时间 2026-06-13 06:39 文件变更 2 提交数 4 评论 1 代码增减 +104 / -21

执行摘要

修复 PR 关闭时取消工作流遗漏后续工作流的问题

PR body 指出,styfle/cancel-workflow-action 的 workflow_id: all fetches only the first page (30) of repo workflows, so runs of newer workflows (e.g. pr-test-extra.yml, observed on #23906 holding GPU runners for ~55 min after merge) were never cancelled on PR close. 需要替换为更全面的取消方式。

建议阅读该 PR 的实现,特别关注如何使用 gh api 组合分页和过滤来实现可靠的取消逻辑。该模式可用于其他需要针对分支取消运行或清理资源的场景。代码内联注释清晰,易于理解。

讨论亮点

无有效 review 讨论。仅有一条来自 gemini-code-assist[bot] 的自动回复,表示无法因文件类型不支持而生成审查。

实现拆解

  1. 删除旧工作流:移除 .github/workflows/cancel-pr-workflow-on-merge.yml,该文件使用 styfle/cancel-workflow-actionworkflow_id: all,只能获取前 30 个工作流。
  2. 新建工作流:创建 .github/workflows/cancel-pr-workflows-on-close.yml,使用 pull_request_target 触发器在 PR 关闭时触发,设置 actions: write 权限。
  3. 列出并过滤运行:在 run 步骤中通过 gh api 列出仓库中指定 branch 的所有运行,用 jq 过滤出 head_repository.id 与当前 PR head repo ID 匹配且运行 ID 不等于当前运行 ID 的运行。遍历所有未完成状态(queued, in_progress, waiting, pending, requested, action_required),并执行两轮以避免时序问题;每个状态列表最多重试 3 次。
  4. 取消与降级:对每个运行 ID 先尝试 gh run cancel,若失败则调用 force-cancel API(处理被 approval/deployment protection 阻塞的情况);若运行已在间隔中完成则忽略。记录错误到 FAILURES 变量。
  5. 错误处理:使用 set -euo pipefail,最后以 exit $FAILURES 退出,确保步骤失败能被工作流捕获。
文件 模块 状态 重要度
.github/workflows/cancel-pr-workflows-on-close.yml CI 工作流 added 6.25
.github/workflows/cancel-pr-workflow-on-merge.yml CI 工作流 removed 3.88

分析完成后,这里会展示 LLM 生成的相对完整源码片段和详细注释。

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

风险较低。主要风险包括:

1) gh api 可能因网络或限频失败,但代码内置了重试机制;
2) pull_request_target 在 fork 场景下需确保 head_repo.id 可用,代码中有空值检查并提前退出;
3) GITHUB_TOKEN 权限可能不足以 force-cancel 某些运行,但已处理错误记录。该变更仅影响 CI 取消行为,不涉及生产逻辑。

影响范围限于 PR 关闭后的 CI 运行取消。此前未取消的工作流现在会被及时取消,释放 GPU Runner 资源,减少资源浪费。对频繁合并 PR 的仓库节省显著。影响程度中等偏下。

简单的 CI 配置变更 API 限频风险 权限依赖

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论