Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure DevOps Yaml pipelines: Stage condition variable syntax

I am working on a azure devops multi stage yaml pipeline. I set a variable in the first stage and then for the next stage, I have a condition based on that variable. I am also retrieving the variable value in the next stage. Apparently there is slight difference between the syntax for accessing inter-stage variables in the condition and at the stage level. I am not able to figure out the syntax I need to use in the condition. I have tried all possible variations but none seems to be working. In the example below, I am expecting the lint stage to run however it gets skipped. What should be exact syntax for the condition here?

stages:
- stage: build
  displayName: build
  pool:
    name: Azure Pipelines
    vmImage: ubuntu-latest
  dependsOn: []
  jobs:
  - deployment: build_job
    environment:
      name: "test"
    strategy:
      runOnce:
        deploy:
          steps:
          - task: PowerShell@2
            displayName: "get commitMessage variable"
            name: getCommitMessage
            inputs:
              targetType: inline
              pwsh: true
              script: |
                $commitMessage = "abcd_import/"
                echo "setting commitMessage: $commitMessage"
                echo "##vso[task.setvariable variable=commitMessage;isOutput=true]$commitMessage"

- stage: lint
  displayName: lint
  dependsOn:
  - 'build'
  condition: contains(stageDependencies.build.build_job.outputs['build_job.getCommitMessage.commitMessage'], 'import/')
  pool:
    name: Azure Pipelines
    vmImage: ubuntu-latest
  variables:
  - name: BUILD_STAGE_GET_COMMIT_MESSAGE
    value: $[stageDependencies.build.build_job.outputs['build_job.getCommitMessage.commitMessage']]
  jobs:
  - deployment: validate
    environment:
      name: "test"
    strategy:
      runOnce:
        deploy:
          steps:
          - task: PowerShell@2
            displayName: "commitMessage is empty"
            name: fail
            inputs:
              targetType: inline
              pwsh: true
              script: "echo $(BUILD_STAGE_GET_COMMIT_MESSAGE)"

Update(Answer): I raised a MS support case on this one and got a resolution. The right syntax is

condition: contains(dependencies.build.outputs['build_job.build_job.getCommitMessage.commitMessage'], 'import/')

A few points on this weird issue:

  • The syntax for using a stage variable is different for using it in a condition and using it to pass in as another variable.
  • Yet again, the syntax is different if the source stage is a job v/s if the source stage is a deployment job.
  • Most importantly, I couldn't find the correct syntax anywhere in the MS documentation.
  • I couldn't find any way to diagnose the issue for example: it would be really helpful to see the stage output json in the build logs.
  • Finally, I believe Azure DevOps team has really messed this feature up. The syntax should be consistent across the jobs/deployment jobs, conditions and variables assignments. It's really a pain in this current state.
like image 583
DevOpsy Avatar asked Sep 02 '26 19:09

DevOpsy


1 Answers

On a stage, to reference an output variable from another stage, you should use the following expression formats:

  • At the stage level, the format for referencing an output variable from another stage is dependencies.STAGE.outputs['JOB.TASK.VARIABLE'].
  • At the job level, the format for referencing an output variable from another stage is stageDependencies.STAGE.JOB.outputs['TASK.VARIABLE'].

For more details, you can see the document about "Use outputs in a different stage".

In addition, on a stage, if you set a stage-level variable using the output from another stage, you should use the format stageDependencies.STAGE.JOB.outputs['TASK.VARIABLE'] instead of dependencies.STAGE.outputs['JOB.TASK.VARIABLE']. See this document.

enter image description here

Below is an example as reference:

  1. azure-pipelines.yml
parameters:
- name: RunStgB
  type: string
  default: YesRun
  values:
  - YesRun
  - NoRun

stages:
- stage: A
  displayName: 'Stage A'
  pool:
    vmImage: ubuntu-latest
  jobs:
  - job: A1
    displayName: 'Job A1'
    steps:
    - task: Bash@3
      name: setOutput
      displayName: 'Set output variable'
      inputs:
        targetType: inline
        script: |
          echo "parameters.RunStgB = ${{ parameters.RunStgB }}"
          echo "##vso[task.setvariable variable=RunStgB;isoutput=true]${{ parameters.RunStgB }}"

- stage: B
  displayName: 'Stage B'
  dependsOn: A
  condition: eq(dependencies.A.outputs['A1.setOutput.RunStgB'], 'YesRun')
  variables:
  - name: Output_RunStgB
    value: $[ stageDependencies.A.A1.outputs['setOutput.RunStgB'] ]
  pool:
    vmImage: ubuntu-latest
  jobs:
  - job: B1
    displayName: 'Job B1'
    steps:
    - task: Bash@3
      displayName: 'show output variable'
      inputs:
        targetType: inline
        script: echo "Output_RunStgB = $(Output_RunStgB)"
  1. Result.

    enter image description here

    enter image description here

like image 131
Bright Ran-MSFT Avatar answered Sep 05 '26 18:09

Bright Ran-MSFT



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!