You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在外部测试失败时阻止PR合并并获取结果通知

更优实现方案推荐

方案一:基于GitHub Checks API的回调式触发(首选)

这个方案无需创建GitHub App,仅通过GitHub Actions+API回调即可实现,完美解决长时间测试的资源占用问题,同时满足阻止PR合并+结果通知的需求。

核心逻辑

  1. 分支保护锁死合并条件:给目标分支branchB设置分支保护规则,要求必须通过指定的检查项才能合并。
  2. Action触发外部任务并标记pending状态:PR创建/同步时,触发GitHub Action,调用外部工具API启动测试任务,同时通过GitHub Checks API创建一个pending状态的检查项(与分支保护规则要求的名称一致),随后Action直接结束,无需持续运行。
  3. 外部工具回调更新检查状态:配置外部工具,在测试任务完成后(成功/失败/中断),调用GitHub Checks API更新检查项的状态为success/failure/cancelled,同时附上测试结果详情。
  4. 自动通知:GitHub会自动在检查状态变更时,向PR作者、评审人发送通知,无需额外配置。

具体实现步骤

1. 设置分支保护规则

  • 进入仓库Settings > Branches > Branch protection rules,针对branchB创建规则:
    • 勾选「Require status checks to pass before merging」
    • 添加检查项名称(比如External Long-Running Test),后续Action和外部工具都要使用这个名称。

2. 编写GitHub Action工作流(触发外部任务)

创建.github/workflows/trigger-external-test.yml:

name: Trigger External Long-Running Test
on:
  pull_request:
    branches: [branchB]
    types: [opened, synchronize]

permissions:
  checks: write # 赋予操作Checks API的权限

jobs:
  trigger-test:
    runs-on: ubuntu-latest
    steps:
      - name: Create external test task
        id: create-task
        run: |
          # 调用外部工具API创建测试任务,替换成实际的API地址和参数
          TASK_RESPONSE=$(curl -X POST https://your-external-tool/api/tasks \
            -H "Authorization: Bearer ${{ secrets.EXTERNAL_TOOL_TOKEN }}" \
            -d '{"branchA": "${{ github.head_ref }}", "branchB": "${{ github.base_ref }}", "pr_number": ${{ github.event.number }} }')
          # 解析出任务ID,假设返回的JSON里有task_id字段
          TASK_ID=$(echo $TASK_RESPONSE | jq -r '.task_id')
          echo "task_id=$TASK_ID" >> $GITHUB_OUTPUT

      - name: Create pending check run
        run: |
          gh api repos/${{ github.repository }}/check-runs \
            -X POST \
            -f name="External Long-Running Test" \
            -f head_sha="${{ github.head_sha }}" \
            -f status="pending" \
            -f output='{"title":"External Test in Progress","summary":"Long-duration test is running, please wait for completion..."}'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

3. 配置外部工具的回调逻辑

当外部测试任务完成时,调用GitHub Checks API更新检查状态:

# 替换以下变量为实际值
OWNER="你的仓库所属组织/个人"
REPO="仓库名称"
CHECK_RUN_NAME="External Long-Running Test"
HEAD_SHA="PR头分支的提交SHA" # 可以在创建任务时传给外部工具
TEST_RESULT="success" # 或failure/cancelled
TEST_DETAILS="测试通过,耗时3小时20分"

# 先查询对应的检查运行ID
CHECK_RUN_ID=$(gh api repos/$OWNER/$REPO/check-runs \
  -f name=$CHECK_RUN_NAME \
  -f head_sha=$HEAD_SHA \
  | jq -r '.check_runs[0].id')

# 更新检查状态
gh api repos/$OWNER/$REPO/check-runs/$CHECK_RUN_ID \
  -X PATCH \
  -f status="completed" \
  -f conclusion="$TEST_RESULT" \
  -f output='{"title":"External Test Completed","summary":"'"$TEST_DETAILS"'"}'

注意:外部工具需要持有具有checks:write权限的GitHub令牌(可以用仓库令牌或个人访问令牌PAT)。

方案优势

  • 无需长时间运行GitHub Action,避免资源浪费和超时风险(GitHub Action默认超时6小时,虽可调整但没必要)
  • 逻辑清晰,依赖GitHub原生能力,稳定性高
  • 无需创建GitHub App,仅需简单的API调用即可实现

方案二:改进版轮询方案(备选)

如果外部工具不支持回调,可以采用定时轮询的方式,但需优化资源占用:

  1. 初始Action创建外部任务后,将任务ID存储在GitHub Secrets或仓库的临时文件(比如task-id.txt提交到临时分支)
  2. 创建另一个定时触发的Action(比如每30分钟运行一次),读取任务ID,轮询外部工具的任务状态
  3. 一旦获取到最终结果,立即更新PR的检查状态,随后停止轮询(可通过删除任务ID标记实现)

这个方案比原始轮询更高效,但仍不如回调方案灵活,仅适用于外部工具无法配置回调的场景。

内容的提问来源于stack exchange,提问作者guilhermecgs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 17:37:09