Search code examples
azure-devopsyamlazure-pipelines-yaml

Updating yaml pipeline variables


Hi I have a yml pipeline in azure devops.

variables:
 - name: dependencyChanged
    value: false

-stage: stage1
 jobs:
 - task: Bash@3
   inputs:
       targetType: 'inline'
       script: |
           CHANGED_FILES=$(git diff HEAD HEAD~ --name-only)
           DEPENDENCY_CHANGED=$(echo "$CHANGED_FILES" | grep -q "aml/ml_service/docker/" && echo "true" || echo "false")
           echo "##vso[task.setvariable variable=dependencyChanged=true;isOutput=true]]$DEPENDENCY_CHANGED"
           echo "Debug: adfChanged value is '${{ variables['dependencyChanged'] }}'"

-stage: stage2
 condition: and(succeeded('stage1'), eq(variables['dependencyChanged'], 'true'))
 jobs:
 .... some jobs here

The problem is: DEPENDENCY_CHANGED is 'true' and dependency_change is also true becasue it is set from DEPENDENCY_CHANGED

but stage2 never gets executed, not sure why. even if if do echo "##vso[task.setvariable variable=dependencyChanged=true;isOutput=true]]'true'"

In summary, I want to update the pipeline variables with in different stages and access them in multiple stages.


Solution

  • There are some syntax errors in your YAML pipeline for setting and using output variables between stages. You can reference below sample to correct your YAML pipeline.

    1. The pipeline main YAML.

      # azure-pipelines.yml
      
       stages:
       - stage: stage1
         jobs:
         - job: job1
           steps:
           - bash: |
               CHANGED_FILES=$(git diff HEAD HEAD~ --name-only)
               DEPENDENCY_CHANGED=$(echo "$CHANGED_FILES" | grep -q "aml/ml_service/docker/" && echo "true" || echo "false")
               echo "##vso[task.setvariable variable=dependencyChanged;isOutput=true]$DEPENDENCY_CHANGED"
             name: setOutVar
             displayName: 'Set Output Variable'
      
           # Use output variable within the same job.
           - bash: |
               echo "dependencyChanged = $(setOutVar.dependencyChanged)"
             displayName: 'Print Output Variable'
      
         # Use output variable from a different job within the same stage.
         # Use the output variable on job-level condition.
         # Map the output variable as a job-level variable.
         - job: job2
           dependsOn: job1
           condition: and(succeeded('job1'), eq(dependencies.job1.outputs['setOutVar.dependencyChanged'], 'true'))
           variables:
             dependencyChanged: $[ dependencies.job1.outputs['setOutVar.dependencyChanged'] ]
           steps:
           - bash: |
               echo "dependencyChanged = $(dependencyChanged)"
             displayName: 'Print job-level Variable'
      
       # Use output variable from a different stage.
       # Use the output variable on stage-level condition.
       # Map the output variable as a stage-level variable.
       - stage: stage2
         condition: and(succeeded('stage1'), eq(stageDependencies.stage1.outputs['job1.setOutVar.dependencyChanged'], 'true'))
         variables:
           dependencyChanged: $[ stageDependencies.stage1.job1.outputs['setOutVar.dependencyChanged'] ]
         jobs:
         - job: job3
           steps:
           - bash: |
               echo "dependencyChanged = $(dependencyChanged)"
             displayName: 'Print stage-level Variable'
      
    2. the results.

      • When dependencyChanged=true, job2 and stage2 will run due to the conditions.

        enter image description here

      • When dependencyChanged=false, job2 and stage2 will get skipped due to the conditions.

        enter image description here

    Related documentations: