如何监控并行GitHub Actions工作流,实现双工作流成功后启用合并按钮
核心问题分析
你当前的两个工作流并行运行,但合并按钮在任意一个工作流完成后就启用,本质是因为两个工作流的状态是独立的,且没有强制关联彼此的成功状态。由于没有分支保护权限,无法通过设置必填检查来约束,所以需要从工作流本身的依赖逻辑入手,让两个工作流的成功状态绑定。
方案1:让主工作流统一管控子工作流(推荐,无额外复杂度)
这个方案通过取消子工作流的独立触发,仅由主工作流调用,确保主工作流的成功必须依赖子工作流的完成,从而让PR的合并条件等价于两个工作流都成功。
步骤1:修改子工作流的触发规则
编辑pull-request-ready-workflow.yml,移除原有的on: pull_request触发,只保留workflow_call(用于被主工作流调用):
on: workflow_call: # 若子工作流需要接收参数,可在此定义,例如: # inputs: # environment: # type: string # required: true
步骤2:调整主工作流的依赖逻辑
确保主工作流中调用子工作流的pull-request-ready-check job是主工作流的最终依赖项之一。如果主工作流还有其他核心任务,可让它们与子工作流并行,最后通过一个汇总job确保所有任务完成:
name: Main Pull Request Workflow on: pull_request jobs: setup: runs-on: ubuntu-latest steps: - name: Setup environment run: echo "Setup completed" validate: needs: setup runs-on: ubuntu-latest steps: - name: Validate code run: echo "Validation completed" # 主工作流的核心业务任务,与子工作流并行 main-business-jobs: needs: validate runs-on: ubuntu-latest steps: - name: Run main business tasks run: echo "Main tasks completed" # 调用子工作流,与main-business-jobs并行(若不需要依赖setup/validate,可去掉needs) pull-request-ready-check: name: Pull request ready check if: github.event.pull_request.draft == false # 若不需要依赖setup/validate,可删除此行,实现完全并行 needs: [setup, validate] uses: ./.github/workflows/pull-request-ready-workflow.yml secrets: inherit # 汇总job,确保主任务和子工作流都成功 final-approval: name: Final combined approval needs: [main-business-jobs, pull-request-ready-check] runs-on: ubuntu-latest steps: - name: All workflows succeeded run: echo "Both main workflow and ready check workflow passed"
这样,主工作流只有在main-business-jobs和pull-request-ready-check(子工作流)都成功后,才会标记为整体成功。PR的合并按钮只会在主工作流成功后启用,等价于两个工作流都完成且成功。
方案2:工作流间交叉检查状态(适合必须保留双工作流独立触发的场景)
如果必须让两个工作流都由PR事件独立触发,可在每个工作流中添加一个检查job,等待并验证另一个工作流的成功状态,从而让两个工作流的成功互相绑定。
主工作流添加检查子工作流的job
在主工作流末尾添加以下job:
check-sub-workflow-status: name: Verify sub workflow success runs-on: ubuntu-latest needs: [setup, validate] steps: - name: Install GitHub CLI run: sudo apt-get install gh -y - name: Wait for sub workflow to complete and verify success env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SUB_WORKFLOW_NAME: "Pull request ready check" HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: | # 获取当前PR关联的子工作流最新运行ID RUN_ID=$(gh api repos/${{ github.repository }}/actions/runs \ --method GET \ --field event=pull_request \ --field head_sha="$HEAD_SHA" \ --field name="$SUB_WORKFLOW_NAME" \ --jq '.workflow_runs[0].id') if [ -z "$RUN_ID" ]; then echo "Error: Sub workflow not found for this PR" exit 1 fi # 轮询等待子工作流完成 while true; do STATUS=$(gh api repos/${{ github.repository }}/actions/runs/$RUN_ID --jq '.status') if [ "$STATUS" = "completed" ]; then break fi echo "Sub workflow is still running, waiting 30s..." sleep 30 done # 检查子工作流是否成功 CONCLUSION=$(gh api repos/${{ github.repository }}/actions/runs/$RUN_ID --jq '.conclusion') if [ "$CONCLUSION" != "success" ]; then echo "Sub workflow failed with status: $CONCLUSION" exit 1 fi echo "Sub workflow succeeded"
子工作流添加检查主工作流的job
在子工作流末尾添加类似的job,将SUB_WORKFLOW_NAME替换为主工作流的名称即可。
这样,只有当两个工作流都成功完成,各自的检查job才会通过,从而整个工作流标记为成功。PR的合并按钮需要两个工作流都成功才会启用。
内容的提问来源于stack exchange,提问作者Prashant Raghav

