2

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 ?

Krzysztof Madej
  • 32,704
  • 10
  • 78
  • 107
Nico
  • 627
  • 7
  • 23

2 Answers2

3

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
Krzysztof Madej
  • 32,704
  • 10
  • 78
  • 107
  • I didnt, if i switch to the 2019 documentation it says this Set a multi-job output variable You can't pass a variable from one job to another job of a build pipeline, unless you use YAML. – Nico Apr 17 '20 at 13:23
  • Are you sure? I changed to Azure DevopsServer 2019 and also reloaded page for that settings and they are available. – Krzysztof Madej Apr 17 '20 at 13:29
  • Try switching to the Classic build view – Nico Apr 17 '20 at 15:37
0

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

PatrickLu-MSFT
  • 49,478
  • 5
  • 35
  • 62
  • Thanks for the lengthy description. But i dont think this does what i wanted. I tried it though. I have a build with 2 jobs, the begin job which runs your script, created the named Pipeline variables as well. Then added another job which depends on the 1st job. This runs Write-Host "Key: $(Key)", which ended up in Key: DefaultValue WHen i open the definition now, the Key has value "Value". I dont want to save this value in the definition, i want to pass it to the other job, not to other builds that will run after this. – Nico Apr 20 '20 at 13:25
  • @Nico OK, get your point. What you need is just a static value. You could try to use variable group. https://learn.microsoft.com/en-us/azure/devops/pipelines/library/variable-groups?view=azure-devops&tabs=classic – PatrickLu-MSFT Apr 21 '20 at 10:11
  • No, what i need is the ability to generate a value in Job A and pass this the Job B which starts after Job A. I would expect updating one of the standard pipeline variables in the build would give that effect, but Job B continues to know the queue time variables – Nico Apr 21 '20 at 14:05
  • @Nico Sorry for the misunderstanding. 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 not change. – PatrickLu-MSFT Apr 22 '20 at 09:01
  • Hi Nico, Do you have any other concern about this issue? Just checking to see if the information provided was helpful. Were you able to resolve? – PatrickLu-MSFT Apr 24 '20 at 10:03
  • I have not upgraded to YAML yet, i am now trying to work arround the issue with publishing build artifacts, which you can then download in another job later on. – Nico Apr 24 '20 at 14:07