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

如何在单个矩阵元素上运行GitHub Actions工作流?

灵活控制GitHub Actions工作流的操作系统运行范围

背景

GitHub Actions中,跨多操作系统运行工作流的标准方式是使用matrix策略:

jobs:
  package:
    strategy:
      matrix:
        os: [ubuntu, macos, windows]
    runs-on: ${{ matrix.os }}-latest

但实际场景中,我们经常需要只在单个操作系统上运行工作流(比如调试阶段,或者仅针对某一OS的代码变更)。直接注释matrix里的元素容易出错,拆分多个工作流又会增加维护复杂度——尤其是存在build->package->deploy这类链式工作流时,每个环节都要做多个变体。

尝试过的方案及问题

1. 下拉选择输入(choice)

尝试通过workflow_dispatch的选择输入指定OS,但多选时会被识别为单个字符串,无法正常解析为matrix数组:

on:
  workflow_dispatch:
    inputs:
      os:
        type: choice
        options:
          - windows
          - macos
          - ubuntu
          - ubuntu, macos, windows
        required: true

jobs:
  package:
    strategy:
      matrix:
        os: "${{ github.event.inputs.os }}"
    runs-on: ${{ matrix.os }}-latest

单个OS选择时正常,但选多个时会把"ubuntu, macos, windows"当作一个OS名称,导致运行失败。

2. 布尔值选择输入

用布尔值勾选要运行的OS,但只能拆分成独立Job,无法复用matrix的优势:

on:
  workflow_dispatch:
    inputs:
      ubuntu:
        required: true
        type: boolean
      macos:
        required: true
        type: boolean
      windows:
        required: true
        type: boolean

jobs:
  ubuntu:
    if: ${{ inputs.ubuntu }} 
    runs-on: ubuntu-latest
    steps: ...
  macos:
    if: ${{ inputs.macos}} 
    runs-on: macos-latest
    steps: ...
  windows:
    if: ${{ inputs.windows}} 
    runs-on: windows-latest
    steps: ...

标准实现方案

方案1:利用fromJSON解析字符串数组

通过选择输入传递数组格式的字符串,再用fromJSON转换为matrix可识别的数组,同时支持单个和多个OS选择:

on:
  workflow_dispatch:
    inputs:
      os:
        type: choice
        options:
          - '["windows"]'
          - '["macos"]'
          - '["ubuntu"]'
          - '["ubuntu", "macos", "windows"]'
        required: true
        default: '["ubuntu", "macos", "windows"]'

jobs:
  package:
    strategy:
      matrix:
        os: ${{ fromJSON(github.event.inputs.os) }}
    runs-on: ${{ matrix.os }}-latest
    steps:
      - name: 示例步骤
        run: echo "运行在 ${{ matrix.os }}"

这种方式既保留了选择输入的便捷性,又能让matrix正确解析OS列表,单个和多选场景都能正常工作。

方案2:结合布尔输入和前置Job生成matrix数组

如果需要更灵活的任意组合选择(而非固定选项),可以先通过一个前置Job根据布尔输入生成OS数组,再传递给后续Job的matrix:

on:
  workflow_dispatch:
    inputs:
      ubuntu:
        type: boolean
        default: true
      macos:
        type: boolean
        default: true
      windows:
        type: boolean
        default: true

jobs:
  generate-matrix:
    runs-on: ubuntu-latest
    outputs:
      os-list: ${{ steps.set-matrix.outputs.os-list }}
    steps:
      - id: set-matrix
        run: |
          OS_LIST=()
          ${{ inputs.ubuntu == 'true' }} && OS_LIST+=("ubuntu")
          ${{ inputs.macos == 'true' }} && OS_LIST+=("macos")
          ${{ inputs.windows == 'true' }} && OS_LIST+=("windows")
          echo "os-list=$(jq -c . <<< "${OS_LIST[@]}")" >> "$GITHUB_OUTPUT"

  package:
    needs: generate-matrix
    strategy:
      matrix:
        os: ${{ fromJSON(needs.generate-matrix.outputs.os-list) }}
    runs-on: ${{ matrix.os }}-latest
    steps:
      - name: 示例步骤
        run: echo "运行在 ${{ matrix.os }}"

这种方式支持任意OS组合选择,同时复用了matrix的优势,避免重复编写Job逻辑。

方案3:支持调用方工作流传递参数

如果需要从其他工作流调用并传递OS参数,可以通过workflow_call的输入定义,结合fromJSON实现:

on:
  workflow_dispatch:
    inputs:
      os:
        type: string
        default: '["ubuntu", "macos", "windows"]'
  workflow_call:
    inputs:
      os:
        type: string
        default: '["ubuntu", "macos", "windows"]'

jobs:
  package:
    strategy:
      matrix:
        os: ${{ fromJSON(inputs.os) }}
    runs-on: ${{ matrix.os }}-latest
    steps:
      - name: 示例步骤
        run: echo "运行在 ${{ matrix.os }}"

调用方工作流可以传递单个OS的字符串数组(如'["ubuntu"]')或多个OS的数组,实现灵活控制。

工作流可重用性优化

对于build->package->deploy这类链式工作流,可以将每个环节封装为可重用的工作流(使用workflow_call),然后在主工作流中通过上述方式生成matrix,再传递给各个子工作流,无需为每个OS组合创建重复的工作流变体。

主工作流示例:

on:
  workflow_dispatch:
    inputs:
      os:
        type: choice
        options:
          - '["windows"]'
          - '["macos"]'
          - '["ubuntu"]'
          - '["ubuntu", "macos", "windows"]'
        required: true

jobs:
  build:
    uses: ./.github/workflows/build.yml
    with:
      os: ${{ inputs.os }}
  package:
    needs: build
    uses: ./.github/workflows/package.yml
    with:
      os: ${{ inputs.os }}
  deploy:
    needs: package
    uses: ./.github/workflows/deploy.yml
    with:
      os: ${{ inputs.os }}

子工作流(如build.yml)示例:

on:
  workflow_call:
    inputs:
      os:
        type: string

jobs:
  build:
    strategy:
      matrix:
        os: ${{ fromJSON(inputs.os) }}
    runs-on: ${{ matrix.os }}-latest
    steps:
      - name: 构建步骤
        run: echo "在 ${{ matrix.os }} 上构建"

这种结构既保证了灵活性,又极大提升了工作流的可维护性和可重用性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 17:05:19