3

I am able to update the variable in the build pipeline using the below json body

        $body = '
{ 
    "definition": {
        "id": 25
    },
    "parameters": "{\"var\":\"value\"}"

}
'

The same json is not working with Release pipeline . Is there any way to pass the variable through same way through release pipeline

mystack
  • 4,910
  • 10
  • 44
  • 75

2 Answers2

7

Set Azure devops Release pipeline variable using REST API

We could use the REST API Definitions - Get to get all the info about this definition in the body, then we could update the body and use the (Definitions - Update) to update the value of the release definition variable from a release pipeline:

PUT https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions/{definitionId}?api-version=5.0

Following is my test inline powershell scripts:

$url = "https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions/{definitionId}?api-version=5.1"

Write-Host "URL: $url"
$pipeline = Invoke-RestMethod -Uri $url -Method Get -Headers @{
    Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
Write-Host "Pipeline = $($pipeline | ConvertTo-Json -Depth 100)"

# Update an existing variable named TestVar to its new value 2
$pipeline.variables.TestVar.value = "789"

####****************** 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 'TestVar' is updated to" $updatedef.variables.TestVar.value

As test result, the variable TestVar updated to 789:

enter image description here

Update:

But I want to achieve it without updating\changing the definition

The answer is yes. You could use the Releases - Create with request body:

{
  "definitionId": Id,
  "environments": [
    {
      "variables": {
        "TestVar": {
          "value": "xxxx"
        },
        "TestVar2": {
          "value": "xxxx"
        }
      },

    }
   ],
}

For more information refer the post here.

Hope this helps.

Leo Liu
  • 71,098
  • 10
  • 114
  • 135
  • But I want to achieve it without updating\changing the definition – mystack Dec 10 '19 at 05:51
  • 2
    @tjdoubts, This is totally another question, you didn't mention it at all in your original question, check my updated answer. – Leo Liu Dec 10 '19 at 07:08
  • @LeoLiu-MSFT, this is great. Perfectly works! But do why assemblies that wraps REST APIs have so much limitations? E.g. for variables manipulation (reason why I'm here!). Anyway, thank you. – gsscoder Jun 12 '20 at 06:19
  • @LeoLiu-MSFT please update your question and remove the non relevant part to the question or at least change the order. This would make a lot more sense – Eugen Mayer Dec 29 '20 at 15:06
1

Old topic, but there is a better way now and I believe it deserves a new answer (maybe it was even available since the very beginning, don't know.)

Instead of updating the very definition of the pipeline which only works for future releases, you can now update the currently running release only and that solves your problem.

This is how I set up the tasks in the pipeline:

enter image description here

And here's a snippet from the Powershell task: (it updates delay_minutes release variable based on deploy_time variable which specifies time in HH:mm format)

if(!"$(deploy_time)") {
  Write-Host "deploy_time empty, won't delay deployment"
  return
}

$url = "$(System.TeamFoundationServerUri)/$(System.TeamProjectId)/_apis/release/releases/$(Release.ReleaseId)?api-version=5.0"

# Uncomment for debugging
# Write-Host "URL: $url"

$delayMinutes = [int](New-TimeSpan -start (Get-Date) -end "$(deploy_time)").TotalMinutes

if($delayMinutes -lt 0) { $delayMinutes = 0 }

$pipeline = Invoke-RestMethod -Uri $url -Method Get -Headers @{
    Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}


# Uncomment for debugging
# Write-Host "Pipeline = $($pipeline | ConvertTo-Json -Depth 100)"

$pipeline.variables.delay_minutes.value = $delayMinutes

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

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

The URL in the snippet uses only always available predefined variables so it should be 100% copy-pastable. Also make sure to set this on the first agent job:

enter image description here

So that the SYSTEM_TOKEN variable is available in the script.