Proposal: Matrix Nesting

Here I have a C++ build workflow which is typical for many C++ projects: https://github.com/iboB/word-grid/blob/master/.github/workflows/build.yml

In it I start various flavors of the build:
* gcc on unbuntu-latest debug and release: 2 jobs

* clang on ubuntu-latest and mac-latest debug and release: 4 jobs

* msvc on windows debug and release, 32 and 64 bit: 4 jobs

Note that the steps in each task are almost the same. It’s easy to make them entirely the same but due to the limitations of the matrix, they have to be copy pasted. I know I can use matrix.include and matrix.exclude but in such cases the include/exclude lines would surpass the step lines. A much simpler solution for this would be to allow a form of matrix nesting. Here’s my suggested syntax: Allow matrix elements to be objects where the key id is the input value and other keys are nested matrices. With this such matrix would be possible:

runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        compiler:
        - id: gcc
          os: [ubuntu-latest]
          build-type: [Debug, Release]
        - id: clang
          os: [ubuntu-latest, macos-latest]
          build-type:
          - id: Debug
            sanitize: [true, false]
          - id: Release
        - id: msvc
          os: [windows-latest]
          build-type: [Debug, Release]
          arch: [Win32, x64]

So this will generate the following input combinations

compiler: gcc, os: ubuntu-latest, build-type: Debug, sanitize: <empty>, arch: <empty>
compiler: gcc, os: ubuntu-latest, build-type: Release, sanitize: <empty>, arch: <empty>
compiler: clang, os: ubuntu-latest, build-type: Debug, sanitize: true, arch: <empty>
compiler: clang, os: ubuntu-latest, build-type: Debug, sanitize: false, arch: <empty>
compiler: clang, os: ubuntu-latest, build-type: Release, sanitize: <empty>, arch: <empty>
compiler: clang, os: macos-latest, build-type: Debug, sanitize: true, arch: <empty>
compiler: clang, os: macos-latest, build-type: Debug, sanitize: false, arch: <empty>
compiler: clang, os: macos-latest, build-type: Release, sanitize: <empty>, arch: <empty>
compiler: msvc, os: windows-latest, build-type: Debug, sanitize: <empty>, arch: Win32
compiler: msvc, os: windows-latest, build-type: Debug, sanitize: <empty>, arch: x64
compiler: msvc, os: windows-latest, build-type: Release, sanitize: <empty>, arch: Win32
compiler: msvc, os: windows-latest, build-type: Release, sanitize: <empty>, arch: x64

and have identical steps that rely on those inputs below.

I’m sure many C and C++ projects would have similar needs as C and C++ are noteworthy for the platofrm and compiler-specific build flavors

5 Likes

That would be a killer feature for C/C++ projects!

It’s already here, if you’re willing to write such list by hand instead of taming matrix. And if you use cmake -P script (or anything like that) to deal with environment and running your build (instead of doing it in workflow), your setup becomes dead simple and easy to run in another CI or locally.

1 Like

Ooh, it’s nice that I can at least write the expanded list by hand. Didn’t know that.

Still, it would be much better (less error prone and easier to deal with) if we could have the atomatic expansion from something like my suggestion above or similar