You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用嵌套矩阵在GitHub Actions中批量触发任务?求替代方案

问题出在哪?

你当前的read-file任务用了矩阵,会同时跑两个实例分别处理两个JSON文件,但GitHub Actions有个坑——带矩阵的job输出变量时,只会保留最后一个实例的输出。所以check任务最后只拿到第二个文件的2个对象,自然只执行2次。

解决方案一:一次性生成完整对象矩阵(最简洁)

不需要嵌套矩阵,直接在第一个任务里读取所有JSON文件,把所有对象合并成一个数组,生成完整矩阵传给后续任务:

jobs:
  generate-object-matrix:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    steps:
      - uses: actions/checkout@v2
      - id: set-matrix
        run: |
          # 读取所有products下的JSON文件,合并所有数组元素为一个大数组
          ALL_OBJECTS=$(jq -s 'add' products/*.json)
          # 输出符合矩阵要求的格式(外层需要是键值对)
          echo "::set-output name=matrix::{\"objects\": $ALL_OBJECTS}"

  check:
    needs: generate-object-matrix
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        object: ${{ fromJson(needs.generate-object-matrix.outputs.matrix).objects }}
    steps:
      - run: |
          echo "处理对象:"
          echo "名称: ${{ matrix.object.name }}"
          echo "版本: ${{ matrix.object.version }}"
          # 这里替换成你的实际任务逻辑

这个方案会让check任务自动执行4次,每个实例对应一个JSON对象。

解决方案二:嵌套矩阵(通过中间任务收集所有输出)

如果一定要保留“先列文件→再读文件→最后处理对象”的嵌套逻辑,需要加一个任务收集read-file所有实例的输出,再合并成完整矩阵:

jobs:
  list-products:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    steps:
      - uses: actions/checkout@v2
      - id: set-matrix
        run: |
          FILES=$(ls products/*.json | jq -R -s -c 'split("\n")[:-1]')
          echo "::set-output name=matrix::$FILES"

  read-file:
    needs: list-products
    runs-on: ubuntu-latest
    strategy:
      matrix:
        manifest: ${{ fromJson(needs.list-products.outputs.matrix) }}
    outputs:
      objects: ${{ steps.read_file.outputs.contents }}
    steps:
      - uses: actions/checkout@v2
      - id: read_file
        uses: andstor/file-reader-action@v1
        with:
          path: ${{ matrix.manifest }}

  collect-objects:
    needs: read-file
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.collect.outputs.matrix }}
    steps:
      - uses: actions/github-script@v6
        id: collect
        with:
          script: |
            # 获取当前工作流的所有任务实例
            const jobs = await github.rest.actions.listJobsForWorkflowRun({
              owner: context.repo.owner,
              repo: context.repo.repo,
              run_id: context.runId
            });
            # 筛选出read-file的任务实例,提取每个实例的objects输出
            const readFileJobs = jobs.data.jobs.filter(job => job.name === 'read-file');
            let allObjects = [];
            for (const job of readFileJobs) {
              if (job.outputs.objects) {
                const objects = JSON.parse(job.outputs.objects);
                allObjects = allObjects.concat(objects);
              }
            }
            # 返回合并后的矩阵格式
            return {"objects": allObjects};
          result-encoding: json

  check:
    needs: collect-objects
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        object: ${{ fromJson(needs.collect-objects.outputs.matrix).objects }}
    steps:
      - run: |
          echo "处理对象:"
          echo "名称: ${{ matrix.object.name }}"
          echo "版本: ${{ matrix.object.version }}"

这个方案通过collect-objects任务把两个read-file实例的输出合并,最终传给check任务执行4次。

替代方案:单任务循环处理(无需矩阵)

如果不需要并行处理对象,直接在一个任务里循环处理所有对象即可:

jobs:
  process-all-objects:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: |
          # 合并所有JSON文件的对象到一个数组
          ALL_OBJECTS=$(jq -s 'add' products/*.json)
          # 循环遍历每个对象执行任务
          echo "$ALL_OBJECTS" | jq -c '.[]' | while read -r obj; do
            echo "===== 处理当前对象 ====="
            NAME=$(echo "$obj" | jq -r '.name')
            VERSION=$(echo "$obj" | jq -r '.version')
            echo "名称: $NAME"
            echo "版本: $VERSION"
            # 这里添加你的任务逻辑
          done

这个方案不需要矩阵,适合不需要并行执行的场景,一次任务完成所有对象的处理。

内容的提问来源于stack exchange,提问作者Hari Prasath

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 14:50:44