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
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.
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'))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With