如何在GitHub Actions单Job内实现步骤的循环执行?
如何在GitHub Actions单Job里实现类似矩阵的步骤循环?
问题描述
我有个处理新版本发布的GitHub Actions工作流,最后要给不同平台构建应用。不想搞多个对应不同平台的步骤,也不想用一个步骤塞多条命令,想找个按数组项循环执行单个步骤的方式。我知道Job级别的矩阵策略,所以写了伪代码展示需求:
jobs: do_it: runs-on: ubuntu-latest steps: - name: For each entry in the array... strategy: matrix: target: [ this, that, something ] run: echo ${{ matrix.target }}
请问能不能实现这种类似矩阵的步骤循环?另外我知道有类似问题,但不想拆成多个Job,因为处理大量构建产物太麻烦。
解决方案
GitHub Actions本身没提供步骤级的矩阵配置,但可以在单Job里用两种方式凑出类似循环执行步骤的效果:
方法1:用actions/github-script动态执行循环步骤
用actions/github-script遍历目标数组,给每个平台单独执行构建命令,每个平台的构建过程会分组显示,体验接近矩阵步骤:
jobs: do_it: runs-on: ubuntu-latest steps: - name: 为每个目标平台构建 uses: actions/github-script@v6 with: script: | # 定义要构建的目标平台数组 const targets = ['this', 'that', 'something']; # 逐个遍历执行构建命令 for (const target of targets) { core.startGroup(`构建平台: ${target}`); # 把这里的echo换成你的实际构建命令 await exec.exec(`echo 正在构建 ${target}`); core.endGroup(); }
这种方式不用拆分Job,所有构建都在同一个runner里完成,产物直接共享,不用额外传文件。每个平台的日志单独分组,查起来方便。
方法2:用YAML锚点+循环生成独立步骤
要是你希望每个平台的构建在GitHub Actions界面里显示成单独的步骤项,可以结合YAML锚点和fromJSON表达式批量生成步骤:
jobs: do_it: runs-on: ubuntu-latest env: # 把目标数组转成JSON字符串存到环境变量里 TARGETS: '["this", "that", "something"]' steps: # 定义步骤模板的锚点 - &build-step name: 构建平台 ${{ item }} run: echo 正在构建 ${{ item }} # 要是需要,还能加env、needs这类配置 # 生成对应每个平台的步骤配置 - name: 生成构建步骤 id: generate-steps uses: actions/github-script@v6 with: script: | const targets = JSON.parse(process.env.TARGETS); return targets.map(target => ({ ...steps['build-step'], name: steps['build-step'].name.replace('${{ item }}', target), run: steps['build-step'].run.replace('${{ item }}', target) })); result-encoding: json # 执行生成的所有构建步骤 - name: 执行构建 uses: actions/github-script@v6 with: script: | const steps = ${{ steps.generate-steps.outputs.result }}; for (const step of steps) { core.startGroup(step.name); await exec.exec(step.run); core.endGroup(); }
这种方式会在界面里给每个平台显示单独的步骤名称,视觉上更像矩阵Job的效果,同时所有操作都在同一个Job里完成,不用处理跨Job的产物问题。
内容的提问来源于stack exchange,提问作者baitendbidz
相关产品推荐
相关产品推荐

