Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unrecognized named-value: 'matrix' in job if conditional #1985

Open
Joe-Kollin opened this issue Jul 7, 2022 · 16 comments
Open

Unrecognized named-value: 'matrix' in job if conditional #1985

Joe-Kollin opened this issue Jul 7, 2022 · 16 comments
Labels
bug Something isn't working

Comments

@Joe-Kollin
Copy link

Describe the bug
A job generates a matrix as an output and I have a subsequent job that depends on the generation of that matrix. The first job does an API call to get all customers which each have a unique schema association. I only want to run this second job in the event that my input SCHEMA array contains the schema of a given return record. However, when I execute the build I get the following error: Unrecognized named-value: 'matrix'. Located at position 26 within expression: contains(inputs.SCHEMAS, matrix.customer.schema). The pattern works without the conditional, but does not fit my use case.

This is a rough idea of what the job looks like.

job-name:
  runs-on: ubuntu-latest
  needs: get-customers
  if: contains(inputs.SCHEMAS, matrix.customer.schema)
  strategy:
    matrix:
      customer: ${{fromJson(needs.get-customers.outputs.customers)}}
  steps:
     ....

Expected behavior
The job should only run when the matrix schema is contained within the input SCHEMA

Runner Version and Platform

ubuntu-latest

What's not working?

The use of matrix in a job level conditional

@Joe-Kollin Joe-Kollin added the bug Something isn't working label Jul 7, 2022
@alexandrebrg
Copy link

I had the same issue, it seems that if statement is evaluated before running a matrix of jobs. I found this topic on GitHub forum about this problem.

@funes79
Copy link

funes79 commented Sep 29, 2022

I do have the same issue, and not using any if statement. And the matrix value does not contain any spaces.

  list-dev-configs:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    steps:
      - uses: actions/checkout@v3
      - id: set-matrix
        run: echo "::set-output name=matrix::[\"A\",\"B\"]"
  check:
    needs: list-dev-configs
    runs-on: ubuntu-latest
    strategy:
        matrix:
            dev_config: ${{ fromJSON(needs.list-dev-configs.outputs.matrix) }}
    steps:
      - uses: actions/checkout@v3   
      - run: |
          echo "${{ needs.list-dev-configs.outputs.matrix }}"
          echo "${{ fromJSON(needs.list-dev-configs.outputs.matrix) }}"
          echo "${{ martix.dev_config }}"

@funes79
Copy link

funes79 commented Sep 30, 2022

My bad, that was a typo in the script last line martix instead of matrix.

@korewaChino
Copy link

Also having this issue. the workflow works fine if there was no if statement.

  build:
    needs: manifest
    strategy:
      matrix: ${{ fromJson(needs.manifest.outputs.build_matrix) }}

    uses: andaman-common-pkgs/github-actions/.github/workflows/anda-rpm.yml@main
    if: ${{ matrix.changed_folders != '' }}
    with:
      name: "rust/${{ matrix.changed_folders }}/pkg"
      subatomicServer: "https://subatomic.fyralabs.com"
      subatomicRepo: ad37
      mockConfig: anda-37-x86_64
      mockConfigPackage: anda-mock-configs
      upload: true
    secrets:
      subatomicToken: ${{ secrets.SUBATOMIC_TOKEN }}

@carmocca
Copy link

carmocca commented Oct 8, 2022

I also have this problem in Lightning-AI/pytorch-lightning#15043

@jsoref
Copy link
Contributor

jsoref commented Oct 12, 2022

You can probably work around this by having additional jobs that generate outputs and relying on needs and the outputs from those jobs.

You might need to demote your ifs from job level to step level.

@garciasdos
Copy link

Same problem here. Are there any plans to add the matrix context to the jobs.<job_id>.if condition?

@mrkesu
Copy link

mrkesu commented Nov 29, 2022

I'm also encountering this issue.

Sadly my workflow had to be changed from this:

jobs:
  remediate:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        env: ["dev", "test", "prod"]
    if: ${{ github.event.schedule || matrix.env == github.event.inputs.env }}
    environment: ${{ matrix.env }}
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - uses: cue-lang/setup-cue@v1.0.0-alpha.2
        with:
      [ etc... ]

to this:

jobs:
  remediate:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        env: ["dev", "test", "prod"]
    environment: ${{ matrix.env }}
    steps:
      - name: Checkout
        if: ${{ github.event.schedule || matrix.env == github.event.inputs.env }}
        uses: actions/checkout@v2
      - uses: cue-lang/setup-cue@v1.0.0-alpha.2
        if: ${{ github.event.schedule || matrix.env == github.event.inputs.env }}
        with:
      [ etc... ]

Obviously with a few more steps than in the above truncated example.

It makes the whole workflow feel a bit messy, especially since the jobs are being marked as successfully run when in reality all the steps within it have been skipped.

(never mind my failed job, it's still in development😅)
image

@jsoref
Copy link
Contributor

jsoref commented Nov 29, 2022

@mrkesu: if you're up for it, you should really try having a job that creates your matrix and then have it create an empty array when you don't want it to do work. #1985 (comment)

Here's a workflow which does something similar:
https://github.com/commercialhaskell/stack/blob/71a85a488ef458d5c7d315b647411056aafd3d0a/.github/workflows/integration-tests.yml#L104-L127

caendesilva added a commit to hydephp/hyde that referenced this issue Jan 3, 2023
Seems like matrix values are not supported in conditionals here actions/runner#1985
@markstijnman-shell
Copy link

I ran into this issue today as well. Can the matrix context indeed be added to jobs.<job_id>.if ? I would imagine that if it is available for runs-on, it should be possible to make it available for jobs.<job_id>.if too, as I would expect both are evaluated before starting the job.

My use case is in reusable workflows, where I also want to reuse my matrix for several projects, However, there are projects who don't need all configurations. So I want to allow the calling workflow to use input parameters to skip certain matrix entries. For example, I would very much like something like this to work, which would allow the calling workflow to control whether to build for win32:

on:
  workflow_call:
    inputs:
      build-win32:
        required: true
        type: boolean
      
jobs:
  build:
    strategy:
      matrix:
        include:
          - os: windows-latest
            arch: "win64"
            build: true
          - os: windows-latest
            arch: "win32"
            build: ${{ inputs.build-win32 }}
          - os: ubuntu-latest
            build: true
        
    if: ${{ matrix.build }}
    runs-on: ${{ matrix.os }}

I've seen workarounds that use a separate job to set up a matrix, but that solution is (1) much harder to understand than this one, and (2) will introduce an extra job in your output that is just noise.

tommie added a commit to tommie/innernet-debian that referenced this issue May 12, 2023
@pawamoy
Copy link

pawamoy commented May 15, 2023

It's indeed a bit surprising to get this error when seeing that runs-on works just fine with it:

    runs-on: ${{ matrix.os }}  # ok
    if: ${{ matrix.os == 'ubuntu-latest' }}  # not ok

@pawamoy
Copy link

pawamoy commented Jun 2, 2023

Here is the most elegant solution I found to this issue:

jobs:
  exclude-jobs:
    runs-on: ubuntu-latest
    outputs:
      jobs: ${{ steps.exclude-jobs.outputs.jobs }}
    steps:
    - id: exclude-jobs
      # 1. use any other condition(s) that fits your requirements
      # 2. each item in the JSON array will be matched against your matrix later
      # 3. here I exclude everything except ubuntu-latest + python3.7 (see matrix below)
      # 4. make sure to output as single line
      # 5. the default case is: exclude nothing
      run: |
        if ${{ github.repository_owner == 'pawamoy-insiders' }}; then  # 1
          # 2, 3
          echo 'jobs=[
            {"os": "macos-latest"},
            {"os": "windows-latest"},
            {"python-version": "3.8"},
            {"python-version": "3.9"},
            {"python-version": "3.10"},
            {"python-version": "3.11"}
          ]' | tr -d '[:space:]' >> $GITHUB_OUTPUT  # 4
        else
          echo 'jobs=[]' >> $GITHUB_OUTPUT  # 5
        fi

  tests:
    needs: exclude-jobs
    strategy:
      matrix:
        os:
        - ubuntu-latest
        - macos-latest
        - windows-latest
        python-version:
        - "3.7"
        - "3.8"
        - "3.9"
        - "3.10"
        - "3.11"
        # simply use the previous JSON data you echoed to exclude jobs
        exclude: ${{ fromJSON(needs.exclude-jobs.outputs.jobs) }}

@Gustl22
Copy link

Gustl22 commented Apr 6, 2024

Thanks @pawamoy that worked for me, in order to use a one dimensional set of inputs and rather use include:

jobs:
  include-jobs:
    runs-on: ubuntu-latest
    outputs:
      jobs: ${{ steps.include-jobs.outputs.jobs }}
    steps:
      - id: include-jobs
        run: |
          includeJobs='
            ${{ inputs.enable_web && '{"platform": "web", "os": "ubuntu-latest", "build-type": "web"},' || '' }}
            ${{ inputs.enable_android && '{"platform": "android", "os": "ubuntu-latest", "build-type": "apk"},' || '' }}
            ${{ inputs.enable_ios && '{"platform": "ios", "os": "macos-latest", "build-type": "ipa"},' || '' }}
          '
          # Remove last ',' with ::-1
          echo "jobs=[${includeJobs::-1}]" | tr -d '[:space:]' >> $GITHUB_OUTPUT

  build-client:
    needs: include-jobs
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        include: ${{ fromJSON(needs.include-jobs.outputs.jobs) }}

@excitoon
Copy link

excitoon commented Apr 27, 2024

@pawamoy @Gustl22 You can also do it this way:

jobs:
  ReuseableMatrixJobForDeployment:
    strategy:
      matrix:
        target: [dev, stage, prod]
    uses: ./.github/workflows/base.yml
    with:
      target: ${{ matrix.target }}

Inside nested job if will work again.

https://docs.github.com/en/actions/using-workflows/reusing-workflows#using-a-matrix-strategy-with-a-reusable-workflow

@deannagarcia
Copy link

I just ran into this issue. As others pointed out, it seems unintuitive that runs-on can access the matrix but if can't. Both proposed workarounds (moving ifs to steps or creating a new job to make the matrix) add a lot of unneeded complexity.

Any chance we could see this be added?

@Sivakajan-tech
Copy link

The 3rd example in the Repo should be useful in conditionally build the matrix in the GitHub Actions.
https://github.com/dorny/paths-filter?tab=readme-ov-file#examples

babichjacob added a commit to babichjacob/ac-qu-ai-nt that referenced this issue Oct 5, 2024
…pile and upload, so copying and pasting instead unfortunately until actions/runner#1985 is fixed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests