azure-devopsazure-pipelinesazure-pipelines-yamlazure-pipelines-build-taskazure-pipelines-tasks

Why Azure Yaml pipeline 'Template Parameter' if-condition does not resolve correctly while comparing the numbers?


I have a parent.yml and sub.yml as shown here:

parent.yml:

variables:
  - name: JavaVersion
    value: 21

jobs:
  - template: templates/sub.yml
    parameters:
      JavaVersion: $(JavaVersion)

sub.yml:

parameters:
  JavaVersion: ''

jobs:
  - job: UseJavaVersion
    steps:
      - ${{ if ge(parameters.JavaVersion, 21) }}:
          - task: PowerShell@2
            displayName: Set default java version to ${{ parameters.JavaVersion }}

      - ${{ else }}:
          - task: PowerShell@2
            displayName: Install java version ${{ parameters.JavaVersion }}

When I run the job then it always goes to else part. Why 'if-condition' does not evaluates to true ? What am I doing wrong or missing here ?

I tried changing the variable value in the parent.yml to '21' and also in the sub.yml if-condition to '21', it did not work.

I also found some related discussions in this github page https://github.com/microsoft/azure-pipelines-agent/issues/1749 but it did not really clarified my issue.

I expect that since variable JavaVersion has value 21 then if-condition in the sub.yml should be executed and we should see a step named as "Set default java version to ${{ parameters.JavaVersion }}".

Note: Since it always goes to else part the step display name shows the correct JavaVersion is resolved by the ${{ parameters.JavaVersion }}.

enter image description here


Solution

  • You're attempting to perform a conditional insertion expression using a value that is only available at runtime.

    Always remember: Variables are evaluated at runtime; Parameters only exist at compile-time.

    If you want to do conditional-insertion at compile-time, you need to use a compile-time value for the parameter:

    # pipeline.yml
    jobs:
      - template: templates/sub.yml
        parameters:
          JavaVersion: 21
    

    If you want to use a variable, you'll have to use conditions on the tasks:

    # pipeline.yml
    jobs:
    - template: templates/sub.yml
      parameters:
        JavaVersion: $(currentJavaVersion)
    
    # templates/sub.yml
    parameters:
    - name: JavaVersion
      type: string
    
    jobs:
    - job: UseJavaVersion
    
      variables:
        javaVersion: ${{ parameters.JavaVersion }}
     
      steps:
      - task: PowerShell@2
        displayName: Using Java 21 or greater
        condition: and( succeeded(), ge( variables['javaVersion'], 21) )
        inputs:
          targetType: inline
          script: Write-Host "Using ${{ parameters.JavaVersion }}"
    
      - task: PowerShell@2
        displayName: Install java 
        condition: and( succeeded(), lt( variables['javaVersion'], 21) )
        inputs:
          targetType: inline
          script: Write-Host "Installing!"