Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reference an Azure DevOps matrix variable, inside an expression?

Tags:

azure-devops

I'm trying to figure out how to access an Azure DevOps matrix variable, in a compile time expression. The reference value is always null/empty/missing. Like the variable hasn't been set.

here's a sample yml file I was trying:


jobs:
- job: LinuxBuild
  displayName: Pew Pew
  strategy:
    matrix:
      debugJob:
        buildConfiguration: Debug
      releaseJob:
        buildConfiguration: Release
  pool:
    vmImage: 'ubuntu-16.04'

 steps:
  - script: echo ${{variables.debugJob.buildConfiguration}} ## <-- always null/empty

  - script: echo ${{variables['debugJob.buildConfiguration']}}  ## <-- always null/empty

  - ${{ if eq(variables.debugJob.buildConfiguration, 'Debug') }}: ## <-- never ran/executed
    - template: doSomething.yml@templates
like image 845
Pure.Krome Avatar asked Apr 07 '20 11:04

Pure.Krome


People also ask

How do I reference a variable group in Azure DevOps?

Use a variable group Then, variables from the variable group can be used in your YAML file. To reference a variable group, use macro syntax or a runtime expression. In the following example, the group my-variable-group has a variable named myhello . You can reference multiple variable groups in the same pipeline.


Video Answer


1 Answers

For keywords Matrix, it is used to expand the multi-configs into multiple runtime jobs. In another word, the YAML which contain the Matrix keywords will be expanded at runtime instead of parse time. So, the variable buildConfiguration is a runtime variable, and it is not available at compile time, also can not be get then.

Also, ${{ }} is a format which to process the variables at compile time.

Now, there's no doubt to know that the issue you met is a expected action since you are trying to get a runtime variable at compile time.


So, to print out the value of buildConfiguration, you need use the format of $()

Change your YAML script to this:

jobs:
- job: LinuxBuild

  displayName: Pew Pew
  strategy:
    matrix:
      debugJob:
        buildConfiguration: Debug
      releaseJob:
        buildConfiguration: Release
  pool:
    vmImage: 'ubuntu-16.04'

  steps:
  - script: echo $(buildConfiguration) 

  - script: echo "hello"
    condition: and(succeeded(), eq(variables.buildConfiguration, 'Debug'))

Now, let's focus on the another try you made: - ${{ if eq(variables.debugJob.buildConfiguration, 'Debug') }}:.

Firstly, you need know that ${{ if xxx }}, this is a template expression which processed at compile time. This means, the system will go parsing the value then decide whether next steps/jobs/templates should be ran. This process are happen before pipeline run. We call that initial step.

As I mentioned above, buildConfiguration is a runtime variable. It only available at run time. So, its value could not be get at compile time. In compile time, its value will be parsed into null. This is why you template never be ran.

There has 2 work arounds you can consider to make this condition true.

1) Change to use another variable in condition, the one which can available at both compile time and run time. e.g Build.SourceBranchName.

2) Split the condition and change them into the tasks' condition which defined in template yml file.

Like:

  - script: echo "hello"
    condition: and(succeeded(), eq(variables.buildConfiguration, 'Debug'))
like image 117
Mengdi Liang Avatar answered Oct 22 '22 12:10

Mengdi Liang