Reputation: 411
I am trying to use if else conditions in Azure Devops yml pipeline with variable groups. I am trying to implement it as per latest Azure Devops yaml pipeline build.
Following is the sample code for the if else condition in my scenario. test is a variable inside my-global variable group.
variables:
- group: my-global
- name: fileName
${{ if eq(variables['test'], 'true') }}:
value: 'product.js'
${{ elseif eq(variables['test'], false) }}:
value: 'productCost.js'
jobs:
- job:
steps:
- bash:
echo test variable value $(fileName)
When the above code is executed, in echo statement we don't see any value for filename, i.e. it empty, meaning none of the above if else condition was executed, however when I test the if else condition with the following condition.
- name: fileName
${{ if eq('true', 'true') }}:
value: 'product.js'
Filename did echo the correct value, i.e. product.js. So my conclusion is that I am not able to refer the variables from the variable group correctly. So any suggestion will be helpful and appreciated. Thanks!
Upvotes: 6
Views: 23681
Reputation: 40533
As of 17.01.2025 you can simplify Tejas solution as ternary operator is available
trigger:
- none
variables:
- group: Temp-group-for-testing
- name: fileName
value: $[ iif(eq(variables['test'], 'true'), 'product.js', 'productCost.js') ]
stages:
- stage: test
jobs:
- job: testvar
continueOnError: false
steps:
- bash: echo $(fileName)
displayName: "echo variable"
And in general you issue here was that values from variable groups are available at runtime, and syntax ${{ }}
is evaluated at compilation time. So your variable was not available at compilation. Syntax $[]
is evaluated at runtime, this more variables are available.
Upvotes: 1
Reputation: 387
A cleaner solution in my opinion is to set the variable to a default value (your "else" case) and then have a set variable step to override that value conditionally (your "if" case).
This is "essentially" an if-else and doesn't feel like a hack or workaround like other answers here.
variables:
# defaults to Testing but conditionally changes to Production if the source branch is release (see below)
Environment: 'Testing'
steps:
- task: VariableSetTask@3
inputs:
variableName: 'Environment'
From: 'value'
value: 'Production'
condition: eq(variables['Build.SourceBranch'],'refs/heads/release')
displayName: 'Set Production Environment'
- script: |
echo Environment: $(Environment)
echo Build Source Branch: $(Build.SourceBranch)
displayName: 'Print Variables'
Upvotes: 1
Reputation: 704
Unfortunately there is no ternary operator in Azure DevOps Pipelines. And it seems unlikely considering the state of https://github.com/microsoft/azure-pipelines-yaml/issues/256 and https://github.com/microsoft/azure-pipelines-yaml/issues/278. So for the time being the only choices are :
Another work-around has been posted by Simon Alling on GitHub (https://github.com/microsoft/azure-pipelines-yaml/issues/256#issuecomment-1077684972) :
format(
replace(replace(condition, True, '{0}'), False, '{1}'),
valueIfTrue,
valueIfFalse
)
It is similar to the solution provided by Tejas Nagchandi, but I find it a little bit better because the syntax looks closer to what it would be if there was a ternary operator.
Upvotes: 5
Reputation: 512
I was able to achieve the goal using some dirty work-around, but I do agree that using parameters would be much better way unless ternary operators are available for Azure DevOps YAML pipeline.
The issue is that ${{ if condition }}:
is compile time expression, thus the variables under variable group are not available.
I was able to use runtime expressions $[<expression>]
Reference: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/expressions?view=azure-devops
My pipeline:
trigger:
- none
variables:
- group: Temp-group-for-testing
- name: fileName
value: $[replace(replace('True',eq(variables['test'], 'True'), 'value1'),'True','value2')]
stages:
- stage: test
jobs:
- job: testvar
continueOnError: false
steps:
- bash: echo $(fileName)
displayName: "echo variable"
Results are available on github
Upvotes: 9
Reputation: 411
After detailed investigation I realized that if else doesnt work with variables in Az Devop yaml pipelines, it only works with parameters. However the solution posted by @Tejas Nagchandi is a workaround and might be able to accomplish the same logic of if else setting variable value with replace commands. Hats off to TN.
Upvotes: 2