Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Paired values in github actions matrix

I want to build against three compiler versions for a C and C++ project: gcc, gcc-8 and clang (for the C compiler), which should use g++, g++-8 and clang++ respectively for the C++ compiler.

That's 3 configurations total. I won't want to build with the product of all C and C++ compiler versions, i.e,. no gcc/g++-8, etc.

How can I specify a matrix with those three configurations, each which sets two variables?

Currently I'm using this (note that 2 OSes are specified, so it's 6 configs in total):

    strategy:
      matrix:
        os: [ubuntu-16.04, ubuntu-latest]
        cpp_compiler: [g++, g++-8, clang++]
        include:
          - c_compiler: gcc
          - cpp_ompiler: g++-8
            c_compiler: gcc-8
          - cpp_compiler: clang++
            c_compiler: clang

Essentially, the C++ compiler (cpp_compiler) is used as the master version, and then include is used in a hacky way to set c_compiler based on the cpp_compiler version, but there must be something better...

like image 577
BeeOnRope Avatar asked Feb 03 '21 10:02

BeeOnRope


People also ask

How do I use matrix actions in GitHub?

A matrix strategy lets you use variables in a single job definition to automatically create multiple job runs that are based on the combinations of the variables. For example, you can use a matrix strategy to test your code in multiple versions of a language or on multiple operating systems.

How do I run jobs sequentially in GitHub Actions?

To run jobs sequentially, you can define dependencies on other jobs using the jobs. <job_id>. needs keyword. Each job runs in a runner environment specified by runs-on .

Do GitHub Actions jobs run in parallel?

You can configure a GitHub Actions workflow to be triggered when an event occurs in your repository, such as a pull request being opened or an issue being created. Your workflow contains one or more jobs which can run in sequential order or in parallel.

Can you CD in GitHub Actions?

With GitHub Actions, you can trigger CI/CD workflows and pipelines of webhooks from these apps (even something simple, like a chat app message, if you've integrated your chat app into your GitHub repository, of course).


2 Answers

Besides @jidicula's answer, which stores matrix as an array, you can also store it as a map, this will make the workflow more readable.

So the following workflow should work prettier:

# simplified

strategy:
  matrix:
    os: [ubuntu-16.04, ubuntu-latest]
    compiler: [ {cpp: g++, c: gcc}, {cpp: g++-8, c: gcc-8}, {cpp: clang++, c: clang} ]
steps:
  - name: Compile with C++ compiler
    run: ${{ matrix.compiler.cpp }} source.cpp
  - name: Compile with C compiler
    run: ${{ matrix.compiler.c }} source.c

When this workflow is triggered, it will execute 6 times in parallel with different matrix.

1: matrix.os == ubuntu-16.04, matrix.compiler.cpp == g++, matrix.compiler.c == gcc
2: matrix.os == ubuntu-16.04, matrix.compiler.cpp == g++-8, matrix.compiler.c == gcc-8
3: matrix.os == ubuntu-16.04, matrix.compiler.cpp == clang++, matrix.compiler.c == clang
4: matrix.os == ubuntu-latest, matrix.compiler.cpp == g++, matrix.compiler.c == gcc
5: matrix.os == ubuntu-latest, matrix.compiler.cpp == g++-8, matrix.compiler.c == gcc-8
6: matrix.os == ubuntu-latest, matrix.compiler.cpp == clang++, matrix.compiler.c == clang

However, whether it is an array or a map, the syntax is currently undocumented, though as of a certain point in time the syntax checker no longer flags it as an error. So all of this may change in the future.

like image 80
Sprite Avatar answered Oct 19 '22 01:10

Sprite


I just tried this out and it turns out you can nest arrays in a build matrix, but it's undocumented. Therefore, you can create an array of arrays of compilers in your job.matrix. Let's call it compiler-version: compiler-version: [[g++, gcc], [g++-8, gcc-8], [clang++, clang]]. Then you can access each value in each element of the compiler-version array with zero-indexing: matrix.compiler-version[0] for the C++ compiler, and matrix.compiler-version[1] its C counterpart.

Your workflow would become:

    strategy:
      matrix:
        os: [ubuntu-16.04, ubuntu-latest]
        compiler-version: [[g++, gcc], [g++-8, gcc-8], [clang++, clang]]
    steps:
      # .... checkout steps
      - name: Compile file with C++ compiler
        env:
          COMPILER: ${{ matrix.compiler-version[0] }}
        run: |
          $COMPILER file.c
          ./a.out
      - name: Compile file with C compiler
        env:
          COMPILER: ${{ matrix.compiler-version[1] }}
        run: |
          $COMPILER file.c
          ./a.out

I've worked up a minimal example with a matrix of 2 Python versions and 2 Ubuntu versions, where 3.7 is paired with Ubuntu-18.04, and 3.8 is paired with Ubuntu-20.04. You can see the workflow file here and its corresponding run here.

This solution gets around the awkwardness of having to define your C++ options in 2 places in the workflow file. Even though it's undocumented, I assume it's stable since GitHub Actions context objects are (or at least are treated like) JavaScript objects, so we're really just defining array literals as the matrix object attributes and accessing their values.

like image 13
jidicula Avatar answered Oct 19 '22 01:10

jidicula