Problem ?
Azure DevOps pipeline is a set of Tasks which can perform a specific task and these tasks will run inside a Agent Machine (ie., Virtual Machine). While Task is executing, it will be allocated some resources and after the Task execution is complete, the allocated resources will be de-allocated. The entire allocation / de-allocation process repeats for other tasks available within the pipeline. It means the Task1 cannot directly communicate with Task2 or any other subsequent Tasks in the pipeline (pass values between Tasks) as their scope of execution is completely isolated though they get executed in the same Virtual Machine .
In this article, we are going to learn about the scenario where you can communicate between Tasks and pass values between Tasks in a Pipeline .
How to Pass Values between tasks ?
When you use PowerShell and Bash scripts in your pipelines, it’s often useful to be able to set variables that you can then use in future tasks. Newly set variables aren’t available in the same task. You’ll use the task.setvariable logging command to set variables in PowerShell and Bash scripts.
what is Task.setvariable?
Task.setvariable is a logging command can be used to create a variable that be used across tasks within the pipeline whether they are in same job of a stage or across stages. VSO stands for Visual Studio Online, which is part of Azure DevOps’ early roots
“##vso[task.setvariable variable=myStageVal;isOutput=true]this is a stage output variable”
Example:
- powershell: | Write-Host "##vso[task.setvariable variable=myVar;]foo" - bash: | echo "##vso[task.setvariable variable=myVar;]foo"
SetVariable Properties
The task.setvariable command includes properties for setting a variable as secret, as an output variable, and as read only. The available properties include:
- variable = variable name (Required)
- Issecret = true make the variable as a Secret
- isoutput = To use the variable in the next stage, set the isoutput property to true
- isreadonly = When you set a variable as read only, it can’t be overwritten by downstream tasks. Set isreadonly to true
Share variables between Tasks within a Job
Let’s now create a new variable in Task1, assign some value to it and access the Variable in next Task.
- Create a variable named Token using the setvariable syntax, assign it some test value (eg – TestTokenValue)
- Display the value of the Token variable in the next Task as shown in below (Task name ‘Stage1-Job1-Task2’).
stages: - stage: Stage1 jobs: - job: Job1 steps: - task: PowerShell@2 displayName: 'Stage1-Job1-Task1' inputs: targetType: 'inline' script: | Write-Host "##vso[task.setvariable variable=token]TestTokenValue" - task: PowerShell@2 displayName: 'Stage1-Job1-Task2' inputs: targetType: 'inline' script: | Write-Host "the Value of Token : $(token)"
Now, view the output of the variable of the Stage1-Job1-Task2 as shown below. Share variables between Tasks across the Jobs (of the same Stage)
Share variables between Tasks across the Jobs (of the same Stage)
As we discussed in SetVariable property section, We need to use the isOutput=true flag when you desire to use the variable in another Task located in another Job.
>pool: name: devopsagent-w-pprd01 stages: - stage: Stage1 jobs: - job: Stage1_Job1 steps: - task: PowerShell@2 name: 'Stage1_Job1_Task1' inputs: targetType: 'inline' script: | Write-Host "##vso[task.setvariable variable=token;isoutput=true;]TestTokenValue" - job: Stage1_Job2 dependsOn: Stage1_Job1 variables: - name: GetToken value: $[dependencies.Stage1_Job1.outputs['Stage1_Job1_Task1.token']] steps: - task: PowerShell@2 displayName: 'Stag1-Job2-Task1' inputs: targetType: 'inline' script: | Write-Host "the Value of Token : $(GetToken)"
- Navigate to Stage1_Job1_Task1 and add isoutput = true flag to the Logging Command which let’s us to access the value outside the Job.
- The Job in which you want to access the variable must be dependent on the other Job which produces the output. Add dependsOn: Stage1_Job1 in the Stage1_Job2.
- In the Stage1_Job2, Create a new variable named GetToken and set it’s values to $[dependencies.Stage1_Job1.outputs[‘Stage1_Job1_Task1.token’]]. This will help to access the variable value which is available in another dependent job. You can’ access this expression directly in the script. It’s mandatory to map the expression into the value of another variable.
- Finally, access the new variable in your script.
- Once the isoutput=true is added, it’s important to access the variable by prefixing the Task name. Otherwise, it wouldn’t work.
OUTPUT:
Below code where the Job2 can access the output of Job1.
Share variables between Tasks across Stages
As per below code, I didn’t specify dependency (using dependsOn) between Stages as Stage1 and Stage2 are one after the other. In case if you would like to access Stage1’s variable in Stage3 then the Stage2 must depend on Stage1.
Accessing value of one stage from another we need to use stageDependencies attribute where in between jobs we are used dependencies as shown in above YAML.
pool: name: devopsagent-w-pprd01 stages: - stage: Stage1 jobs: - job: Stage1_Job1 steps: - task: PowerShell@2 name: 'Stage1_Job1_Task1' inputs: targetType: 'inline' script: | Write-Host "##vso[task.setvariable variable=token;isoutput=true;]TestTokenValue" - stage: Stage2 jobs: - job: Stage2_Job1 variables: - name: getToken value: $[stageDependencies.Stage1.Stage1_Job1.outputs['Stage1_Job1_Task1.token']] steps: - task: PowerShell@2 displayName: 'Stag1-Job2-Task1' inputs: targetType: 'inline' script: | Write-Host "the Value of Token from Stage2: $(getToken)"