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
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 have a BRANCH_NAME variable based on the trigger branch which is working great. Now based on my BRANCH_NAME value I have to select a json file. Im using starts with but not sure why my TARGET_ENV is not working
variables:
system.debug: 'false'
${{ if startsWith(variables['Build.SourceBranch'],
'refs/heads/') }}:
BRANCH_NAME: $[replace(variables['Build.SourceBranch'],
'refs/heads/', '')]
${{ if startsWith(variables['Build.SourceBranch'],
'refs/heads/feature') }}:
BRANCH_NAME: $[replace(variables['Build.SourceBranchName'],
'/', '-')]
###
${{ if eq(variables['BRANCH_NAME'], 'dev') }}:
TARGET_ENV: dev
${{ if startsWith(variables['BRANCH_NAME'], 'test') }}:
TARGET_ENV: test
${{ if or( startsWith(variables['BRANCH_NAME'], 'XX'), startsWith(variables['BRANCH_NAME'], 'VV') ) }}:
TARGET_ENV: feature
And the value of TARGET_ENV should be used in a script ( echo $TARGET_ENV )
The yaml file isn't executes as soon as an element is parted, the yaml file is parted in stages. During the template expansion stage only the variables set at queue time are available.
After the template has been expanded (e.g. the ${{}} blocks have been evaluated the yaml is interpreted top to bottom. So the value of BRANCH_NAME isn't available yet.
You can set the variable either from a pre (like my variable tasks) or from a script by printing one of the special command statements.
- bash: |
echo "##vso[task.setvariable variable=myVar;]foo"
condition: $[ eq(variables['BRANCH_NAME'], 'dev' ]
Or you can put all the logic in a single PowerShell block and let PowerShell evaluate the values of the variables.
- powershell: |
if ($env:BRANCH_NAME -eq 'dev') {
Write-host ##vso[task.setvariable variable=TARGET_ENV;]dev
}
...
...
This variable will only be available in the job the task runs. You can make it an output variable to make the task available in other jobs, but then you need to refer to it by its long name:
Dependencies.jobname.stepname.outputvariable
See also:
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/set-variables-scripts?view=azure-devops&tabs=bash#about-tasksetvariable
https://stackoverflow.com/a/73609482/736079
I have the code as below which works fine
variables:
- group: docker-settings
I need to add a variable to use in a condition so i insert the variable as below but then I get an error? If I remove -group :docker-settings it works, if I remove isMaster line instead it works but it doesnt like them both there? What am I doing wrong?
variables:
- group: docker-settings
isMaster: $[eq(variables['Build.SourceBranch'], 'refs/heads
I used these docs
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/conditions?view=azure-devops&tabs=yaml
I used the name / value notation and fixed the value based on the MS example and set master instead of main. I guess this is what you want to have.
variables:
- group: docker-settings
- name: 'isMaster'
value: $[eq(variables['Build.SourceBranch'], 'refs/heads/master')]
Microsoft example:
variables:
staticVar: 'my value' # static variable
compileVar: ${{ variables.staticVar }} # compile time expression
isMain: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')] # runtime expression
steps:
- script: |
echo ${{variables.staticVar}} # outputs my value
echo $(compileVar) # outputs my value
echo $(isMain) # outputs True
Don't give up with yaml and Azure DevOps ;-)
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)"
How does one overwrite a pipeline variable or how does one create a pipeline variable from a job?
I'm running a prepare job where I extract the current git tag into a variable that I need in following jobs so I decided to create a pipeline variable and overwrite its value in the first job:
variables:
GIT_TAG: v0.0.1
jobs:
- job: job1
pool:
vmImage: 'ubuntu-16.04'
steps:
- powershell: |
Write-Host "##vso[task.setvariable variable=GIT_TAG]$(git describe --tags --always)"
But, in the next job GIT_TAG has the initial value of v0.0.1.
By default, if you overwrite a variable the value is available only to his job, not to the sequence jobs.
Passing variables between jobs in the same stage is a bit more complex, as it requires working with output variables.
Similarly to the example above, to pass the FOO variable:
Make sure you give a name to the job, for example job: firstjob
Likewise, make sure you give a name to the step as well, for example: name: mystep
Set the variable with the same command as before, but adding ;isOutput=true, like: echo "##vso[task.setvariable variable=FOO;isOutput=true]some value"
In the second job, define a variable at the job level, giving it the value $[ dependencies.firstjob.outputs['mystep.FOO'] ] (remember to use single quotes for expressions)
A full example:
jobs:
- job: firstjob
pool:
vmImage: 'Ubuntu-16.04'
steps:
# Sets FOO to "some value", then mark it as output variable
- bash: |
FOO="some value"
echo "##vso[task.setvariable variable=FOO;isOutput=true]$FOO"
name: mystep
# Show output variable in the same job
- bash: |
echo "$(mystep.FOO)"
- job: secondjob
# Need to explicitly mark the dependency
dependsOn: firstjob
variables:
# Define the variable FOO from the previous job
# Note the use of single quotes!
FOO: $[ dependencies.firstjob.outputs['mystep.FOO'] ]
pool:
vmImage: 'Ubuntu-16.04'
steps:
# The variable is now available for expansion within the job
- bash: |
echo "$(FOO)"
# To send the variable to the script as environmental variable, it needs to be set in the env dictionary
- bash: |
echo "$FOO"
env:
FOO: $(FOO)
More info you can find here.