Runtime Variable in Yaml Azure DevOps - azure-devops

If have created the Pipeline for One of our CRM Solution in Yaml
I have Created variables SolutionExit,SolutionName,SolutionVersion
#back-up.yaml
parameters:
- name: Solution
displayName: Solution Need to be backed up
type: object
default: [solution1,Solution2]
trigger:
- none
variables:
SolutionExit: ''
SolutionVersion: ''
SolutionName: ''
pool:
vmImage: windows-2019
steps:
- task: MSCRMToolInstaller#12
inputs:
nugetFeed: 'official'
psFeed: 'official'
- ${{each value in parameters.Solution}}:
- task: MSCRMGetSolution#12
inputs:
crmConnectionString: '$(ConnectStr)'
solutionName: '${{value}}'
existsVariableName: 'SolutionExit' #replace existing variable with output value True or False
versionVariableName: 'SolutionVersion' #replace existing variable with output value
displayVariableName: 'SolutionName' #replace existing variable with output value
- template: template/validate-solution.yml
parameters:
SolutionExit: $(SolutionExit)
#validate-solution.yml
parameters:
SolutionExit: ""
steps:
- ${{if eq(parameters.SolutionExit, 'True')}}:
- script: echo "Solution exist $(SolutionExit),$(SolutionVersion),$(SolutionName),${{parameters.SolutionExit}}"
- ${{else}}:
- bash: echo "solution doesnt exit $(SolutionExit),$(SolutionVersion),$(SolutionName),${{parameters.SolutionExit}}"
But runtime parameters are not accepted If condition never satisfies. How to pass the runtime parameter
This Is the result for both cases
If the solution available
Starting: Bash
==============================================================================
Task : Bash
Description : Run a Bash script on macOS, Linux, or Windows
Version : 3.214.0
Author : Microsoft Corporation
Help : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/bash
==============================================================================
Generating script.
Script contents:
echo "solution doesnt exit True,1.0.0.11,Solution1,True"
"C:\Program Files\Git\bin\bash.exe" -c pwd
/d/a/_temp
========================== Starting Command Output ===========================
"C:\Program Files\Git\bin\bash.exe" /d/a/_temp/237f7dc2-debc-4c47-ba88-41a6a97c49d9.sh
solution doesnt exit True,1.0.0.11,soultion1,True
Finishing: Bash
if solution not available
Starting: Bash
==============================================================================
Task : Bash
Description : Run a Bash script on macOS, Linux, or Windows
Version : 3.214.0
Author : Microsoft Corporation
Help : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/bash
==============================================================================
Generating script.
Script contents:
echo "solution doesnt exit False,,,False"
"C:\Program Files\Git\bin\bash.exe" -c pwd
/d/a/_temp
========================== Starting Command Output ===========================
"C:\Program Files\Git\bin\bash.exe" /d/a/_temp/49e5bea1-b380-4a74-a0ce-b89d0dfb3a07.sh
solution doesnt exit False,,,False
Finishing: Bash
How to fix this issue. There is compile time and Runtime variables,as per microsoft I tried ${{if eq(variables['SolutionExit'], 'True')}}: this too didnt work. We cannot use the macro variable in conditions like $(SolutionExit)

From your YAML definition, the variable will generate during the process of Pipeline Run.
The Variable should be Runtime variable. It will be expand at runtime. But the If expression and parameters will be expand at Compile time.
In this case, If expression will not work.
To solve this issue, you need to change to use Condition to replace the If expression.
At the same time, you don't need to use parameters to pass the variable value. You can directly use the variable in the condition.
For example:
Main YAML :
parameters:
- name: Solution
displayName: Solution Need to be backed up
type: object
default: [solution1,Solution2]
trigger:
- none
variables:
SolutionExit: ''
SolutionVersion: ''
SolutionName: ''
pool:
vmImage: windows-2019
steps:
- task: MSCRMToolInstaller#12
inputs:
nugetFeed: 'official'
psFeed: 'official'
- ${{each value in parameters.Solution}}:
- task: MSCRMGetSolution#12
inputs:
crmConnectionString: '$(ConnectStr)'
solutionName: '${{value}}'
existsVariableName: 'SolutionExit' #replace existing variable with output value True or False
versionVariableName: 'SolutionVersion' #replace existing variable with output value
displayVariableName: 'SolutionName' #replace existing variable with output value
- template: template/validate-solution.yml
Template YAML:
steps:
- script: echo "Solution exist $(SolutionExit),$(SolutionVersion),$(SolutionName),${{parameters.SolutionExit}}"
condition: eq(variables['SolutionExit'], 'true')
- bash: echo "solution doesnt exit $(SolutionExit),$(SolutionVersion),$(SolutionName),${{parameters.SolutionExit}}"
condition: ne(variables['SolutionExit'], 'true')

Related

Evaluating Azure Devops Expressions within Powershell

I want to be able to invoke the Counter expression within a template but I am unsure how to do so; my current template yml file looks like this:
parameters:
- name: major
type: string
default: '1'
- name: minor
type: string
default: '0'
steps:
- task: PowerShell#2
displayName: Set NuGet package version
inputs:
targetType: 'inline'
script: |
$isMain = ('$(Build.SourceBranch)' -eq 'refs/heads/main')
$minor = ${{ parameters.minor }}
$revision1 = $[counter($minor, 1)]
Write-Host $revision
exit 0
But I get:
The term '$[counter' is not recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
I am guessing there is way I can invoke the function via Powershell.
The reason for me wanting to do this in the template as opposed to passing it in as a parameter from the consumer of the template is because seemingly parameters are not evaluated when passed into a template.
Evaluating Azure Devops Expressions within Powershell
Just as Daniel said that:
The powershell script you're trying to run is getting finalized
during compile time. This line: $revision1 = $[counter($minor, 1)]
cannot possibly work. You are trying to take the results of a
powershell script expression and use it in a YAML function.
That is reason why it is not work for you.
And personally think you can go the easier way, just define the variable in the main YAML file:
azure-pipelines.yml:
variables:
- name: minor
value: 0
- name: revision1
value: $[counter(variables['minor'], 0)]
stages:
- stage: Run
jobs:
- job:
steps:
- template: Template.yml
And we could use the the Counter in the template directly:
Template.yml:
steps:
- task: PowerShell#2
displayName: Set NuGet package version
inputs:
targetType: 'inline'
script: |
Write-Host '$(revision1)'
The test result:

retrieve value from nested object parameter

my question is closely releted to this one, but I this one doesnt seem to help me :( How to retrieve value from nested object?
I am trying to loop over an object that i get as a parameter, I use a default value as an example, the values in this object are also objects.
I have a template:
parameters:
- name: fruits
type: object
default:
- Banana:
name: " acuminata"
url: "www.banana.com/ acuminata"
- Apple:
name: "jonaGold"
url: "www.apple.com"
steps:
- bash: echo ${{parameters.fruits[0].url}}
- ${{ each fruit in parameters.fruits }}:
- script: echo ${{fruit.name}}
Both the first bash and the second bash are not working. Is it possible to use objects in azure pipelines like this?
This is my output for both bash steps:
2022-04-13T13:01:21.8035586Z ##[section]Starting: CmdLine
2022-04-13T13:01:21.8178179Z ==============================================================================
2022-04-13T13:01:21.8178533Z Task : Command line
2022-04-13T13:01:21.8178874Z Description : Run a command line script using Bash on Linux and macOS and cmd.exe on Windows
2022-04-13T13:01:21.8179171Z Version : 2.201.1
2022-04-13T13:01:21.8179614Z Author : Microsoft Corporation
2022-04-13T13:01:21.8179954Z Help : https://learn.microsoft.com/azure/devops/pipelines/tasks/utility/command-line
2022-04-13T13:01:21.8180355Z ==============================================================================
2022-04-13T13:01:23.2732262Z Generating script.
2022-04-13T13:01:23.2840010Z Script contents: shell
2022-04-13T13:01:23.2849739Z echo
2022-04-13T13:01:23.3217106Z ========================== Starting Command Output ===========================
2022-04-13T13:01:23.3517504Z ##[command]"C:\Windows\system32\cmd.exe" /D /E:ON /V:OFF /S /C "CALL "D:\a\_temp\7a91b1cc-432d-4a20-b39c-7c6b0c78724b.cmd""
2022-04-13T13:01:23.3655983Z ECHO is off.
2022-04-13T13:01:23.3990627Z ##[section]Finishing: CmdLine
I just found a solution. The other thread does provide an answer, I just need to read better :P.
You can access the values with the 'value' keyword. I also removed the '-' before the keywords so its not an array anymore. The code now looks like this:
parameters:
- name: fruits
type: object
default:
Banana:
name: " acuminata"
url: "www.banana.com/ acuminata"
Apple:
name: "jonaGold"
url: "www.apple.com"
steps:
- ${{ each fruit in parameters.fruits }}:
- script: echo ${{fruit.value.name}}
And I get this output:
I did not yet get the first one working, but i don't really need this for my project
- bash: echo ${{parameters.fruits[0].value.url}}

How to reference a variable in Azure Devops on an Linux Agent which contains a dash/minus/-

There is this question which asks about using variables with a minus on linux agents. I tried an indirect reference as suggested here by doing ${!RELEASE_ARTIFACTS__BUILDPROJECT_SOURCEBRANCH} but this does not work, and causes an error in my pipeline. I tried some other approaches using the env command but they too throw errors... Seems odd that this issue persists I guess not as much attention is put on Linux Agents as to Windows. But I am wondering if anyone has found a solution to this?
Here is some code on a Linux agent with variables with dashes.
Try running a bash task and running printenv which will show you all variables available in the linux agent.
Please clarify further what you are trying to do because I can see vars with dashes are working fine in the Linux agents.
pool: default
variables:
- name: test
value: test-value-with-dashes
- name: test-name
value: test-name-with-dashes
- name: System.Debug
value: true
trigger:
- never
stages:
- stage: approval_check
jobs:
- job: bash
steps:
- task: Bash#3
inputs:
targetType: 'inline'
script: |
# Write your commands here
set -x
echo $(test)
echo $(test-name)
echo "print all env vars"
printenv
And here is the output of printenv you can see the vars available in the build agent.
echo test-value-with-dashes
echo test-name-with-dashes
echo 'print all env vars'
printenv
.... lots of env vars printed...
BUILD_SOURCEBRANCH=refs/heads/main
BUILD_ARTIFACTSTAGINGDIRECTORY=/home/james/_work/3/a
...

Azure DevOps Variable Groups Password not working

I'm having userName and passWord field in my Azure DevOps Variable group, and I would like to pass the userName and passWord to my python script as a command line argument, I'm able to get the userName without any issue but passWord is not coming when I pass it from my pipeline script. I tried printing using echo - its printing empty - not evening printing masked value like this '*****'
Please find my pipeline code below:
trigger:
- none
variables:
- group: myVariableGrp
pool:
name: myAgents
stages:
- stage: Testing
jobs:
- job: Test
displayName: Test script
steps:
- task: Bash#3
displayName: Test variable
inputs:
targetType: inline
script: |
echo "hello variables"
echo $USER_NAME
echo $MY_PASSWORD
- task: CmdLine#2
displayName: Test Python script
inputs:
script: python test.py $USER_NAME $MY_PASSWORD
test.py
import sys
# total arguments
#n = len(sys.argv)
#print("Total arguments passed:", n)
print("UserName:", sys.argv[1])
print("Password:", sys.argv[2])
I'm getting the below error:
Traceback (most recent call last):
File "test.py", line 12, in <module>
print("Password:", sys.argv[2])
IndexError: list index out of range
##[error]Bash exited with code '1'.
Finishing: Test Python script
Secret variables are not automatically exposed as env variables. You have to explicitly map them: Reference secret variables in variable groups.
In this case, it would be:
- task: Bash#3
displayName: Test variable
inputs:
targetType: inline
env:
MAPPED_PASSWORD: $(MY_PASSWORD)
script: |
echo "hello variables"
echo $USER_NAME
echo $MAPPED_PASSWORD

Set bash command output into an azure yml variable

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)