Nico
Nico

Reputation: 719

ADS 2019 - How to pass variables between build jobs

Using Azure DevOps Server 2019.1 i am starting to work with Multi jobs, to allow me to split up work onto multiple agents.

The flow itself works fine. I have it setup like this

Begin Job - this basically tests a few variables and Updated the buildnumber

(Depends on Begin Job) RunTest Job - A job to run "multi-configuration", which splits a comma seporated list of task categories

(Depends on RunTest Job) End Job - A trigger build task for a new build in the chain

While the jobs depend on another job, this only seems to affect the time they will start, they will not get access to the information provided by the job that ran before.

Basically what i need is the value of a variable that has been set (buildNumber) in the Begin Job. I need this version number in the RunTest and End Job. How can i get this information ? I read articles that this is not possible, but have not seen a valid workaround yet. Does anyone have a decent workaround ?

Upvotes: 2

Views: 2071

Answers (2)

PatrickLu-MSFT
PatrickLu-MSFT

Reputation: 51133

Update2: Using YAML should be the simplest solution. If you insist on Classic build view. You could try to accomplish this by storing the values in a file (json, xml, yaml, what have you), you can read the file in the Job either direct use or re-set the variable again.

When you queue next build, it will not effect the file in source control and the default value will also not change.


Passing variables between jobs in the same stage, it requires working with output variables.

However, according to this, using outputs in a different job is not supported in Classic UI Format.

As workarounds in this scenario, you can share variables via Pipeline Variables(share variables across jobs in same pipeline).

1.You can set a key variable in pipeline variables:

enter image description here

2.Add one Powershell Inline task with content below in your first job:

$url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/build/definitions/$($env:SYSTEM_DEFINITIONID)?api-version=5.0"

Write-Host "URL: $url"

$pipeline = Invoke-RestMethod -Uri $url -Headers @{

    Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"

}

Write-Host "Pipeline = $($pipeline | ConvertTo-Json -Depth 100)"



# Update an existing variable to its new value

$pipeline.variables.key.value = "value"



####****************** update the modified object **************************

$json = @($pipeline) | ConvertTo-Json -Depth 99



$updatedef = Invoke-RestMethod -Uri $url -Method Put -Body $json -ContentType "application/json" -Headers @{Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"}



write-host "==========================================================" 

Write-host "The value of Varialbe key is updated to" $updatedef.variables.key.value

write-host "=========================================================="

3.Run the pipeline we can find the value of key variable is successfully updated:

enter image description here

So you can run the ps script in first job to update the value of key variable, then all next jobs can access the updated variable easily.

Note:

  1. For the script itself, you only need to change lines $pipeline.variables.key.value = "value"(necessary) and Write-host "The value of Varialbe key is updated to" $updatedef.variables.key.value(optional).

If I want to set the variable named MyTest to value MyValue, the lines should be $pipeline.variables.MyTest.value = "MyValue" and Write-host "The value of Varialbe MyTest is updated to" $updatedef.variables.MyTest.value.

  1. To make sure the ps task in one job can access OAuth Token, we should Allow Scripts to Access OAuth Token. Click the agent job name and check the box:

enter image description here

  1. To enable the pipeline has the permission to update pipeline variable (edit build pipeline), go pipeline security to set the Edit build pipeline allow for user xxx(ProjectName) build service.

enter image description here

Upvotes: 0

Krzysztof Madej
Krzysztof Madej

Reputation: 40729

Did you try multi job output variable:

jobs:

# Set an output variable from job A
- job: A
  pool:
    vmImage: 'vs2017-win2016'
  steps:
  - powershell: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the value"
    name: setvarStep
  - script: echo $(setvarStep.myOutputVar)
    name: echovar

# Map the variable into job B
- job: B
  dependsOn: A
  pool:
    vmImage: 'ubuntu-16.04'
  variables:
    myVarFromJobA: $[ dependencies.A.outputs['setvarStep.myOutputVar'] ]  # map in the variable
                                                                          # remember, expressions require single quotes
  steps:
  - script: echo $(myVarFromJobA)
    name: echovar

Upvotes: 3

Related Questions