Run matrix job on macos and on ubuntu in container

Let’s consider the following workflow:

name: On push

on:
  push:
    branches: master

jobs:
  main:
    strategy:
      matrix:
        os:
          - ubuntu-18.04
          - macos-10.14
    runs-on: ${{ matrix.os }}
    container: linuxbrew/brew
    steps:
      - name: brew config
        run: |
          brew config

Currently the macos job will fail because: “##[error]File not found: ‘docker’”.

What I would want to see is: the macos job would run on macos VM and ubuntu job would run in container.

I know I can workaround this by making 2 separate jobs but I would need to repeat myself and would rather avoid that, granted that this workflow is simple and I can do it easily but it is just an example.

8 Likes

I definitely understand the motivation here.  I’m not sure that just ignoring the container key on macOS runs will necessarily be the solution, but we’ll look at how to simplify this for you so that it’s more DRY.

3 Likes

Just wanted to say this would be very helpful for us as well. Is there anyway currently we can write the yaml so that the container field is included conditionally, only for the linux builds? That would basically solve the issue for us I think.

3 Likes

Yes, the solution here would be for GitHub Actions to allow something like:

container:
  image: debian:stable
  if: matrix.os == ubuntu-latest

for example.

This problem is compounded by the fact that Yaml anchors are not supported - further forcing us to duplicate CI specification code.

1 Like

@pmatos I like your suggestion! It’s concise, clear, explicit, and consistent. @ethomson what do you think?

For the record, I have exactly the same problem and would really enjoy a solution, like what @pmatos suggests!

@ethomson any update on this?

Hi all,
I tried a solution with a matrix job, but ending with a “a step cannot have both the uses and run keys” unfortunately.

The idea was to build this kind of matrix:

matrix:
  - os: debian
    runnner: ubuntu-latest
    uses: docker://gcr.io/crazy-matt/localenv-builder/debian:latest
  - os: redhat
    runnner: ubuntu-latest
    uses: docker://gcr.io/crazy-matt/localenv-builder/redhat:latest
  - os: suse
    runnner: ubuntu-latest
    uses: docker://gcr.io/crazy-matt/localenv-builder/suse:latest
  - os: mac
    runnner: macos-10.14
    uses: 

Working on this implementation:

global_vars:
  runs-on: ubuntu-latest
  outputs:
    matrix: ${{ steps.set_vars.outputs.matrix }}
  steps:
    - uses: actions/checkout@v2
    - id: set_vars
      run: |
        json_array="{\"include\":$(ls -d docker/* | cut -f2 -d'/' | jq --arg repo "docker://ghcr.io/${{ github.repository }}/" --arg tag ":latest" -s -R -c 'split("\n") | to_entries | map( {"os": (.value), "runner": (if .value == "mac" then "macos-10.14" else "ubuntu-latest" end), "uses": (if .value == "mac" then "" else ($repo+.value+$tag) end) })'[:-1])}"
        echo "::set-output name=matrix::$( echo "$json_array" )"

testing:
  runs-on: ${{ matrix.runner }}
  needs: global_vars
  continue-on-error: true
  strategy:
    fail-fast: false
    matrix: ${{ fromJson(needs.global_vars.outputs.matrix) }}
  steps:
    - name: "Running localen-builder for '${{ matrix.os }}'"
      uses: ${{ matrix.uses }}
      run: any_command

The way you build the matrix json depends on your specific needs.

But I couldn’t make it work.
Any news on this @ethomson