Mike Murray
Mike Murray

Reputation: 1461

Can Conditional Variable Assignment be Done in Azure Pipelines?

Azure Pipelines has Expressions and Conditions, but I can find no way to assign one of two values to a variable, based on a condition.

Is there any way to accomplish what this pseudo-code would?

    ${{ if endsWith( variables['Build.SourceBranchName'], '/master' ) }}: 
      buildVersion: variables['mavenVersion']
    ${{ else }}: 
      buildVersion: variables['Build.SourceBranchName']

Upvotes: 80

Views: 90734

Answers (7)

user7395504
user7395504

Reputation: 21

In a template with parameters you are maybe tempted to try something like this (remark: variables in templates can be declared in jobs or stages):

variables:
  ${{ if eq( ${{parameters.Environment}}, 'DEV' ) }}: 
    targetenv: myDevMachine
  ${{ if eq( ${{parameters.Environment}}, 'TST' ) }}: 
    targetenv: myTSTMachine

Unfortunately that doesn't work. A workaround for that is to store the template variable first in a temporary variable like this:

variables:
  env: ${{parameters.Environment}} 
  ${{ if eq( variables.env, 'DEV' ) }}: 
    targetenv: myDevMachine
  ${{ if eq( variables.env, 'TST' ) }}: 
    targetenv: myTSTMachine

Upvotes: 2

SoloDolo
SoloDolo

Reputation: 310

You can have conditional variables based on parameters:

parameters:
- name: example
  default: master
  values:
  - master
  - branch1
  - branch2

variables:
  ${{ if eq( parameters.example, 'master' ) }}: 
    buildVersion: 'this'
  ${{ else }}: 
    buildVersion: 'that' # buildVersion = this

Won't work if the variables are in a separate template.

Upvotes: 3

Krzysztof Madej
Krzysztof Madej

Reputation: 40543

With this update your YAML is valid:

    ${{ if endsWith( variables['Build.SourceBranchName'], '/master' ) }}: 
      buildVersion: variables['mavenVersion']
    ${{ else }}: 
      buildVersion: variables['Build.SourceBranchName']

All works fine with this

trigger: none

name: if-else

pool:
  vmImage: ubuntu-latest

variables:
  ${{ if endsWith( variables['Build.SourceBranchName'], 'master' ) }}: 
    buildVersion: 'master'
  ${{ else }}: 
    buildVersion: 'none-master'

steps:
- script: |
    echo "$(Build.SourceBranchName)"
    echo "$(buildVersion)"
  displayName: 'Display buildVersion'

Simply Build.SourceBranchName contains just master.

Generating script.
========================== Starting Command Output ===========================
/usr/bin/bash --noprofile --norc /home/vsts/work/_temp/1121efc8-6445-4e19-be5a-8d525a76467e.sh
master
master
Finishing: Display buildVersion

Note: This doesn't work on Azure DevOps Server - please be aware of that! Thanks @psulek for highlighting this!

Upvotes: 17

Evan Citulsky
Evan Citulsky

Reputation: 760

As an extension to @Mike Murray's answer, if you are using variable groups you must define additional variables as name value pairs. To use conditional variable assignment in this case would be as follows:

variables:
- group: 'my-variable-group'
- name: myfirstadditionalvariable
  value: 100
- name: myconditionalvariable
  ${{ if eq( variables['Build.SourceBranchName'], 'master' ) }}: 
    value: masterBranchValue
  ${{ if ne( variables['Build.SourceBranchName'], 'master' ) }}: 
    value: featureBranchValue

Upvotes: 76

@Mike Murray, thank you for this! I have been trying to solve this for ages. When builds are triggered from pull requests the SourceBranchName is always 'merge'. Your answer helped me come up with this solution for getting the target branch name for both scenarios, manual builds and builds triggered by pull-requests:

${{ if ne( variables['Build.SourceBranchName'], 'merge' ) }}: 
    environment: ${{ variables['Build.SourceBranchName'] }}
  ${{ if endsWith( variables['System.PullRequest.TargetBranch'], 'dev' ) }}: 
    environment: dev
  ${{ if endsWith( variables['System.PullRequest.TargetBranch'], 'staging' ) }}: 
    environment: staging
  ${{ if endsWith( variables['System.PullRequest.TargetBranch'], 'master' ) }}: 
    environment: prod

Not very pretty, but finally works.

Upvotes: 3

Mike Murray
Mike Murray

Reputation: 1461

I was closer than I thought. This is not pretty, but it worked. (with more yaml context)

variables:
  ${{ if eq( variables['Build.SourceBranchName'], 'master' ) }}: 
    buildVersion: ${{ variables['mavenVersion'] }}
  ${{ if ne( variables['Build.SourceBranchName'], 'master' ) }}: 
    buildVersion: ${{ variables['Build.SourceBranchName'] }}

  buildKey: ${{ format('{0}_{1}', variables['supportReleaseNumber'], variables['buildVersion']) }}
  buildNum: $[counter(variables['buildKey'], 1)]  # same as $(Rev:r), but more widely usable 

name: $(buildKey)_$(buildNum)  # build run name

Upvotes: 52

Venura Athukorala
Venura Athukorala

Reputation: 720

This should do the trick....

BuildVersion is initialised as $(Build.SourceBranch) if it's the master branch you change that to the $(mavenVersion) else no change.

variables:
  mavenVersion: '1.0'
  buildVersion: $(Build.SourceBranch)

pool:
  vmImage: 'ubuntu-latest'

steps:

- script: echo '##vso[task.setvariable variable=buildVersion]$(mavenVersion)'
  displayName: "Set the buildVersion as mavenVersion if the Build.SourceBranch = 'refs/heads/master' "
  condition: eq(variables['Build.SourceBranch'], 'refs/heads/master')

- script: echo $(buildVersion)
  displayName: 'Printing the variable'

non-master branches prints 'refs/heads/branch_name' which is mavenVersion non-master branches prints 'refs/heads/branch_name' which is mavenVersion

master branch prints 1.0 which is mavenVersion master branch prints 1.0 which is mavenVersion

Upvotes: 12

Related Questions