I'm trying to use the build number of the pipeline in a conditional to determine which task to run.
Inspired by this example in the ADO expressions FAQ, I set a variable to the minor number of the build number:
- script: |
minor_run=$(echo $BUILD_BUILDNUMBER | cut -d '.' -f2)
echo "Minor run number: $minor_run"
echo "##vso[task.setvariable variable=minor]$minor_run"
This prints out the correct minor number, let's say Minor run number: 14 for the following examples.
If I want to print out the minor, I can do it like this
script: "echo $minor"
Now I want to use this in a conditional. I'm trying something like this:
- ${{ if eq(variables.minor, 14) }}:
- script: "echo first if worked"
- ${{ elseif eq(variables['minor'], 14) }}:
- script: "echo second if worked"
- ${{ else }}:
- script: "echo neither worked"
I always get to the else part. I have tried evaluating against '14' as well, but same result.
I have also tried evaluating $minor, $(minor), and just minor, but that causes the pipeline to fail entirely.
What's the correct way to use a defined variable in a conditional?
I see you set two conditions all to minor value '14'. Then you could use condition to set two scenarios when minor value is 14 and not.
You could use condition syntax as this.
steps:
- bash: |
MAJOR_RUN=$(echo $BUILD_BUILDNUMBER | cut -d '.' -f1)
echo "This is the major run number: $MAJOR_RUN"
echo "##vso[task.setvariable variable=major]$MAJOR_RUN"
MINOR_RUN=$(echo $BUILD_BUILDNUMBER | cut -d '.' -f2)
echo "This is the minor run number: $MINOR_RUN"
echo "##vso[task.setvariable variable=minor]$MINOR_RUN"
- script: "echo first if worked"
condition: eq(variables.minor, 8)
- script: "echo neither worked"
condition: ne(variables.minor, 8)
Test on my side, if you want to use if syntax, you need to set specific value in pipeline variables part like this.
I hope this could do some help.
Related
I have declared a variable group "myVariableGroup" and inside this I have a variable name "myVariable" with default value = true.
Pipeline looks like this
I declared the group variable name in variables
first step, I debug the result of myVariable, working fine, I get the value true
second step, I pass the variable to a template parameter
variables:
- group: myVariableGroup
steps:
- script: "echo myVariableFROM group vars = $(myVariable)"
displayName: debug groupvars
- template: "./.azure-devops/some-template.yml"
parameters:
myVariableParam: $(myVariable)
Template looks like this
parameter declared with default value false
debug the parameter value, result being true (it works)
I'm using an if statement to determine if the bash script should run or not, but this is not working
parameters:
- name: myVariableParam
type: boolean
default: false
- script: "echo parameters.myVariableParam = ${{ parameters.myVariableParam}}"
displayName: debug parameters.myVariableParam
- ${{ if eq(parameters['myVariableParam'], true) }}:
- script: "echo parameters.myVariableParam= ${{ parameters.myVariableParam}}"
Questions:
Is it possible to use group variables inside if statements or the IF is interpreted before running the pipeline and value is not defined?
The only way to achieve this is via conditions? I have a corner case where I don't really want to use those
Maybe I miss something pretty obvious and can anybody help me with this?
Based on the #Alex's comments, updated the template to use condition.
I know this seems a bit hacky but if doesn't seem to be evaluated properly when using with boolean. See this answer for details
parameters:
myVariableParam: 'false'
steps:
- script: |
echo "##vso[task.setvariable variable=myVariableNew;]$myVariableEnv"
displayName: setting myVariableNew to parameter.myVariableParam
env:
myVariableEnv: ${{parameters['myVariableParam']}}
- script: |
echo "myVariableNew: $(myVariableNew)"
displayName: check myVariableNew
- script: |
echo "I should run when myVariableNew is $(myVariableNew)"
condition: eq(variables['myVariableNew'], 'true')
myVariable set to true
myVariable set to false
I am working on Azure DevOps YAML Pipelines and trying to do something like -
if project = proj1 or project = proj2:
run some commands.
if project = proj3:
run some other commands.
Snippet of code:
- ${{ if or(eq(parameters.project, 'proj1'), eq(parameters.project, 'proj2')) }}: # 1st if
- bash: |
echo "Hello"
name: hello
- ${{ if eq(parameters.project, 'proj3') }}: # 2nd if
- bash: |
echo "Hi"
name: hi
Now, I have been using 2nd if conditions for quite some time and that is working flawlessly. The issue is with 1st if condition. Even when correct parameter is passed, the control wont go into that code block.
I tested this with following code:
parameters:
- name: project
type: string
default: proj1
values:
- proj1
- proj2
- proj3
trigger: none
steps:
- ${{ if or(eq(parameters.project, 'proj1'), eq(parameters.project, 'proj2')) }}: # 1st if
- bash: |
echo "Hello"
name: hello
- ${{ if eq(parameters.project, 'proj3') }}: # 2nd if
- bash: |
echo "Hi"
name: hi
and it works as expected. Can you explain how you setp values for project?
In September 2021 Azure DevOps Service update, we have a new syntax for the same and it's better to use that.
Explaining that with my original example -
- ${{ if or(eq(parameters.project, 'proj1'), eq(parameters.project, 'proj2')) }}: # if
- bash: |
echo "Hello"
name: hello
- ${{ elseif eq(parameters.project, 'proj3') }}: # elseif
- bash: |
echo "Hi"
name: hi
- ${{ else }}: # else
- bash: |
echo "Hey"
name: hey
The advantage over previous syntax is that instead of expanding and comparing if condition every time, this will short circuit on first true match and only move to elseif or else if all previous conditions are false.
It might also help in speeding up the pipeline (some fraction of a second).
I have completely migrated my pipelines to new syntax. Microsoft may/may not discontinue old syntax in near future so it is advised to migrate to new one.
I have a YAML file which forms an Azure DevOps pipeline. The pipeline itself defines four variables which are needed in the variables section of the YAML...
variables:
environmentIdentifier: "$(environmentIdentifier)"
keyVaultSourceName: "$(keyVaultSourceName)"
location: "$(location)"
locationIdentifier: "$(locationIdentifier)"
The variables are definitely set for each run of the pipeline, but when it runs I encounter errors further down in my script which indicate that these variables were not populated correctly...
ERROR: (InvalidResourceGroup) The provided resource group name 'rg-main-$(locationIdentifier)' has these invalid characters: '$:'. The name can only be a letter, digit, '-', '.', '(', ')' or '_'.
I've also tried...
$env:location
${{variables['location']}}
...but incurred the same error.
How should I correctly declare vars in the variables section of the pipeline definition, where their values are retrieved from the pipeline's variables?
You need to define as:
variables:
- name: location
value: 'Australia Southeast'
If you want them at a later stage as a template expression use:
${{ variables.location }}
and if you want to use them inside a script:
steps:
- bash: echo $(location)
- powershell: echo $(location)
- script: echo $(location)
Check this Link and the below extracted sample for more information.
variables:
- name: one
value: initialValue
steps:
- script: |
echo ${{ variables.one }} # outputs initialValue
echo $(one)
displayName: First variable pass
- bash: echo '##vso[task.setvariable variable=one]secondValue'
displayName: Set new variable value
- script: |
echo ${{ variables.one }} # outputs initialValue
echo $(one) # outputs secondValue
displayName: Second variable pass
It seems that name is a special magic variable that somehow gets used for my output directory.
(Is this behavior documented anywhere?)
I'm trying to set it.
Given the extraordinary difficulty of writing Azure pipeline yml, it's highly unlikely that I'll get it right. In the absence of any form of debugging I want to add a print statement so that I can see the value.
How?
${{ if eq(variables['Build.SourceBranchName'], 'master') }}:
buildConfiguration: 'Release'
tag: ''
${{ if ne(variables['Build.SourceBranchName'], 'master') }}:
buildConfiguration: 'Debug'
tag: ${{ format('-{0}', variables['Build.SourceBranchName']) }}
# How do you do string concatenation in yml? Do I need to do `format` like above?
name: $(Build.BuildId)$(tag)
steps:
- script: echo "name is $(name)"
But the output is
Generating script.
Script contents:
echo "name is $(name)"
...
name is $(name)"
Is it possible to make this work? How?
The name variable is for the Build.BuildNumber value (see here).
So just print it:
- script: echo "name is $(Build.BuildNumber)"
I'm working with Azure DevOps and I need to set the return of bash commands into some variables, for example I have the following:
variables:
VERSION: 7.2 # works fine
FILE_VERSION: ${{cat public/VERSION}} # syntax error
I tried some some variations from ${{}} without success and I could not found the right syntax for it, but I think it must be possible.
You should use a bash step for that.
Like this:
steps:
- bash: |
echo "##vso[task.setvariable variable=FILE_VERSION]$(cat public/VERSION)"
You need to do this in two steps
STEP 1: Set static value first
variables:
VERSION: 7.2
STEP 2: Create step to calculate the value
Note this will only be available for subsequent steps
- bash: |
FILE_VERSION="$(cat public/VERSION)"
echo "##vso[task.setvariable variable=FILE_VERSION]$FILE_VERSION"
Resources:
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch
We shouldn't use cat command when defining variables. The command should be located in tasks/steps.
According to your description, I assume you're trying to pass the content of public/7.2 to FILE_VERSION variable. Here's my test:
1.Azure Devops Git repo:
2.Define the VERSION variable:
variables:
VERSION: 7.2
Run the cat command and set job-scoped variable:
- bash: |
FILE_VERSION=$(cat public/$(VERSION))
echo "##vso[task.setvariable variable=FILE_VERSION]$FILE_VERSION"
The whole yaml:
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
variables:
VERSION: 7.2
steps:
- bash: |
FILE_VERSION=$(cat public/$(VERSION))
echo "##vso[task.setvariable variable=FILE_VERSION]$FILE_VERSION"
#Use second bash task to test the variable.
- task: Bash#3
inputs:
targetType: 'inline'
script: |
echo $(FILE_VERSION)