Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tell if a variable exists in template with azure pipelines

I'm trying to figure out a way to do the following

variables:
  ${{ if eq(variables['var-a'], exists_and_is_set) }}:
    namespaceName: $(var-a)
  ${{ if ne(variables['var-a'], exists_and_is_set) }}:
    namespaceName: $(var-b)

Basically, if variable a exists and a != null and a != '', then use it, otherwise use another variable. The scripting here is pretty simplistic and I can't find a way to do this. The reason for it is I'm making a change that out of several hundred cicd pipelines that use this template, only 10 or so will use var-a, so I'm trying to find a way to implement the logic without having to go update several hundred pipelines to include something they won't use.

like image 638
scphantm Avatar asked Dec 05 '25 21:12

scphantm


2 Answers

You could try to use the ''to indicate non-existence or no value.

For example: eq(variables['var-a'], '')

If you use the If Expression, it may not achieve the feature you want.

Based on my test, when I use the If Expression, the value of the var-a variable will always remain non-existent or empty, even if it has been created.

So I find another method to set the variable, and it could work as expected:

Here is my example:

template: build.yml

steps:

- script: echo "##vso[task.setvariable variable=namespaceName;]$(var-a)"
  condition: ne(variables['var-a'], '')
- script: echo "##vso[task.setvariable variable=namespaceName;]$(var-b)"
  condition: eq(variables['var-a'], '')

Azure pipelines.yml

....
steps:
- template: build.yml
- script: |
    echo $(namespaceName)
  displayName: 'Run a multi-line script'

This sample use the Condition Expression and Logging command.

In this case, it will select the task to run based on the value of the variable. In the task, it will use the logging command to set the variable.

var-a: null/non-existence -> run task 2 -> namespaceName: var-b

var-a: existence -> run task 1 -> namespaceName: var-a

like image 101
Kevin Lu-MSFT Avatar answered Dec 10 '25 18:12

Kevin Lu-MSFT


Kevin Lu is correct, but here is some additional context to why it works the way it does.

The ${{ <expression> }} syntax is only evaluated at template compile time. This means that any user variables will not yet have been initialized. If you attempt to check their value, it will always return an empty value. While the ${{ <expression> }} syntax is handy to conditionally output template lines for processing, user variable values will not have been set limiting what you can do with the if.

The $[ <expression> ] syntax is evaluated at run time. Variables will have been initialized, however you can't directly use the if syntax to conditionally output a different variable value directly. You can use a cleaver hack however, as documented by Simon Alling's answer in this post.

Reference: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/expressions

This very simple YAML Pipeline illustrates the concept:

stages:
- stage: TestVarsCompile
  variables:
    - name: state_prefix
      # $subdirectory is not defined
      ${{ if eq(variables['subdirectory'], '') }}:
       value: 'subdirectory-not-set'

      # $subdirectory is defined 
      ${{ if ne(variables['subdirectory'], '') }}: 
       value: 'subdirectory-set'

  jobs:
   - job:
     steps:
     - checkout: none
     - script: |
        echo $(subdirectory)
        echo $(state_prefix)

- stage: TestVarsRuntime
  variables:
   state_prefix: $[
        replace(
          replace(
            eq(variables['subdirectory'], ''),
            True,
            'sub-directory-not-set'
          ),
          False,
          'sub-directory-set'
        )
      ]

  jobs:
   - job:
     steps:
     - checkout: none
     - script: |
        echo $(subdirectory)
        echo $(state_prefix)

The TestVarsCompile stage output always returns the following output regardless if the subdirectory variable is set or not:

some value
subdirectory-not-set

The TestVarsRuntime stage output will return the following if the subdirectory variable is set:

some value
subdirectory-set

like image 30
codechurn Avatar answered Dec 10 '25 19:12

codechurn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!