azure-devopsazure-pipelines

How to run a template based on update to a directory in azure pipeline


I want to conditionally run a template within azure pipeline based on it the commit has updated a particular directory. When i run the expression it's always see the variable as false. What am I missing?


        - stage: Provision_Central_Techops
      dependsOn: [] 
      
      displayName: Provision Central Techops
      jobs:
      
      - job: Provision_TechOps_Central_Stack
        displayName: Provision TechOps Central Stack
        variables:
          workingDirectory: terraform/stacks/techops
       
        steps:
        - bash: |
            
                  echo workingDirectory $(workingDirectory)
                  
                  if git diff-tree --no-commit-id --name-only -r HEAD | grep -q $(workingDirectory); then
    
                    echo "##vso[task.setvariable variable=techopsUpdated]true"
                    
                  else
    
                    echo "##vso[task.setvariable variable=techopsUpdated]false"
                    
                  fi
                  
                    
          name: Check_For_Update
        
        - ${{ if eq(variables.techopsUpdated, true) }}:
          - template: steps/terraform.yml
           
            parameters:
              environment: prod
              workingDirectory: $(workingDirectory)
              stackName: techops
              terraformVersion: $(terraformVersion)
        - ${{ else }}:
          - script: echo "techopsUpdated $(techopsUpdated)"

I have tried adding a condition still no joy. The condition is comparing again a null value

enter image description here

- stage: Provision_Central_Techops
  dependsOn: [] 
  
  displayName: Provision Central Techops
  jobs:
  
  - job: Provision_TechOps_Central_Stack1
    displayName: Provision TechOps Central Stack
    variables:
      workingDirectory: terraform/stacks/techops
    
   
    steps:
    - bash: |
        
              echo workingDirectory $(workingDirectory)
              
              if git diff-tree --no-commit-id --name-only -r HEAD | grep -q $(workingDirectory); then

                echo "##vso[task.setvariable variable=techopsUpdated; isOutput=true]true"
                
              else

                echo "##vso[task.setvariable variable=techopsUpdated; isOutput=true]false"
                
              fi
              
                
      name: Check_For_Update
  
  - job: Provision_TechOps_Central_Stack
    
    condition: eq(variables.techopsUpdated , true)
    displayName: Provision TechOps Central Stack
    variables:
      workingDirectory: terraform/stacks/techops
   
    steps:

    
    - template: steps/terraform.yml       
      parameters:
          environment: prod
          workingDirectory: $(workingDirectory)
          stackName: techops
          terraformVersion: $(terraformVersion)

Solution

  • The template expression "${{ xxx }}" is evaluated at compile-time before runtime, while the variable techopsUpdated is created at runtime. This could cause the expression "${{ xxx }}" always evaluates the value of this variable as empty, so the condition will always return false.


    EDIT:

    As a workaround, you can do like as below:

    1. Within the same stage, you can add another job before job 'Provision_TechOps_Central_Stack' to run the step 'Check_For_Update'.

    2. In the step 'Check_For_Update', set the variable 'techopsUpdated' as a output variable.

    3. On the job 'Provision_TechOps_Central_Stack', set it dependsOn the previous job. And use the condition key on this job check the value of the output variable.

    stages:
    - stage: Provision_Central_Techops
      jobs:
      - job: checkUpdate
        variables:
          workingDirectory: terraform/stacks/techops
        steps:
        - bash: |
            echo workingDirectory $(workingDirectory)
            if git diff-tree --no-commit-id --name-only -r HEAD | grep -q $(workingDirectory); then
              echo "##vso[task.setvariable variable=techopsUpdated;isoutput=true]true"
            else
              echo "##vso[task.setvariable variable=techopsUpdated;isoutput=true]false"
            fi
          name: Check_For_Update
      
        - bash: |
            echo "techopsUpdated $(Check_For_Update.techopsUpdated)"
          displayName: 'Show value of techopsUpdated'
    
      - job: Provision_TechOps_Central_Stack
        displayName: 'Provision TechOps Central Stack'
        dependsOn: checkUpdate
        condition: eq(dependencies.checkUpdate.outputs['Check_For_Update.techopsUpdated'], 'true')
        variables:
          workingDirectory: terraform/stacks/techops
        steps:
        - template: steps/terraform.yml
          parameters:
            . . .
    

    With above configurations, if the value of output variable 'techopsUpdated' is 'true', the job 'Provision_TechOps_Central_Stack' gets run, otherwise it gets skipped.

    Related documentations: