How to modify Azure DevOps release definition variable from a release task?
Asked Answered
R

3

7

What is the easiest way to get key rotation to work for azure storage accounts from a AzureDevOps relase task? The current plan is to re-generate the old key after release to invalidate it, and have a fresh key that can be used on next deployment. But to get that to work it seems like I at least need to store the name of the key to use in a release variable.

I had a look at he logging tasks (https://github.com/Microsoft/azure-pipelines-tasks/blob/master/docs/authoring/commands.md), but that only changes the value in the current release and does not modify the release definition.

Rigdon answered 29/10, 2018 at 9:40 Comment(1)
Works, but only takes effect when all the stages in the release pipeline are completed. The predeployment script in the pipeline picks up the old value of the definition variables.Shawna
M
27

You can use the REST API (Definitions - Update) to update the value of the release definition variable from a release task.

  1. Go to the Agent Phase and select Allow Scripts to Access OAuth Token. See Use the OAuth token to access the REST API
  2. Grant Project Collection Build Service (xxx) account the edit release pipeline permission. (Select the release pipeline --> ... --> Security --> Edit release definition set to Allow)
  3. Add a PowerShell task in your release pipeline
  4. Run inline script: (Update the value of variable v1030 in below sample)

    $url = "$($env:SYSTEM_TEAMFOUNDATIONSERVERURI)$env:SYSTEM_TEAMPROJECTID/_apis/Release/definitions/$($env:RELEASE_DEFINITIONID)?api-version=5.0-preview.3"
    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 named v1030 to its new value 1035
    $pipeline.variables.v1030.value = "1035"
    
    ####****************** 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 'v1030' is updated to" $updatedef.variables.v1030.value
    write-host "=========================================================="
    

enter image description here

Magnoliamagnoliaceous answered 30/10, 2018 at 8:27 Comment(3)
It worked great for all my test releases, but the production release keeps throw 400 bad request when doing the PUT request to update the release definition. Any suggestions on what might be wrong here or how to figure out what is wrong? Even posting the original response without modifying it fails for this release definition...Rigdon
@Andy Li-MSFT, above solution effects when all the tasks are completed in the stage. Do we have any alternative way to pass the values from one agent to another agent in same stage?Kaon
I am getting the error "##[error]The property 'value' cannot be found on this object. Verify that the property exists and can be set.", when i tried this approach. I hope we can set predefined variables using this script. I used the same variable 'v1030' in the script above. Not sure what i am missing...!Ailssa
E
0

Here is a much cleaner and better solution that also allows for multiple builds being triggered simultaneously. https://tsuyoshiushio.medium.com/how-to-pass-variables-with-pipeline-trigger-in-azure-pipeline-5771c5f18f91

Essentially your triggering build produces artifacts that your triggered build reads and turns into variables.

Still not at all great, but better than nothing and better than REST calls setting static global variable groups.

Edris answered 15/7, 2021 at 20:43 Comment(1)
I believe the OP is asking about release rather than build pipelines, which doesn't seem to offer this supportMonospermous
D
0

The other answer above talks about how to update Release pipelines.

If you would like to update a Build Pipeline's variables, here is how you do that:

  • Edit build pipeline
    • Go to the Agent Phase and select Allow Scripts to Access OAuth Token. See Use the OAuth token to access the REST API

    • Go to Manage Security -> Users -> Select Project Collection Build Service (YOUR TEAM NAME HERE)

      • Change "Edit Build Definitions" to Allow
    • Now add a powershell stage - 2.x - inline script called Update variables.

Script inline contents:

$api_version='5.0-preview.6'
$url = "$($env:SYSTEM_TEAMFOUNDATIONSERVERURI)$env:SYSTEM_TEAMPROJECTID/_apis/build/definitions/$(System.DefinitionId)?api-version=${api_version}"
Write-Host "URL: $url"
$pipeline = Invoke-RestMethod -Uri $url -Headers @{
    Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
Write-Host "Pipeline = $($pipeline | ConvertTo-Json -Depth 100)"

# Update variables as desired here:
$pipeline.variables.mavenBuildVersionPatch.value = "2401"

####****************** 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 Variable mavenBuildVersionPatch is updated to" $updatedef.variables.mavenBuildVersionPatch.value
write-host "=========================================================="

Take note of the API version in this script is 5.0-preview.6. If your version of Azure Devops is newer, you may need to update this in the future.

  • Save build pipeline.

Now when you run job, after the job completes this powershell stage, this variable will be set.

Important: If you want to update a variable then make the updated variable for other pipeline stages, then you do it with a powershell stage with the following inline script:

$mavenBuildVersionPatch = [int]"$(mavenBuildVersionPatch)"
$mavenBuildVersionPatch = $mavenBuildVersionPatch + 1
Write-Host "##vso[task.setvariable variable=mavenBuildVersionPatch;]$mavenBuildVersionPatch"

This example would take our existing patch number and increment it by 1.

This does not save the variable at the end of the job, you still need to do that with another powershell script if desired.

Deontology answered 30/1, 2023 at 16:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.