Prhub

#26035 cancel pr ci: cover closed-no-merge; widen workflows; rerun-test opt-in

原始 PR 作者 hnyls2002 合并时间 2026-05-22 10:38 文件变更 2 提交数 3 评论 1 代码增减 +132 / -54

执行摘要

修复 PR CI 取消工作流的漏洞,覆盖关闭未合并和工作流不完整

PR body 指出原有工作流存在空白,导致已关闭但未合并的 PR 仍有排队运行,且 pr-test-extra 和 ci-coverage-overview 工作流未被取消,/rerun-test 的 workflow_dispatch 运行无法正确关联到 PR。

对于 CI 维护者值得精读,特别是 maybe_cancel_for_pr 函数的处理逻辑和 gh run list --status 的使用。

讨论亮点

无 review 讨论。

实现拆解

  1. 修改 cancel-unfinished-pr-tests.yml
    • 默认工作流列表从 pr-test.yml 扩展为 pr-test.yml pr-test-extra.yml,增加新输入 include_rerun_test 以选择性地包含 rerun-test.yml
    • 重构取消逻辑,提取 maybe_cancel_for_pr 函数,统一处理 PR 状态查询和取消决策。
    • 对已关闭 PR(无论是否合并)直接取消运行;对开放 PR 保持原有标签跳过规则。
    • 改用 gh run list --status 服务器端过滤查找旧运行,避免 --limit 长时间扫描。
  2. 修改 cancel-pr-workflow-on-merge.yml
    • 工作流名称从 "Cancel PR Workflows on Merge" 改为 "Cancel PR Workflows on Close",移除 if: github.event.pull_request.merged == true 条件,使 PR 关闭时(无论是否合并)都触发取消。
文件 模块 状态 重要度
.github/workflows/cancel-unfinished-pr-tests.yml CI modified 5.75
.github/workflows/cancel-pr-workflow-on-merge.yml CI modified 3.22

关键源码片段

.github/workflows/cancel-unfinished-pr-tests.yml infrastructure

主要重构文件,覆盖了新的工作流范围、添加 rerun-test 选项,并提取统一的取消判断逻辑。

# 核心逻辑片段:maybe_cancel_for_pr 函数
# 根据 PR 状态决定是否取消运行
maybe_cancel_for_pr() {
  local run_id="$1"
  local pr_query="$2"
  local pr_label="$3"  # 查询 PR 信息,取第一个结果
  local pr_info
  pr_info=$(gh api -H "Accept: application/vnd.github+json" "$pr_query" \
    --jq '.[0] | {number, state, merged_at}' 2>/dev/null || true)  if [ -z "$pr_info" ] || [ "$pr_info" = "null" ]; then
    echo " ⚠️ 未找到 PR($pr_label),跳过"
    return
  fi  local pr_number pr_state
  pr_number=$(echo "$pr_info" | jq -r '.number // empty')
  pr_state=$(echo "$pr_info" | jq -r '.state // empty')  if [ -z "$pr_number" ]; then
    echo " ⚠️ PR 查询返回空编号,跳过"
    return
  fi  local pr_url="https://github.com/$REPO/pull/$pr_number"
  echo " PR: $pr_url ($pr_state)"  # 关键决策:已关闭 PR(合并或未合并)直接取消
  if [ "$pr_state" = "closed" ]; then
    echo " 🚫 取消(PR 已关闭)..."
    gh run cancel "$run_id" --repo "$REPO" || echo " ⚠️ 取消失败"
    return
  fi  # 开放 PR:根据标签判断是否跳过
  local labels
  labels=$(gh pr view "$pr_number" --repo "$REPO" --json labels \
    | jq -r '.labels[].name' 2>/dev/null || true)  if echo "$labels" | grep -Fxq "bypass-maintenance"; then
    echo " ⏭️ 跳过(标签 bypass-maintenance)"
  else
    echo " 🛑 取消(无跳过标签)..."
    gh run cancel "$run_id" --repo "$REPO" || echo " ⚠️ 取消失败"
  fi
}
.github/workflows/cancel-pr-workflow-on-merge.yml infrastructure

重命名事件触发器,移除合并检查,使关闭 PR 即可触发取消。

# 修改说明:工作流名称和触发条件
name: Cancel PR Workflows on Close # 原名 "on Merge",现改为 on Close
on:
  pull_request_target:
    types: [closed]permissions:
  actions: writejobs:
  cancel:
    runs-on: ubuntu-latest
    steps:
      - name: Cancel Previous Runs
        # 不再检查 merged == true,关闭即取消

评论区精华

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

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

风险与影响

低风险。变更仅限于 CI 工作流脚本,不涉及业务代码。主要风险是取消逻辑错误导致误取消或漏取消,但通过不同状态下的明确分支避免。

对用户透明;对 CI 维护者,取消行为更符合预期:已关闭的 PR 会自动取消排队运行,不再遗留在队列中。

CI 流程变更 覆盖关闭未合并

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论