Reusable Workflow with Strategy Matrix

Is there a way to use strategy matrix with reusable workflows?

What I’m looking for is something like this:

on:
  workflow_dispatch:

strategy:
  fail-fast: false
  matrix:
    env: [dev, stage, prod]

jobs:
  Reuseable:
    uses: company/repo/.github/workflows/resuable-workflow.yml@main
    with:
      env: ${{ matrix.env }}
13 Likes

Yes, I have an example setup for this. But there’s a rough spot: array is not a supported input type, so you have to use a string. Here’s how it works:

The workflow that defines the matrix:

name: Node.js CI

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  ci:
    uses: waldos-woof/actions-automation/.github/workflows/main.yml@main
    with: 
      versions: "[\"14.x\", \"16.x\"]"

The reusable workflow:

name: Node.js CI

on:
  workflow_call:
    inputs:
      versions:
        description: 'Stringified JSON object listing target Node versions'
        default: '14.x'
        required: false
        type: string

jobs:
  build:

    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: ${{fromJson(inputs.versions)}}

    steps:
    - uses: actions/checkout@v2
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v2
      with:
        node-version: ${{ matrix.node-version }}
    - run: npm ci
    - run: npm run build --if-present
    - run: npm test
7 Likes

I’d like to +1 this for the originally mentioned implementation.

I guess it might be out of the scope of reusable workflows, but what I would really like is to be able to use the matrix strategy with jobs as well as steps. (That in combination with reusable workflows would be super useful)

6 Likes

Got it - thanks for the feedback

7 Likes

Yup, was just about to define a re-usable workflow for a Java project with a matrix build of different distros and versions, with a default that can be overridden. I still can, of course, but the override will have to be in this fromJson form and that means that so will the default. Not the end of the world, but definitely feels like a rough edge.

1 Like

Hello, could I piggyback on this conversation and ask, probably @jenschelkopf if this is a bad code, me not understanding something or something we could in the future see working?

jobs:
  test:
    strategy:
      fail-fast: false
      matrix:
        toolA: [12, 34]
        toolB: [56, 78]
        exclude:
          - toolA: 12
            toolB: 78
    uses: org/repo/.github/workflows/sbt_run_test.yml@develop
    with:
      toolA: ${{ matrix.toolA }}
      toolB: ${{ matrix.toolB }}

I am getting

The workflow is not valid. .github/workflows/test.yml (Line: 34, Col: 5): Unexpected value 'uses' .github/workflows/test.yml (Line: 35, Col: 5): Unexpected value 'with'

@jenschelkopf thank you so much for showing us a workaround.

This is one of those that I feel that GitHub Actions should support such a use case. I would like to know if you are taking into consideration implementing it or if there is a technical limitation that doesn’t allow such a thing.

As soon as I finish my right-after question coming from Elixir (where we support multiple Elixir and Erlang combinations) this is a must-to-have right out of the getgo.

3 Likes

Thank you @jenschelkopf, this solved my problem!

For anybody reading along, this can be made less cumbersome to type using YAML’s multiline strings; as in:

  uses: ...
   with:
      versions: >-
        ["14.x", "16.x"]

Thank you so much again! Brightened my morning. :smiley:

3 Likes