如何聚合GitHub Actions矩阵策略执行的最终状态?
GitHub Actions矩阵任务状态聚合实现方案
下面是三种可行的实现方式,适配你的Terraform多目录扫描场景:
方法一:利用Job输出与依赖汇总(推荐)
核心思路是让矩阵任务允许失败(continue-on-error: true),并输出各自的执行状态,最后用一个汇总Job依赖所有矩阵任务,遍历判断整体状态。
示例配置:
name: Terraform Scan & Plan on: [push] jobs: matrix-tasks: runs-on: ubuntu-latest continue-on-error: true # 允许单个任务失败,不中断整个工作流 strategy: matrix: target: [workdir, network, app] outputs: status: ${{ steps.set-status.outputs.status }} target: ${{ matrix.target }} steps: - name: Checkout code uses: actions/checkout@v4 - name: Run Terraform Plan & Static Scan id: run-tasks run: | # 执行你的Terraform plan和静态扫描命令 cd ${{ matrix.target }} terraform init terraform plan -out=plan.tfplan # 假设静态扫描工具是trivy,示例命令 trivy config . continue-on-error: true - name: Set task status id: set-status run: | if [ "${{ steps.run-tasks.outcome }}" == "success" ]; then echo "status=success" >> $GITHUB_OUTPUT else echo "status=failure" >> $GITHUB_OUTPUT fi aggregate-status: runs-on: ubuntu-latest needs: matrix-tasks steps: - name: Check all task statuses run: | # 遍历所有矩阵任务的输出 declare -a failures=() for i in "${!needs.matrix-tasks.outputs.status[@]}"; do target="${needs.matrix-tasks.outputs.target[$i]}" status="${needs.matrix-tasks.outputs.status[$i]}" echo "Task for $target: $status" if [ "$status" == "failure" ]; then failures+=("$target") fi done # 判断是否有失败任务 if [ ${#failures[@]} -gt 0 ]; then echo "Failed tasks: ${failures[*]}" exit 1 # 汇总Job失败,整个工作流标记为失败 else echo "All tasks succeeded" exit 0 fi
方法二:通过Artifact记录状态文件
每个矩阵任务执行后,将状态写入文件并上传为Artifact,汇总Job下载所有文件后统一判断。
示例配置:
name: Terraform Scan & Plan on: [push] jobs: matrix-tasks: runs-on: ubuntu-latest continue-on-error: true strategy: matrix: target: [workdir, network, app] steps: - name: Checkout code uses: actions/checkout@v4 - name: Run Terraform Plan & Static Scan id: run-tasks run: | cd ${{ matrix.target }} terraform init terraform plan -out=plan.tfplan trivy config . continue-on-error: true - name: Write status file run: | echo "${{ steps.run-tasks.outcome }}" > status-${{ matrix.target }}.txt - name: Upload status artifact uses: actions/upload-artifact@v4 with: name: task-statuses path: status-${{ matrix.target }}.txt if-no-files-found: error aggregate-status: runs-on: ubuntu-latest needs: matrix-tasks steps: - name: Download status artifacts uses: actions/download-artifact@v4 with: name: task-statuses path: ./statuses - name: Check all statuses run: | failures=0 for file in ./statuses/*.txt; do target=$(basename "$file" | sed 's/status-\(.*\)\.txt/\1/') status=$(cat "$file") echo "$target: $status" if [ "$status" != "success" ]; then failures=$((failures+1)) fi done if [ $failures -gt 0 ]; then echo "$failures tasks failed" exit 1 else echo "All tasks succeeded" exit 0 fi
方法三:使用GitHub CLI查询Job状态
在汇总Job中调用GitHub API,获取当前工作流的所有Job状态,过滤矩阵任务后判断。
示例配置:
name: Terraform Scan & Plan on: [push] jobs: matrix-tasks: runs-on: ubuntu-latest continue-on-error: true strategy: matrix: target: [workdir, network, app] steps: - name: Checkout code uses: actions/checkout@v4 - name: Run Terraform Plan & Static Scan run: | cd ${{ matrix.target }} terraform init terraform plan -out=plan.tfplan trivy config . continue-on-error: true aggregate-status: runs-on: ubuntu-latest needs: matrix-tasks steps: - name: Install GitHub CLI run: sudo apt-get install gh -y - name: Authenticate GitHub CLI run: echo "${{ secrets.GITHUB_TOKEN }}" | gh auth login --with-token - name: Check matrix task statuses run: | # 获取当前工作流的所有Job jobs=$(gh api repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/jobs --jq '.jobs[] | select(.name | contains("matrix-tasks"))') failures=$(echo "$jobs" | jq -r '.conclusion' | grep -v "success" | wc -l) if [ $failures -gt 0 ]; then echo "$failures matrix tasks failed" exit 1 else echo "All matrix tasks succeeded" exit 0 fi
内容的提问来源于stack exchange,提问作者wehelpdox
相关产品推荐
相关产品推荐

