32
votes

I am trying to figure out how to share custom variables across ADO pipelines in my script. Below is my script with 2 stages.

I am setting the curProjVersion as an output variable and trying to access it from a different stage. Am I doing it right?

stages:
- stage: Build
  displayName: Build stage
  jobs:
  - job: VersionCheck
    pool:
      vmImage: 'ubuntu-latest'
    displayName: Version Check
    continueOnError: false
    steps:

      - script: |
          echo "##vso[task.setvariable variable=curProjVersion;isOutput=true]1.4.5"
        name: setCurProjVersion
        displayName: "Collect Application Version ID"

- stage: Deploy
  displayName: Deploy stage
  dependsOn: Build
  variables:
    curProjVersion1: $[ dependencies.Build.VersionCheck.outputs['setCurProjVersion.curProjVersion'] ]
  jobs:
  - job: 
    steps: 
      - script: |
          echo $(curProjVersion1)
8

8 Answers

24
votes

Updated:

Share variables across stages feature has been released in Sprint 168 now.

Please use below format to access output variables from previous stage:

stageDependencies.{stageName}.{jobName}.outputs['{stepName}.{variableName}'] 

Original:

Share variables across stages in Azure DevOps Pipelines

I'm afraid to say that it does not supported to share the variable which defined in one stage and pass it into another stage.

This is the feature we are plan to add, but until now, it does not supported. You can follow this Github issue, many people has the same demand with you. You can follow track that.

Until now, we only support set a multi-job output variable, but this only support YAML. For Classic Editor, there's no any plan to add this feature in release.

For work around, you can predefined the variables before the stages. But one important thing is if you change its value in one stage. The new value could not be passed to the next stage. The lifetime of variable with new value only exists in stage.

13
votes

Jobs can now access variables from previous stages

Output variables are still produced by steps inside of jobs. Instead of referring to dependencies.jobName.outputs['stepName.variableName'], stages refer to stageDependencies.stageName.jobName.outputs['stepName.variableName'].

https://docs.microsoft.com/en-us/azure/devops/release-notes/2020/sprint-168-update#azure-pipelines-1

13
votes

What is important to mention stageDependencies is not available in condition at stage level. It is aviable in jobs, but not in stage directly (at least at the moment).

stages:
- stage: A
  jobs:
  - job: JA
    steps:
    - script: |
        echo "This is job Foo."
        echo "##vso[task.setvariable variable=doThing;isOutput=true]Yes" #The variable doThing is set to true
      name: DetermineResult
    - script: echo $(DetermineResult.doThing)
      name: echovar
  - job: JA_2
    dependsOn: JA
    condition: eq(dependencies.JA.outputs['DetermineResult.doThing'], 'Yes')
    steps:
    - script: |
        echo "This is job Bar."

#stage B runs if DetermineResult task set doThing variable n stage A
- stage: B
  dependsOn: A
  jobs:
  - job: JB
    condition: eq(stageDependencies.A.JA.outputs['DetermineResult.doThing'], 'Yes') #map doThing and check if true
    variables:
      varFromStageA: $[ stageDependencies.A.JA.outputs['DetermineResult.doThing'] ]
    steps:
    - bash: echo "Hello world stage B first job"
    - script: echo $(varFromStageA)
11
votes

This is available as of May 4th 2020

Jobs can access output variables from previous stages:

Output variables may now be used across stages in a YAML-based pipeline. This helps you pass useful information, such as a go/no-go decision or the ID of a generated output, from one stage to the next. The result (status) of a previous stage and its jobs is also available.

Output variables are still produced by steps inside of jobs. Instead of referring to dependencies.jobName.outputs['stepName.variableName'], stages refer to stageDependencies.stageName.jobName.outputs['stepName.variableName'].

Note

By default, each stage in a pipeline depends on the one just before it in the YAML file. Therefore, each stage can use output variables from the prior stage. You can alter the dependency graph, which will also alter which output variables are available. For instance, if stage 3 needs a variable from stage 1, it will need to declare an explicit dependency on stage 1.

1
votes

You can define a global variable and use a Powershell to assign the value of the stage variable to the global variable.

Write-Output ("##vso[task.setvariable variable=globalVar;]$stageVar")

Global variables can either be defined in the yaml itself or in variable groups. Initialise the var with an empty value.

E.g. yaml

  variables:
    globalVar: ''
1
votes

As an update for anyone seeing this question, it seems passing variables between stages has been implemented and should be released in the next couple of weeks.

1
votes

For stage conditions on Azure DevOps Version Dev17.M153.5 with Agent Version 2.153.1 the following works:

stages:
- stage: A
  jobs:
  - job: JA
    steps:
    - script: |
        echo "This is job Foo."
        echo "##vso[task.setvariable variable=doThing;isOutput=true]Yes" #The variable doThing is set to 'Yes'
      name: DetermineResult

#stage B runs if DetermineResult task set doThing variable on stage A
- stage: B
  dependsOn: A
  condition: eq(dependencies.A.outputs['JA.DetermineResult.doThing'], 'Yes')
  jobs:
  - job: JB
    steps:
    - bash: echo "Hello world stage B first job"

Note: The layout of properties is different on stage compared to job:

dependencies.{stage name}.outputs['{job name}.{script name}.{variable name}']

Note: The expression with 'stageDependencies' failed with the following error message:

An error occurred while loading the YAML build pipeline. Unrecognized value: 'stageDependencies'. Located at position XX within expression: and(always(), eq(stageDependencies.A.outputs['JA.DetermineResult.doThing'], 'Yes')). For more help, refer to https://go.microsoft.com/fwlink/?linkid=842996

Bonus:

See the following documentation on how to access the status of the dependent stages: link

-1
votes

You can define the variables just after you define the trigger and before you define the stages

trigger:
- master
  variables:
    VarA: aaaaa
    VarB: bbbbb
stages:
- stage: Build  
  jobs:
  - job: Build
    pool:
      vmImage: 'vs2017-win2016'