How to perform arithmetic operations in Azure devops YAML script? - azure

I am trying to get some values based on the logic to form the version number for my dot net application.
I am using Azure devops and created a Pipeline (YAML). In the pipeline, I have created few variables, which gets the values by using some calculation logic. Below is the code.
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
old_date: '20210601'
latest_date: '20210603'
PSI: ($(latest_date)-$(old_date))/56+1
totalsprints: '($(latest_date)-$(old_date))/14'
sprint: '$(totalsprints)%4+1'
majorversion: '2.'
dot: '.'
name: '$(majorversion)$(Year:yy)$(PSI)$(dot)$(sprint)$(dot)$(Date:MMdd)'
the above logic has a default date set in old_date and it is subtracted from latest_date and divided by 56 to get some value. the next value of the resultant is our PSI. the same way sprint is calculated. this is done in order to form the version number of our Dot Net application. something like this "2.212.2.0312"
The same type of logic works in groovy script in Jenkins. But here, it shows PSI = ($(latest_date)-$(old_date))/56+1 and doesnt evaluate anything.
Appreciate your response on the same.

This is not possible. There is no support for math expressions in variables expressions. You can check it here. You can however declare static variables as above and move all calculation into step and set build number dynamically like it is shown here
It could like this:
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
old_date: '20210601'
latest_date: '20210603'
# PSI: ${{ (variables.latest_date-variables.old_date)/56+1}}
# totalsprints: ${{ (variables.latest_date-variables.old_date)/14 }}
# sprint: ${{ variables.totalsprints%4+1 }}
majorversion: '2.'
dot: '.'
#name: '$(majorversion)$(Year:yy)$(PSI)$(dot)$(sprint)$(dot)$(Date:MMdd)'
trigger: none
pr: none
pool:
vmImage: ubuntu-latest
name: 'Set dynamically below in a task'
steps:
- task: PowerShell#2
displayName: Set the name of the build (i.e. the Build.BuildNumber)
inputs:
targetType: 'inline'
script: |
[int] $PSI = (([int] $(latest_date))-([int] $(old_date)))/56+1
[int] $totalsprints = ( ([int] $(latest_date))-([int] $(old_date)))/14
[int] $sprint = $totalsprints%4+1
$year = Get-Date -Format "yy"
$monthDay = Get-Date -Format "MMdd"
[string] $buildName = "$(majorversion)$year$PSI.$sprint.$monthDay"
Write-Host "Setting the name of the build to '$buildName'."
Write-Host "##vso[build.updatebuildnumber]$buildName"

Related

Azure DevOps Pipeline conditional script arguments

Is it possible to conditionally add arguments to a script within a pipeline task, based on a value of a pipeline paramater?
Example:
parameters:
- name: paramName
displayName: DisplayName
type: boolean
default: trueasd
steps:
- task: PowerShell#2
displayName: TaskName
inputs:
filePath: $(System.DefaultWorkingDirectory)/someScript.ps1
arguments: -DefaultArg1 DefaultArg1_Value `
-DefaultArg2 DefaultArg2_Value
${{ if eq(parameters.paramName, 'false') }}:
-ConditionalParameter
ConditionalParameter is a [switch] parameter. The script which is called in PowerShell#2 task is also meant for local use, which is why a [switch] parameter is much easier for the users, as you do not have to provide a value to it, as with [boolean] type, and the script has a bunch of such parameters.
Or will i have to change both the pipeline parameter and powershell script parameter types to boolean, as it is not possible to use a compile time pipeline expression in this case?
It is not correct to set the condition in the value string of the input parameter on pipeline task.
To conditionally set the value of input parameter on pipeline task, you can do like as below.
. . .
- task: PowerShell#2
displayName: 'TaskName'
inputs:
filePath: '$(System.DefaultWorkingDirectory)/someScript.ps1'
${{ if eq(parameters.paramName, 'false') }}:
arguments: >
-DefaultArg1 DefaultArg1_Value
-DefaultArg2 DefaultArg2_Value
-ConditionalParameter
${{ else }}:
arguments: >
-DefaultArg1 DefaultArg1_Value
-DefaultArg2 DefaultArg2_Value
For more details, you can reference the following documents:
Expressions
PowerShell v2 task

Azure pipeline yaml: Cannot use strategy matrix variable in conditions

I am having problem in calling template as the pre-condition is not getting satisfied, I am comparing parameter value to select which template to call at runtime, here I am having parameter value coming from strategy matrix and I think that might be the issue.
pipeline yaml :
stages:
- stage: build_stage
jobs:
- job:
strategy:
matrix:
Dev_Build:
build_type: "dev"
Rel_Build:
build_type: "rel"
steps:
- template: test_conditional_template.yml#templates_repo
parameters:
build: $(build_type)
test_conditional_template.yml :
parameters:
- name: build
type: string
default: 'dev'
steps:
- ${{ if eq(parameters.build, 'dev') }}: # this condition is not working
- template: test_conditional_template_generic.yml#templates_repo
parameters:
build_quality: ${{ parameters.build }}
test_conditional_template-generic.yml :
parameters:
- name: build
type: string
default: 'dev'
steps:
- script: |
echo "build quality : ${{ parameters.build }}"
displayName: "print build quality, test_conditional_template-generic"
I am not even able to compare the parameter value with normal script step too :
- script: |
echo "build quality : ${{ parameters.build }}"
condition: eq('${{ parameters.build }}', 'dev')
This is what pipeline prints for above step :
if template is called with hard-coded parameter value, condition works fine :
steps:
- template: test_conditional_template.yml#templates_repo
parameters:
build: 'dev' #this works fine with above template code
we're avoiding so much of boilerplate code with usage of strategy matrix so dont really want to get away from it, any pointers will be helpful.
I wanted to add this as a comment but my first thought was that it's comparing 'dev' with "dev" in the first example and ''dev'' (double single quotes) in the script example, so both would evaluate as false,
I've been writing quite a few templates and have had a lot of similar issues, it would be nice if we could find out before checking the code in but ehh yaml...

Azure yaml pipeline display parameter value and have another actual value

I have a yaml pipeline in which I have a string parameter with several values. I want to have a human readable options to choose from but when reading the parameter I want to have an actual different value.
a psuedo yaml declaration for what I mean:
- name: actionParam
displayName: Choose Action
type: string
default: 'Action0': 'no action'
values:
- 'Action1' : 'drop tables'
- 'Action2' : 'hack NASA'
- 'Action3' : 'solve world hunger'
In this example I want for the user to see the options on the right but when doing {{parameters.actionParam}} I want to get the corresponding option on the left.
Is such a thing possible?
Based on your requirement, you need to display parameter value and have another actual value.
I am afraid that there is no out-of-box method to achieve this requirement.
For a workaround, I suggest that you can define the parameters with the options on the right and then you can set the variable value based on the value of the parameters.
Here is an example:
parameters:
- name: actionParam
displayName: Choose Action
type: string
default: 'no action'
values:
- 'drop tables'
- 'hack NASA'
- 'solve world hunger'
variables:
- ${{ if eq(parameters.actionParam, 'solve world hunger') }}:
- name: actionParam
value: Action1
- ${{ if eq(parameters.actionParam, 'drop tables') }}:
- name: actionParam
value: Action2
- ${{ if eq(parameters.actionParam, 'hack NASA') }}:
- name: actionParam
value: Action3
Result:
Then you can use the actual value with the format: $(actionParam)

Hide/Show parameters based on a condition in Azure DevOps Pipelines YAML

I have a use case where I have multiple parameters in ADO build pipeline but those parameters should be visible based on a condition e.g. the branch name (for releases/* branches). Following is a template to showcase what I am trying to achieve:
variables:
- name: systemAccessToken
value: $(System.AccessToken)
- name: system.debug
value: true
- ${{if startsWith(variables['Build.SourceBranch'], 'refs/heads/releases/') }}:
- name: START_DATE_TIME
value: ${{ parameters.startDateTime }}
- name: END_DATE_TIME
value: ${{ parameters.endDateTime }}
- ${{if startsWith(variables['Build.SourceBranch'], 'refs/heads/releases/') }}:
parameters:
- name: startDateTime
displayName: Enter the Start Datetime
type: string
default: 04-14-2022 14:55:00
- name: endDateTime
displayName: Enter the End Datetime
type: string
default: 04-14-2022 23:00:00
resources:
repositories:
...
...
stages:
...
...
The above doesn't work but I would like to get an idea if there is some way I can achieve this using any workaround like injecting the parameters at runtime. Would appreciate any help on this
Sorry, can't be done. The list of parameters is fixed and the pipeline is compiled, before it ever knows about any runtime variables such as Build.SourceBranch.
Instead, you could perhaps define two different pipelines with different sets of parameters? You can avoid duplicating code by extracting the common elements (resources, variables, stages) into a template.

Is it possible to add runtime parameters based on condition - Azure Devops Pipeline

My current azure pipeline looks like following -
parameters:
- name: Deploy
type: Boolean
default: false
- name: Stages
type: string
values:
- Stg A
- Stg B
- Stg C
- Stg D
- Stg E
I was trying to add a condition in such a way that if user checks Deploy on running pipeline, it should dynamically show up only Stg A, Stg B as values for Stages. And if they uncheck Deploy, it should show Stg C, Stg D and Stg E.
I tried to add conditions in following way -
parameters:
- name: Deploy
type: Boolean
default: false
- name: Stages
type: string
${{ if eq(parameters['Deploy'], 'true' ) }}:
values:
- Stg A
- Stg B
${{ if ne(parameters['Deploy'], 'true' ) }}:
values:
- Stg C
- Stg D
- Stg E
However, the following conditional way worked for variables, but did not work for parameters. Is there any way to achieve this in Azure pipelines.
Is it possible to add runtime parameters based on condition - Azure Devops Pipeline
I am afraid it it impossible to runtime parameters conditionally define values based on another parameter value.
Because the parameters need to be defined before the pipeline run starts. As stated in the document Runtime parameters:
Parameters are only available at template parsing time. Parameters are
expanded just before the pipeline runs so that values surrounded
by ${{ }} are replaced with parameter values. Use variables if you
need your values to be more widely available during your pipeline run.
As workaround, we could use condition in the steps:
parameters:
- name: Deploy
type: Boolean
default: false
stages:
- ${{ if eq(parameters['Deploy'], 'true' ) }}:
- template: template.yml
parameters:
stages:
- "Stg A"
- "Stg B"
- ${{ if ne(parameters['Deploy'], 'true' ) }}:
- template: template.yml
parameters:
stages:
- "Stg C"
- "Stg D"
- "Stg E"

Resources