如何在GitHub Actions中当某一并行Job失败时终止其他Job?
在GitHub Actions中实现并行Job失败时终止其他Job
GitHub Actions本身没有内置的跨Job终止机制,要实现「任一并行Job失败时立即终止另一个」的需求,需要借助GitHub REST API来主动取消运行中的Job,具体配置方案如下:
完整配置示例
name: Parallel Test Workflow on: [push, pull_request] # 必须赋予取消Job的权限 permissions: actions: write jobs: Unit: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: 后台监控Integration Job状态 run: | while true; do # 获取当前Workflow运行ID WORKFLOW_RUN_ID=${{ github.run_id }} # 查询Integration Job的状态和结果 INTEGRATION_JOB_INFO=$(gh api repos/${{ github.repository }}/actions/runs/$WORKFLOW_RUN_ID/jobs | jq -r '.jobs[] | select(.name == "Integration") | "\(.status)|\(.conclusion)"') STATUS=$(echo "$INTEGRATION_JOB_INFO" | cut -d'|' -f1) CONCLUSION=$(echo "$INTEGRATION_JOB_INFO" | cut -d'|' -f2) # 若Integration Job已失败,立即终止当前Job if [ "$STATUS" = "completed" ] && [ "$CONCLUSION" = "failure" ]; then echo "Integration测试已失败,终止Unit测试..." exit 1 fi sleep 10 done & env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: 运行单元测试 run: | # 替换成你的实际单元测试命令,比如 pytest、npm test 等 npm test - name: 若Unit测试失败,取消Integration Job if: failure() run: | WORKFLOW_RUN_ID=${{ github.run_id }} # 获取Integration Job的ID INTEGRATION_JOB_ID=$(gh api repos/${{ github.repository }}/actions/runs/$WORKFLOW_RUN_ID/jobs | jq -r '.jobs[] | select(.name == "Integration") | .id') # 取消目标Job(仅当Job存在时执行) if [ -n "$INTEGRATION_JOB_ID" ]; then gh api --method POST repos/${{ github.repository }}/actions/jobs/$INTEGRATION_JOB_ID/cancel echo "已取消运行中的Integration Job" fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} Integration: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: 后台监控Unit Job状态 run: | while true; do WORKFLOW_RUN_ID=${{ github.run_id }} UNIT_JOB_INFO=$(gh api repos/${{ github.repository }}/actions/runs/$WORKFLOW_RUN_ID/jobs | jq -r '.jobs[] | select(.name == "Unit") | "\(.status)|\(.conclusion)"') STATUS=$(echo "$UNIT_JOB_INFO" | cut -d'|' -f1) CONCLUSION=$(echo "$UNIT_JOB_INFO" | cut -d'|' -f2) if [ "$STATUS" = "completed" ] && [ "$CONCLUSION" = "failure" ]; then echo "Unit测试已失败,终止Integration测试..." exit 1 fi sleep 10 done & env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: 运行集成测试 run: | # 替换成你的实际集成测试命令 npm run test:integration - name: 若Integration测试失败,取消Unit Job if: failure() run: | WORKFLOW_RUN_ID=${{ github.run_id }} UNIT_JOB_ID=$(gh api repos/${{ github.repository }}/actions/runs/$WORKFLOW_RUN_ID/jobs | jq -r '.jobs[] | select(.name == "Unit") | .id') if [ -n "$UNIT_JOB_ID" ]; then gh api --method POST repos/${{ github.repository }}/actions/jobs/$UNIT_JOB_ID/cancel echo "已取消运行中的Unit Job" fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
关键说明
权限配置
必须在Workflow开头添加permissions: actions: write,因为取消Job需要修改GitHub Actions的运行状态,默认的GITHUB_TOKEN没有该权限,需显式赋予。双向监控与取消
- 每个Job启动一个后台进程,每隔10秒查询另一个Job的状态,一旦发现对方失败就立即终止自身。
- 当当前Job失败时,执行取消另一个Job的操作,避免对方继续占用资源。
工具依赖
Ubuntu系统的GitHub Actions Runner默认已预装gh(GitHub CLI)和jq(JSON解析工具),无需额外安装。注意事项
- 确保Job名称与脚本中
select(.name == "XXX")的名称完全一致,否则无法匹配到目标Job。 - API状态同步存在几秒延迟,无法做到完全实时终止,但能有效减少不必要的资源浪费。
- 确保Job名称与脚本中
内容的提问来源于stack exchange,提问作者margherita pizza
相关产品推荐
相关产品推荐

