Set Azure devops Release pipeline variable using REST API - azure-devops

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

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:
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.

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:
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:
So that the SYSTEM_TOKEN variable is available in the script.

Related

azure devops release pipeline , bulk edit

$Organization = "y"
$Project = "x"
$DefinitionID = "81"
$url = "https://dev.azure.com/$Organization/$Project/_apis/build/definitions/$DefinitionID?api-version=6.0"
Write-Host "URL: $url"
$pipeline = Invoke-RestMethod -Uri $url -Headers #{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
Write-Host "Pipeline = $($pipeline | ConvertTo-Json -Depth 100)"
$pipeline.variables.v1030.value = "xyz"
####****************** 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
error:
2022-03-17T13:05:24.9981259Z Invoke-RestMethod : {"$id":"1","innerException":null,"message":"Build pipeline
2022-03-17T13:05:24.9982421Z 81 was not found.","typeName":"Microsoft.TeamFoundation.Build.WebApi.Definition
2022-03-17T13:05:24.9982939Z NotFoundException, Microsoft.TeamFoundation.Build2.WebApi","typeKey":"Definitio
2022-03-17T13:05:24.9983313Z nNotFoundException","errorCode":0,"eventId":3000}
Hi I get this error in Logs,
I think I can not find the release pipeline number
The $ DefinitionID
I want to do it on 100 releases pipelines I'll wrap it with 'for' later, but first I want to see I can do on one

Update Azure Devops Build Pipeline Variable with Rest API

I have an Azure Devops YAML based Build (Not Release) Pipeline. I have defined a variable called Department. My Requirement is that this variable to be updated at the end of the build using the rest API. I'm using this code.
How to modify Azure DevOps release definition variable from a release task?
The API call works fine. But I'm not sure whether this is the correct API to call. The Department will change for each build. According to the output HTTP method put is not supported.
Note: I have actually defined 5 variables including Department, Department being the last one. When the API is called it only outputs first 3 variables only.
$Department = getDepartment.ps1
$url = "https://dev.azure.com/xxx/xxx/_apis/pipelines/$(System.DefinitionId)/runs?api-version=6.0-preview.1"
$pipeline = Invoke-RestMethod -Uri $url -Headers #{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
Write-Host "Pipeline = $($pipeline | ConvertTo-Json -Depth 100)"
$pipeline.variables.Department.value = $Department
$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 'Department' is updated to $( $updatedef.variables.Department.value)"
write-host "=========================================================="
The Department will change for each build. According to the output HTTP method put is not supported.
According to the document Pipelines:
It does not provide a method for update pipeline with PUT.
To resolve this issue, you still need use the REST API Build Definitions - Update:
PUT https://dev.azure.com/{organization}/{project}/_apis/build/definitions/{definitionId}?api-version=6.0
The code sample:
$url = "https://dev.azure.com/{organization}/{project}/_apis/build/definitions/{definitionId}?api-version=6.0"
Write-Host "URL: $url"
$pipeline = Invoke-RestMethod -Uri $url -Headers #{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
Write-Host "Pipeline = $($pipeline | ConvertTo-Json -Depth 100)"
$pipeline.variables.Test.value = "$Department"
####****************** 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 'Test' is updated to" $updatedef.variables.Test.value
The test result:
When you start the pipeline using the API, you can add the values of the parameters that should be different from the default values, to the payload of the call. So you're not updating the definition, but just the value of the variables for that instance of the pipeline run.
Payload
$JSON = #"
{
"definition": {
"id":"207"
},
"parameters": "{ \"ENVIRONMENT\":\"$($config.testEnvironmentName)\", \"API_CLIENT_SECRET\":\"$($config.testEnvironmentApiClientSecret)\" }"
}
"#
Note that the 'parameters' property has a value as an escaped json string.
This is the API that I use to start the pipeline.
/_apis/build/builds?api-version=7.1-preview
Use a 'POST' method and send the json as the body of the request (content-type application/json).

How to delete variable in azure devops release through powershell

I have azure DevOps release and I would like to delete release variables post one stage of deployment. could you please provide some pointers on how to do this? I know how to update the value of the variable using API but am unable to delete the variable. Any pointers are highly appreciated
To delete the release pipeline variable during the release process, you could use the Definitions - Update Rest API.
Here is the PowerShell example:
$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"
}
$pipeline.variables.PSObject.Properties.Remove('variablename')
####****************** 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 'test' is deleted"
write-host "=========================================================="
The following code is used to delete the variable.
$pipeline.variables.PSObject.Properties.Remove('variablename')
For more detailed info, you could refer to this ticket: How to modify Azure DevOps release definition variable from a release task?

Set tfs build variables via powerShell

To queue a build i use this ps script
param (
[string]$definitionName = "",
[string]$testFilter = ""
)
$rootTfsUri = "rootUri"
$collectionName = "CollectionName"
$projectName = "ProjName"
$tfsUri = $rootTfsUri + "/" + $collectionName + "/" + $projectName
$buildDefinition = "WebTesting-Regress-" + $definitionName
$buildDefinitionUri = "$tfsUri/_apis/build/definitions?api-version=3.1&name=$buildDefinition"
# first get build definition id
$buildResponse = Invoke-WebRequest -Uri $buildDefinitionUri -UseDefaultCredentials -Method Get -Verbose -UseBasicParsing -ContentType "application/json"
$buildResponseAsJson = $buildResponse.Content | convertfrom-json
$buildDefinitionId = $buildResponseAsJson.value.id
# Now queue this build definition
$requestContentString = #"
{
"definition": {
"id" : "$buildDefinitionId"
},
"variables": {
"testFilter": {
"value": "$testFilter"
}
}
}
"#
$buildUri = "$tfsUri/_apis/build/builds?api-version=3.1"
$buildResponse = Invoke-WebRequest -Uri $buildUri -UseDefaultCredentials -Method Post -Verbose -UseBasicParsing -ContentType "application/json" -Body $requestContentString
$buildNumber = ($buildResponse.Content | ConvertFrom-Json).buildNumber
it works good but i need to change build variable before my test started, how can i do this?
i've tried to send it with id in body but it didn't works
VariablesExample
You could use Logging Commands to set value during your build pipeline. ##vso[task.setvariable variable=testvar The first task can set a variable, and following tasks in the same phase are able to use the variable. The variable is exposed to the following tasks as an environment variable.
Define and modify your variables in a script
To define or modify a variable from a script, use the task.setvariable
logging command. Note that the updated variable value is scoped to the
job being executed, and does not flow across jobs or stages. Variable
names are transformed to uppercase, and the characters "." and " " are
replaced by "_".
For example, Agent.WorkFolder becomes AGENT_WORKFOLDER. On Windows,
you access this as %AGENT_WORKFOLDER% or $env:AGENT_WORKFOLDER. On
Linux and macOS, you use $AGENT_WORKFOLDER.
More details please take a look at this tutorial Define and modify your variables in a script You could also look at this blog: Use Azure DevOps Variables Inline powershell in build and release pipelines
$definition = Invoke-RestMethod -Method Get -Uri "https://tfs-app/tfs/[COLLECTIONNAME]/[PROJECTNAME]/_apis/build/definitions/BUILDID?api-version=2.0" -UseDefaultCredentials
$definition.variables.[VARIABLENAME].value = [NEWVALUE]
$json = $definition | ConvertTo-Json -Compress -Depth 100
$updatedef = Invoke-RestMethod -Method Put -Uri "https://tfs-app/tfs/[COLLECTIONNAME]/[PROJECTNAME]/_apis/build/definitions/BUILDID?api-version=2.0" -UseDefaultCredentials -Body $json -ContentType "application/json; charset=utf-8"
Now just queue your build.

Post Method - Changing a Nested Value

I am trying to change a value - specifically a variable - of one of my TFS 2017 builds. To my understanding, Patch is not supported at all. I can successfully queue a build with the Post method and I am trying to use the same command change a value as well.
When I run the Get method, I have:
*A bunch of text*
"variables": {
"system.debug": {
"value": "false",
"allowOverride": true
},
"BuildVersion": {
"value": "ValueIWantToChange"
}
},
*A bunch of text*
I need to change the Build Version and everything else will stay the same. My body in Postman looks like:
{
"Variables":
{
"BuildVersion":
{
"value": NewValue
}
}
}
When I run this in Postman, I get this error:
"Value cannot be null.\r\nParameter name: definition.Repository"
Could anyone tell me where I am going wrong or if this is possible using another method?
Seems you want to update the build definition base on you description.
To update the build definition with the REST API you need to use PUT method, please see Definitions - Update Definition for details.
Get the build definition first:
GET http://server:8080/tfs/DefaultCollection/ScrumProject/_apis/build/definitions/6?api-version=3.2
Copy all the json response from the first step as the request body,
then change the value of the specific variable which you want to be
modified.
PUT http://SERVER:8080/tfs/DefaultCollection/ScrumProject/_apis/build/definitions/6?api-version=3.2
Content-Type: application/json
Note that you need to provide the latest revision in request body:
UPDATE:
You can also use PowerShell by calling the REST API to update the specific variable value, just try below sample: (the variable name is lctest in below sample, you just need to replace it with your own variable name.)
Param(
[string]$collectionurl = "http://server:8080/tfs/DefaultCollection",
[string]$project = "ProjectName",
[string]$definitionid = "6",
[string]$user = "username",
[string]$token = "password"
)
# Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
#Get build definition
$defurl = "$collectionurl/$project/_apis/build/definitions/$($definitionid)?api-version=3.2"
$definition = Invoke-RestMethod -Uri $defurl -Method Get -UseDefaultCredential -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
#Set new value for the specific variable
$definition.variables.lctest.value = "1.0.0.4"
$json = #($definition) | ConvertTo-Json -Depth 99
#Update the definition
$updatedef = Invoke-RestMethod -Uri $defurl -Method Put -Body $json -ContentType "application/json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
write-host $definition.variables.lctest.value
I figured out my problem awhile back and forgot to update. My initial task was to get the API for octopus so this is the long version. If youre only interested in the REST commands, refer to the last section of code. Just wanted to add the rest in for extra context.
#Create a folder
if(test-Path C:\Test){}
else{
new-item -path "C:\" -name "Test" -ItemType "directory"}
$encodedPAT = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":$TFSAPIKeyForAutomatedBuild"))
$GetURI = "$MyURI"
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Basic $encodedPAT")
[string]$Global:ChangeVersion = [version]$OctopusParameters["Octopus.Action[Deploy Package].Package.NuGetPackageVersion"]
write-host $ChangeVersion
$GetBuildresponse = Invoke-RestMethod -Method Get -header $headers -ContentType "application/json" -Uri $GetUri
write-host $GetBuildResponse
$y = convertTo-json $GetBuildresponse -depth 99 | Out-file -FilePath "C:\test\FromPostmanCopy.json"
$z = (get-content "C:\test\FromPostmanCopy.json") | select-string -pattern '(?<=value": "2.)(.*)(?=")' | % { $_.Matches} | % { $_.value }
Write-Host $z
$Content = (Get-Content "C:\Test\FromPostmanCopy.json")
$content -replace "2.$z", $changeVersion | out-file "C:\Test\FromPostmanCopy.json"
$Content = (Get-Content "C:\Test\FromPostmanCopy.json")
$Buildresponse = Invoke-RestMethod -URI $GetURI -Method Put -header $headers -Body $content -ContentType application/json