variablescontinuous-integrationenvironment-variablesgithub-actions

GitHub Actions: Use variables in matrix definition?


I have the following code in a GitHub Action config:

name: Build & Tests

on:
  pull_request:

env:
  CARGO_TERM_COLOR: always
  ZEROCOPY_MSRV: 1.61.0
  ZEROCOPY_CURRENT_STABLE: 1.64.0
  ZEROCOPY_CURRENT_NIGHTLY: nightly-2022-09-26

jobs:
  build_test:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        # See `INTERNAL.md` for an explanation of these pinned toolchain
        # versions.
        channel: [ ${{ env.ZEROCOPY_MSRV }}, ${{ env.ZEROCOPY_CURRENT_STABLE }}, ${{ env.ZEROCOPY_CURRENT_NIGHTLY }} ]
        target: [ "i686-unknown-linux-gnu", "x86_64-unknown-linux-gnu", "arm-unknown-linux-gnueabi", "aarch64-unknown-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc64-unknown-linux-gnu", "wasm32-wasi" ]
        features: [ "" , "alloc,simd", "alloc,simd,simd-nightly" ]
        exclude:
          # Exclude any combination which uses a non-nightly toolchain but
          # enables nightly features.
          - channel: ${{ env.ZEROCOPY_MSRV }}
            features: "alloc,simd,simd-nightly"
          - channel: ${{ env.ZEROCOPY_CURRENT_STABLE }}
            features: "alloc,simd,simd-nightly"

I'm getting the following parsing error on this file:

Invalid workflow file: .github/workflows/ci.yml#L19
You have an error in your yaml syntax on line 19

It appears to be referring to this line (it's actually one off, but maybe it's zero-indexing its line numbers?):

channel: [ ${{ env.ZEROCOPY_MSRV }}, ${{ env.ZEROCOPY_CURRENT_STABLE }}, ${{ env.ZEROCOPY_CURRENT_NIGHTLY }} ]

Is there any way to use variables in the matrix definition like this? Or do I just need to hard-code everything?


Solution

  • According to the documentation (reference 1 and reference 2)

    Environment variables (at the workflow level) are available to the steps of all jobs in the workflow.

    In your example, the environment variables are used at the job level (inside the job strategy / matrix definition), not inside the job steps.

    At that level, environment variables aren't interpolated by the GitHub interpreter.


    First alternative

    Hardcode the values inside the channel field inside your matrix strategy:

    Example:

    channel: [ "1.61.0", "1.64.0", "nightly-2022-09-26" ]
    

    However, you'll have to do this for each job (bad for maintenance as duplicated code).

    Second alternative

    Use inputs (with reusable workflow workflow_call trigger, or with workflow_dispatch trigger.

    Example:

    on:
      workflow_dispatch: # or workflow_call
        inputs:
          test1:
            description: "Test1"
            required: false
            default: "test1"
          test2:
            description: "Test2"
            required: false
            default: "test2"
          test3:
            description: "Test3"
            required: false
            default: "test3"
    
    jobs:
      build_test:
        runs-on: ubuntu-latest
        strategy:
          matrix:
            channel: [ "${{ inputs.test1 }}", "${{ inputs.test2 }}", "${{ inputs.test3 }}" ]
    

    In that case, inputs will be interpolated by the GitHub interpreter.

    However, you'll need to trigger the workflow from another workflow, or through the GitHub API to send the inputs (in some way, it gives you more flexibility with the values, but increase the complexity).