Passing variables from stage to stage in Azure DevOps release

If you have ever wanted to pass variables between the stages of your release this post will show you how. Using VSTeam you can update or add variables to your release with just a few lines of PowerShell. With PowerShell now being cross platform, this means you can do this from our hosted macOS, Linux or Windows agents.

It is important to point out you are changing the variables for a release and not the release definition itself. Any variables added are only added to the release and will not appear on the release definition. Also, any changes to values will only affect the release.

The key to all of this is REST API provided by Azure DevOps. The REST API provides calls to update a release which gives us access to the variables of that release. The icing on the cake is VSTeam. VSTeam is a PowerShell module that has already wrapped the required API calls to get and update a release.

To demonstrate I will create a release definition with two stages.

clip_image002

In Stage 1 I will install VSTeam and use it to get the current release, update one variable and add another and then update the release. I will do all of this from a single Inline PowerShell task.

image

The code for the task is below.

   1:  Install-Module VSTeam -Scope CurrentUser -Force
   2:  Set-VSTeamAccount –Account $(Acct) -PersonalAccessToken $(PAT)
   3:  $r = Get-VSTeamRelease -ProjectName "$(System.TeamProject)" `
             -Id $(Release.ReleaseId) -Raw
   4:  $r.variables.test.value = 'Set In Stage 1'
   5:  $r.variables | Add-Member NoteProperty `
             temp([PSCustomObject]@{value='Created in Stage 1'})
   6:  Update-VSTeamRelease -ProjectName "$(System.TeamProject)" `
             -Id $(Release.ReleaseId) -Release $r -Force


Let’s break down the code above.

On line 1 we are installing the VSTeam module on the agent. Be sure and set the Scope parameter to CurrentUser or you will get an error trying to install the module globally. You also need to add the Force switch to prevent any confirmations.

On line 2 we are connecting to the desired account using a personal access token. This is very important. Although VSTeam supports using the Access Token from AzD with Bearer authentication the token does not have enough permission to update a release. Therefore, you must create a personal access token that has the correct permissions. Store the personal access token as a secured variable in your release definition. Also create a variable named “Acct” that holds the name of the AzD organization you are running this release from. Lastly, add a variable named “Test” that we will update in the release.

clip_image001

 

UPDATE (7/19/2019):

After Stefan Stranger blogged he could not get my steps to work I tested the pipeline I used to create this post and it still worked. However, when I tried to follow this blog on a different pipeline in a different organization I was getting strange errors. The problem was the permissions. After reading Stefan’s post I started looking for permission issues and found them. If you make sure your ‘Team Module Build Service has the following permissions you can use the bearer token option of VSTeam and no longer need a PAT.

image

End of UPDATE

On line 3 we are getting the release we are running by using the predefined variables provided by AzD. The first variable we need is System.TeamProject. This gives us the name of the project we are running inside. The second variable is Release.ReleaseId which returns the id of the release. Finally, we must provide the Raw switch. This switch instructs the function to not modify the output in anyway. That way it can be returned to AzD in the update call. Without the Raw switch you will be returned a VSTeam.Release object. This object even when converted to JSON will not be the required shape to send back to AzD.

On line 4 we simply update an existing variable to a new value.

On line 5 we are adding a new variable named ‘temp’ to the release and setting its value to ‘Created in Stage 1’.

Finally, on line 6 we send the object back to AzD using the Update-VSTeamRelease function passing in the modified release.

Now, in the second stage of the release I will use PowerShell to simply output the values.

   1:  Write-Host $(Test)
   2:  Write-Host $(Temp)

Notice we are using the $(VariableName) format. This is very important. I often see people trying to access release variables as if they are PowerShell variables (omitting the parenthesis) which they are not. The name must be wrapped in parenthesis. Below is the log output from Stage 2.

2019-06-08T02:42:12.4564565Z Set In Stage 1
2019-06-08T02:42:12.4565202Z Created in Stage 1

Comments (7) -

  • Jason Gaylord

    6/10/2019 5:23:31 PM | Reply

    Thanks for posting this Donovan. So, if I wanted to get a value in an agent phase of a particular stage, would that value be present in an agentless phase for a REST call to the Azure API?

  • Vygis

    6/12/2019 10:51:54 AM | Reply

    I'm getting the following error when following the steps on AzD using HostedVS2017 agents:

    Invoke-RestMethod : {"$id":"1","innerException":null,"message":"VS402987: Deploy job 'first agent' in stage 'Stage 1' cannot be modified while it is in-progress. Changes were detected in the following properties: 'WorkflowTasks'.","typeName":"Microsoft.VisualStudio.Services.ReleaseManagement.Data.Exceptions.InvalidRequestException, Microsoft.VisualStudio.Services.ReleaseManagement2.Data","typeKey":"InvalidRequestException","errorCode":0,"eventId":3000}

    Is it actually possible to update variables when the release is in progress?

  • Stefan Stranger

    6/21/2019 1:18:27 PM | Reply

    I followed your steps but I'm getting the following error back:

    2019-06-21T13:16:05.4130580Z Invoke-RestMethod : {"$id":"1","innerException":null,"message":"VS402987: Deploy job 'Agent job' in stage 'Stage 1'
    2019-06-21T13:16:05.4131164Z cannot be modified while it is in-progress. Changes were detected in the following properties: 'WorkflowTasks'.","typeN
    2019-06-21T13:16:05.4131398Z ame":"Microsoft.VisualStudio.Services.ReleaseManagement.Data.Exceptions.InvalidRequestException, Microsoft.VisualStudio
    2019-06-21T13:16:05.4131552Z .Services.ReleaseManagement2.Data","typeKey":"InvalidRequestException","errorCode":0,"eventId":3000}
    2019-06-21T13:16:05.4131764Z At C:\Users\VssAdministrator\Documents\WindowsPowerShell\Modules\VSTeam\6.2.6\Private\common.ps1:625 char:12
    2019-06-21T13:16:05.4131911Z +    $resp = Invoke-RestMethod @params
    2019-06-21T13:16:05.4132052Z +            ~~~~~~~~~~~~~~~~~~~~~~~~~
    2019-06-21T13:16:05.4132216Z     + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
    2019-06-21T13:16:05.4132358Z    eption
    2019-06-21T13:16:05.4133298Z     + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

  • Carsten

    6/26/2019 10:51:17 AM | Reply

    Hi, why not use the "system" token?
    [x] Allow scripts to access OAuth token

    System.AccessToken

    • Donovan

      7/14/2019 6:23:49 PM | Reply

      When I tried that the system token did not have permissions to change the values.

  • Swathi

    8/2/2019 10:38:28 AM | Reply

    Hi,
    Whenever I try to print the object "r" the output is very weird in html format.
    Due to which I am not able to update value for my release variable "test"
    Error is as below :
    2019-08-02T09:42:50.3977360Z The property 'value' cannot be found on this object. Verify that the property exists and can be set.
    2019-08-02T09:42:50.3977943Z At C:\agent\_work\_temp\a4044201-b1bc-411c-b05d-14242f16a704.ps1:5 char:1
    2019-08-02T09:42:50.3978131Z + $r.variables.test.value = 'Set In App 1'
    2019-08-02T09:42:50.3978227Z + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    2019-08-02T09:42:50.3978370Z     + CategoryInfo          : InvalidOperation: (Smile [], ParentContainsErrorRecordException
    2019-08-02T09:42:50.3978475Z     + FullyQualifiedErrorId : PropertyNotFound

  • MIchelle

    8/15/2019 2:28:29 PM | Reply

    Incase anyone else runs into the error:The string is missing the terminator: ".

    If you copy & pasted code from here, delete and re-type your dashes: https://stackoverflow.com/a/20706950/6446063

    This got me for a while so incase anyone else runs into it...

Add comment

Loading