如何让GitHub第3个Workflow在第2个所有Pipeline完成后仅触发一次
解决方案
核心思路
给同一次由W1触发的所有W2运行实例打上统一标识,通过跟踪该标识下所有W2实例的完成状态,在全部完成后触发W3。
具体实现步骤
1. W1生成批次标识并传递给W2
在W1中生成唯一批次ID(比如时间戳+随机字符串),触发W2的HTTP请求时,将这个ID作为workflow_dispatch的输入参数传递。
示例W1触发逻辑:
- name: 生成唯一批次ID id: create_batch_id run: echo "batch_id=$(date +%s)-$RANDOM" >> $GITHUB_OUTPUT - name: 触发5个W2批次任务 run: | for batch_num in {1..5}; do curl -X POST \ -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ -H "Accept: application/vnd.github.v3+json" \ https://api.github.com/repos/[你的仓库名]/actions/workflows/[W2的yaml文件名].yaml/dispatches \ -d '{"ref":"main","inputs":{"batch_id":"${{ steps.create_batch_id.outputs.batch_id }}","batch_number":"'$batch_num'"}}' done
2. W2完成后检查同批次任务状态
在W2的收尾步骤中,通过GitHub API查询当前批次ID下的所有W2运行实例,若全部完成则触发W3。
示例W2检查逻辑:
- name: 检查同批次所有任务是否完成 if: success() run: | # 查询当前批次下已完成的W2任务数量 completed_count=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ "https://api.github.com/repos/[你的仓库名]/actions/workflows/[W2的yaml文件名].yaml/runs?status=completed&per_page=100" | \ jq --arg target_id "${{ inputs.batch_id }}" '[.workflow_runs[] | select(.inputs.batch_id == $target_id)] | length') # 若完成数量等于总批次(5),触发W3 if [ "$completed_count" -eq 5 ]; then curl -X POST \ -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ -H "Accept: application/vnd.github.v3+json" \ https://api.github.com/repos/[你的仓库名]/actions/workflows/[W3的yaml文件名].yaml/dispatches \ -d '{"ref":"main","inputs":{"batch_id":"${{ inputs.batch_id }}"}}' fi
3. 可选:用独立监控Workflow替代W2内检查
如果不想在每个W2中重复执行检查逻辑,可让W1在触发5个W2后,同时启动一个监控Workflow。该Workflow循环查询批次任务状态,全部完成后触发W3。
示例监控Workflow核心代码:
on: workflow_dispatch: inputs: batch_id: required: true total_batches: required: true type: number jobs: monitor_batches: runs-on: ubuntu-latest steps: - name: 循环等待所有批次完成 run: | while true; do # 查询当前批次下成功完成的W2任务数量 success_count=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ "https://api.github.com/repos/[你的仓库名]/actions/workflows/[W2的yaml文件名].yaml/runs?status=completed&per_page=100" | \ jq --arg target_id "${{ inputs.batch_id }}" '[.workflow_runs[] | select(.inputs.batch_id == $target_id and .conclusion == "success")] | length') if [ "$success_count" -eq "${{ inputs.total_batches }}" ]; then echo "所有批次任务完成,触发W3" curl -X POST \ -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ -H "Accept: application/vnd.github.v3+json" \ https://api.github.com/repos/[你的仓库名]/actions/workflows/[W3的yaml文件名].yaml/dispatches \ -d '{"ref":"main","inputs":{"batch_id":"${{ inputs.batch_id }}"}}' exit 0 fi echo "已完成 $success_count/${{ inputs.total_batches }} 个任务,1分钟后重试" sleep 60 done
关键注意事项
- 确保
GITHUB_TOKEN拥有仓库操作权限(仓库内默认的GITHUB_TOKEN已具备该权限)。 - 可根据需求调整触发W3的条件:若需所有W2成功才触发,保留
conclusion == "success"过滤;若只要完成(无论成败),则移除该过滤。 - 批次ID需保证唯一性,避免不同W1触发的批次互相干扰。
内容的提问来源于stack exchange,提问作者subbareddy
相关产品推荐
相关产品推荐

