如何在GitHub复用工作流中提取矩阵构建各元素的步骤输出?
解决GitHub矩阵构建的输出收集与后置检查问题
核心问题原因
你没法直接在同一个deploy job里拿到所有矩阵实例的状态,因为每个矩阵项都是独立运行的job实例,steps.XXX.outcome只能在当前实例内部访问。要收集所有实例的状态并执行后置检查,得靠Job输出 + 依赖Job的组合来实现。
具体配置修改
1. 修改deploy Job,添加输出
先给每个矩阵实例配置输出,把需要的状态/结果传递出去:
jobs: deploy: strategy: matrix: jdk: [8, 11, 14] # 用户输入的JDK版本 runs-on: [self-hosted] # 定义该Job的输出,供后续Job调用 outputs: jdk-version: ${{ matrix.jdk }} build-outcome: ${{ steps.build-step.outcome }} # 如果复用的工作流有自定义输出,比如构建产物路径,可追加 # build-result: ${{ steps.build-step.outputs.result }} steps: - name: Checkout Repo uses: actions/checkout@v3 - name: Build id: build-step # 给步骤加ID,方便引用输出 uses: abc_workflow@v1 with: java-version: ${{ matrix.jdk }}
这里的关键是给Build步骤添加id,然后在Job的outputs中定义要传递的内容——包括矩阵的JDK版本、步骤的执行结果(success/failure/skipped),如果复用的abc_workflow本身暴露了输出参数,也可以一起捕获。
2. 新增后置检查Job
添加一个依赖于所有deploy矩阵实例的Job,等所有实例跑完后,统一收集并处理状态:
post-build-checks: runs-on: [self-hosted] needs: deploy # 等待所有deploy矩阵实例执行完成 steps: - name: 遍历所有矩阵构建状态 run: | # 将needs.deploy转成JSON后,用jq解析遍历每个实例的输出 echo '${{ toJson(needs.deploy) }}' | jq -c '.[]' | while read job; do JDK=$(echo "$job" | jq -r '.outputs.jdk-version') OUTCOME=$(echo "$job" | jq -r '.outputs.build-outcome') echo "JDK $JDK 构建结果: $OUTCOME" # 如果有自定义输出,可在这里打印 # RESULT=$(echo "$job" | jq -r '.outputs.build-result') # echo "JDK $JDK 构建输出: $RESULT" done - name: 执行失败检查与处理 if: ${{ contains(needs.deploy.*.outputs.build-outcome, 'failure') }} run: | echo "发现至少一个JDK版本构建失败,启动后续处理..." # 这里写你的自定义逻辑,比如发送通知、生成失败报告等
关键细节说明
needs: deploy会自动等待所有矩阵实例完成,无论成功失败;如果只需要在全成功时运行检查,可追加if: success()。needs.deploy是一个数组,包含每个矩阵实例的输出和执行状态,用toJson()转成JSON后,可通过jq工具解析遍历。- 若不需要遍历,仅需判断是否存在失败实例,直接用
contains(needs.deploy.*.outputs.build-outcome, 'failure')即可快速校验。
补充:复用工作流无输出的处理方案
如果abc_workflow没有暴露输出参数,你可以在Build步骤后手动捕获状态:
- name: 捕获构建状态 id: capture-status if: always() # 无论前面步骤成功失败都执行 run: | if [ "${{ steps.build-step.outcome }}" = "success" ]; then echo "build-status=success" >> $GITHUB_OUTPUT else echo "build-status=failure" >> $GITHUB_OUTPUT fi
之后在Job的outputs中引用steps.capture-status.outputs.build-status即可。
内容的提问来源于stack exchange,提问作者new_bie
相关产品推荐
相关产品推荐

