Matrix Exclude does not work with Pipeline Parameters

If you pass a pipeline parameter to matrix.exclude, it does not function properly.

Consider the following minimum example:

version: 2.1

parameters:
  skip: { type: string, default: "test" }
    
workflows:
  version: 2
  infra:
    jobs:
      - test:
          type: approval
      - other:
          type: approval
          name: << matrix.name >>
          matrix:
            alias: the-matrix
            parameters: 
              name: [test, other, thing]
            exclude:
            - name: test
      - bug:
          type: approval
          requires: [test, other, thing]

In this case, Circle sees this config as valid, since the duplicate “test” job is removed by the matrix exclude.
Config file at .circleci/config.yml is valid.

If we replace the string "test" with << pipeline.parameters.skip >> (whose value is equal to test), I would expect the file to still be valid, since the duplicate test job is being filtered out from the matrix by the exclude in the same way.

version: 2.1

parameters:
  skip: { type: string, default: "test" }
    
workflows:
  version: 2
  infra:
    jobs:
      - test:
          type: approval
      - other:
          type: approval
          name: << matrix.name >>
          matrix:
            alias: the-matrix
            parameters: 
              name: [test, other, thing]
            exclude:
            - name: << pipeline.parameters.skip >>
      - bug:
          type: approval
          requires: [test, other, thing]

However, instead we now get:

Error: Job 'bug' requires 'test', which is the name of 2 other jobs in workflow 'infra'
You can give a job within a workflow an explicit name by adding a name key

Expected Behaviour
I would expect these two configs to be equivalent, and equally valid.

Related (similar issue but the other way around, where the matrix parameters are populated by pipeline parameters):

In both cases, it seems the pipeline parameters are simply not substituted when evaluating the matrix.

1 Like

Thank you for all of the info! This level of detail makes me very happy. I’m going to pass it along to the team!

1 Like

Update: This is a known issue. The most summarized version of this is that the feature works this way by design.

The actual functionality of using a pipeline parameter to exclude a matrix job has no workaround, but depending on what you’re trying to accomplish with the functionality, there may be an alternative. For example, simply not using the matrix feature and explicitly adding each matrix job to the config.

I hope that helps, and as always, if you have further feedback, let me know!

Thanks for the response and suggested workarounds!

So as far as I understand it, it behaves this way as a result of the way the underlying system is designed (as opposed to it being “designed” to behave this way intentionally?).

It would be great if this could be fixed - it’s particularly useful for those of us who are trying to eke out some extra dynamicity from our Circle workflows.


The main pushback I’d give in terms of considering this a “bug” rather than a “feature” is the fact that the behaviour is inconsistent.

For a given matrix:

matrix:
  parameters:
    example:
      - << pipeline.parameters.example_01 >>
      - << pipeline.parameters.example_02 >>
  exclude:
    - example: << pipeline.parameters.example_02 >>

Why should the pipeline parameters substitution work semi-correctly for the matrix parameters, but not for the matrix exclude?

1 Like

That totally makes sense. I will add this feedback to the discussion we have internally so we have more data points. Thank you for pointing this out :grinning: