skip to Main Content

I’m new to GitHub Actions so I don’t quite have the Googlefu to solve my problem

Simplifying, I have something like

jobs:
  test_run_a:
    uses: ./.github/workflows/test.yml
    with:
      param: "A"
    secrets: inherit

in the other file test.yml I have

name: test

on:
  workflow_call:
    inputs:
      param:
          required: true
          type: string

jobs:
  unit-test:
    timeout-minutes: 60
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest]
    runs-on: ${{ matrix.os }}
    steps: ...

so currently, all jobs that use test.yml run on ubuntu and mac. I would like to make it so that it is the outer job (in this case test_run_a) that defines the OS matrix.

Basically, I would like to make it so that job test_run_a runs on both OS, and I can define another test_run_b that runs only on mac, with both of them using the shared job code in test.yml

I have tried to move the strategy out into the outer job, but it does not work. Thank you in advance

2

Answers


  1. Chosen as BEST ANSWER

    Thanks to @licvdom I was able to get it working, with the help of this link: https://github.com/orgs/community/discussions/11692#discussioncomment-3541856

    You have to do

    strategy:
          fail-fast: false
          matrix:
            os: ${{ fromJson(input.systems) }}
        runs-on: ${{ matrix.os }}
    

    and call it with

    systems: "['ubuntu-latest', 'macos-latest']"
    

    The double quotes and single quotes are critical, you are basically formatting a JSON as a string, GitHub Actions won't let you pass a list as a param so you have to pass a string and convert it.


  2. So, probably the simplest solution would be to add another parameterized input (let’s call it systems and annotate it with a description) to the test.yml file:

    name: test
    on:
      workflow_call:
        inputs:
          param:
              required: true
              type: string
          systems:
              required: true
              description: "A comma-separated string with the desired os"
              type: string
    
    jobs:
      unit-test:
        timeout-minutes: 60
        strategy:
          fail-fast: false
          matrix:
            os: [ '${{ inputs.systems }}' ]
        runs-on: ${{ matrix.os }}
        steps: ...
    
    
    

    and then you can define the desired systems from your consuming workflow:

    jobs:
      test_run_a:
        uses: ./.github/workflows/test.yml
        with:
          param: "A"
          systems: "ubuntu-latest, macos-latest"
        secrets: inherit
    

    You can check more examples of this pattern on GitHub Docs: Workflow syntax for GitHub Actions

    If you want to take it a step further, you could look into creating a composite action so that you can reuse the workflow across different repositories. Cheers

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search