Why am i getting an error when declaring variables YAML - azure-devops

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 ;-)

Related

Is it possible to use variable group in IF statements? - Azure DevOps

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

How to pass variables from variable group between .yaml files with CopyFiles#2?

I have one variable group in ADO library which store different paths and some other variables.
In my main "master" pipeline I use it as below:
variables:
- group: myGroupName
- name: nameOfMyVariable(from variables group) or JustAnyName
- value: $[variables.nameOfMyVariable] or $[variables.JustAnyName]
then in job in the first Stage (for testing, there is only one stage and job for now) I'm trying to using template yaml:
jobs:
- template: my-template.yaml
parameters:
path: $(nameOfMyVariable) or $(JustAnyName)
then in my-template.yaml I have this code:
parameters:
- name: path
type: string
default: ''
jobs:
- job: BuildSomething
steps:
- task: CopyFiles#2
inputs:
Contents: |
${{ parameters.path }}
TargetFolder: '$Build.ArtifactStagingDirectory)'
....
Rest is not that important as it just can't find files to copy and when I try to print parameters.path with echo I get error :
syntax error: invalid arithmetic operator(error token is ".nameOfMyVariable").
I do not know how to fix it so I can access variables from variable group in some of my templates. Do I need to use ##vso[task.setvariables] or something else?
If you want use variable from variable group it is enough to just include this group
variables:
- group: myGroupName
And then use variable by name $(nameOfMyVariable)
In your example it seems you try unnecessary try to declare this variable again in first yaml example.
This example is additionally incorrect because you are addings dash directly before 'value' keyword and it may cause undefined behaviour.
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#specify-variables
Just like Kontekst says, when it comes to variable groups, you don't need to declare the variable names and values in your yaml. Once you declare the variable groups in your yaml, you could use the variables from the groups directly.
And if you are using parameters against templates, for your scenario, I suppose that you could declare the parameters in your main yaml, and input the parameter value into your template. (and you don't have to use the variable groups)
My main yaml as below.
trigger:
- none
pool:
vmImage: ubuntu-latest
parameters:
- name: pathmain
displayName: Source Path
type: string
default: README.md
values:
 - azure-pipelines.yml
 - README.md
jobs:
 - job:
   steps:
   - script: echo ${{ parameters.pathmain }}
 - template: test-template.yml
   parameters:
     path: ${{parameters.pathmain}}
My test-template as below.
parameters:
- name: path
displayName: Source Path
type: string
jobs:
- job: BuildSomething
steps:
   - task: CopyFiles#2
     inputs:
       Contents: |
         ${{ parameters.path }}
       TargetFolder: '$Build.ArtifactStagingDirectory'

If condition not working for runtime variables/parameters in Azure YAML file

Hi I am trying to run the load testing and integration tests simultaneously and I wanted to run the load tests only when we are in "stg" environment but not in any other environments. But my variable value is coming in run time as $(environment) as below
variables:
- name: loadenv
value: $(environment)
My condition before the load testing code block is
${{if eq(variables['loadenv'], 'stg') }}:
loadTestParams:
executor: jmeter
This works fine if I hardcode the value: stg whereas in runtime, I am not able to get the variables if it is like this $(environment).
Can anyone please help to solve this issue?
I have tried the same thing with parameters but no luck
You should use Expressions.
Quoted from the linked Microsoft documentation:
# Two examples of expressions used to define variables
# The first one, a, is evaluated when the YAML file is compiled into a plan.
# The second one, b, is evaluated at runtime.
# Note the syntax ${{}} for compile time and $[] for runtime expressions.
variables:
a: ${{ <expression> }}
b: $[ <expression> ]
So as you're saying environment will be filled at runtime you will need to use $[ <expression> ].
Based on your description, the variable value is coming from Runtime. But the If expression will expand at compile time, so the variable value will not pass to the If Expression.
To solve this issue, you can change to use Parameters to pass the environment value.
For example:
parameters:
- name: loadenv
displayName: value
type: string
default: stg
steps:
- ${{if eq( parameters.loadenv , 'stg') }}:
- script: echo Hello, world!
displayName: 'Run a one-line script'
When you run the Pipeline, you can set the environment value and it will pass to the If Expression.
The solution that is working is we have modified the template to accept a condition in load test params so that it will accept the runtime variables in the condition
loadTestParams:
condition: {condition here with run-time variable}
executor: jmeter

YAML pipeline definition which retrieves variables values from pipeline variables

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

How to use VSTS pipeline variable in YAML?

I have defined a variable in the pipeline and set it to false/true. However, when the pipeline is set, I can see that the value for parameters.RunUnitTest is $(RunUnitTest), and this is not the value I set up in the pipeline. So what I am doing wrong here?
trigger: none
extends:
template: ThunderPipeline.yaml
parameters:
MergeBetweenBranches: true
FromBranch: 'master'
ToBranch: 'R_Current_Sprint'
RunUnitTest: '$(RunUnitTest)'
Variables can be defined in one YAML and included in another template. This could be useful if you want to store all of your variables in one file. If you are using a template to include variables in a pipeline, the included template can only be used to define variables. You can use steps and more complex logic when you are extending from a template. Use parameters instead of variables when you want to restrict type.
In this example, the variable favoriteVeggie is included in azure-pipelines.yml.
# File: vars.yml
variables:
favoriteVeggie: 'brussels sprouts'
# File: azure-pipelines.yml
variables:
- template: vars.yml # Template reference
steps:
- script: echo My favorite vegetable is ${{ variables.favoriteVeggie }}.
Or something like:
# File: templates/steps-with-params.yml
parameters:
- name: 'runExtendedTests' # defaults for any parameters that aren't specified
type: boolean
default: false
steps:
- script: npm test
- ${{ if eq(parameters.runExtendedTests, true) }}:
- script: npm test --extended
# File: azure-pipelines.yml
steps:
- script: npm install
- template: templates/steps-with-params.yml # Template reference
parameters:
runExtendedTests: 'true'