Reputation: 162
I am attempting to use the if condition to execute a block of operations but it doesn't seem to be working for me. I'm not entirely sure if I understand the if condition correctly, but this is how I have been using it - or at least a simplified version of it.
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
name: MyTest-$(date:yyyyMMdd)$(rev:.r)
trigger: none
resources:
- repo: self
clean: false
fetchDepth: 2
variables:
- group: TestVG
- name: EnableSigning
value: true
- name: SignDebugBuilds
value: false
stages:
- stage: Stage_Build
displayName: Build Stage
dependsOn: []
jobs:
- job: Job_Build
displayName: Build Job
condition: succeeded()
dependsOn: []
pool:
vmImage: 'windows-latest'
variables:
BuildPlatform: AnyCPU
strategy:
matrix:
Debug:
BuildConfiguration: Debug
Retail:
BuildConfiguration: Retail
steps:
- template: param-test.yml
parameters:
Value: 'Build Solution 1'
#- script: echo 'Build Solution 1'
- ${{ if and(eq(variables['EnableSigning'], True), or(ne(variables['BuildConfiguration'], 'Debug'), eq(variables['SignDebugBuilds'], True))) }}:
#- script: echo 'Build Solution 2 IF check'
- template: param-test.yml
parameters:
Value: 'Build Solution 2 IF check'
- script: echo 'Build Solution 2 COND check'
condition: and(eq(variables['EnableSigning'], True), or(ne(variables['BuildConfiguration'], 'Debug'), eq(variables['SignDebugBuilds'], True)))
The param-test.yml file is a simple file to echo a line for logging/debugging purposes.
parameters:
Value: string
steps:
- script: echo '${{ parameters.Value }}'
My expectation was that for the debug build I would see the first log and the other 2 logs would get skipped, while all 3 logs would be printed for retail build.
However, what I see is that for the debug build, the first and second logs are printed, while only the 3rd log is skipped (the one with the explicit condition in the script step), while all 3 logs are printed for retail build.
To clarify a few items, I used the 3rd log as a control to check if the condition was correct or not. And this is a highly simplified version of the actual pipeline that I have in our repo. We have a primary pipeline YAML file where all the variables are declared including the EnableSigning and SignDebugBuilds. This calls a template file passing in the EnableSigning and SignDebugBuilds flags to the same. This happens a few times around with subtemplates, till one of the sub-templates, the one responsible for the build, uses these from the parameters in the if check. In the actual pipeline, I have the condition use parameters instead of variables, but the result is still the same.
I have looked at a few documentation but it wasn't very clear as to what we could expect from the if statement. And since template tags don't support an explicit condition that we can pass in, this seems to be the only option aside from maintaining 2 separate versions of the template files corresponding to the flags
Upvotes: 0
Views: 6669
Reputation: 1152
In your current situation, the 'if' keyword cannot get the variables['BuildConfiguration']
, because this variable is created when the job is running. And 'if' key word needs to use the runtime parameters.
So, every time the job is running, the result of the variables['BuildConfiguration']
under the 'if' keyword is NULL. Because when the job is init, this variable has not been created. This variable will be created when the job is running and then the pipeline will help you create other two jobs under your job.
At present the work around is to split the matrix to different two jobs and use the parameters to instead of the variables. Here is the demo I create:
name: MyTest-$(date:yyyyMMdd)$(rev:.r)
trigger: none
resources:
- repo: self
clean: false
fetchDepth: 2
parameters:
- name: EnableSigning
type: boolean
displayName: 'EnableSigning'
default: true
- name: SignDebugBuilds
type: boolean
displayName: 'SignDebugBuilds'
default: false
variables:
# - group: TestVG
# - name: EnableSigning
# value: true
# - name: SignDebugBuilds
# value: false
- name: system.debug
value: true
stages:
- stage: Stage_Build
displayName: Build Stage
dependsOn: []
jobs:
- job: Build_Job_Debug
pool:
# vmImage: 'windows-latest'
name: default
variables:
BuildPlatform: AnyCPU
BuildConfiguration: Debug
steps:
- template: param-test.yml
parameters:
Value: 'Build Solution 1'
- ${{ if and(eq(parameters.EnableSigning, true), eq(parameters.SignDebugBuilds, true))}}:
- template: param-test.yml
parameters:
Value: 'Build Solution 2 IF check'
- script: echo 'Build Solution 2 COND check and BuildConfiguration is $(BuildConfiguration)'
name: 'CMD3_check'
condition: eq('${{ parameters.EnableSigning }}', true)
- job: Build_Job_Retail
pool:
# vmImage: 'windows-latest'
name: default
variables:
BuildPlatform: AnyCPU
BuildConfiguration: Retail
steps:
- template: param-test.yml
parameters:
Value: 'Build Solution 1'
- ${{ if or(eq(parameters.EnableSigning, true), eq(parameters.SignDebugBuilds, false))}}:
- template: param-test.yml
parameters:
Value: 'Build Solution 2 IF check'
- script: echo 'Build Solution 2 COND check and BuildConfiguration is $(BuildConfiguration)'
name: 'CMD3_check'
condition: eq('${{ parameters.EnableSigning }}', true)
Also, if you need to use the variable BuildConfiguration
, you can also define it under the different job.
Upvotes: 3