Powershell script Trigger an release pipeline using Devops API - azure-devops

I am trying to create a Powershell script create a new release using DevOps API.
I can see the pipeline information using invoke rest method but not able to trigger a pipeline. Can I get some assistance here.?
Thanks,
Venkatraman

It's not documented very well, but to start the release you have to update the status to inProgress.
$updateReleaseUri = "$($vrsmBaseUri)_apis/Release/releases/$($releaseId)/environments/$($environmentId)?api-version=6.0-preview"
$updateReleaseJsonBody = #{status = 'inProgress' }
$updateReleaseJsonBody = $updateReleaseJsonBody | ConvertTo-Json -Depth 100
Invoke-RestMethod -Uri $updateReleaseUri -Method Patch -Headers $headers -Body $updateReleaseJsonBody -ContentType 'application/json'
Ref: https://learn.microsoft.com/en-us/rest/api/azure/devops/release/releases/update-release-environment?view=azure-devops-rest-6.0

You can use the specific endpoint "Releases - Create" to trigger the release pipeline.
The required parameter you need to provide at least to this endpoint is the definitionId of the release pipeline that you want to trigger.
Below is the complete PowerShell script of a demo as reference. I have tested with this script, and it can work well as expected.
$pat = '{Personal Access Token}'
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "", $pat)))
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", ("Basic {0}" -f $base64AuthInfo))
$headers.Add("Content-Type", "application/json")
$uri = "https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/releases?api-version=6.0"
$body = '{ "definitionId": {definitionId} }'
Invoke-RestMethod -Uri $uri -Headers $headers -Body $body -Method POST | ConvertTo-Json -Depth 10

Related

Jobs stuck at queue, seems running. I'm not able to cancel or delete

I'm trying to delete jobs from my queue. I didn't see cancel button at the time so I decided to delete build. After that I can't cancel or delete stucked jobs at queue. I don't have experience with rest api but tried bulk queue remove powershell script. It removes every job in queue except stucked ones.
I've tried to bulk queue delete script
$PATToken = "************************"
$AuthHeader= #{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($PATToken)")) }
$azureDevops = "https://dev.azure.com//*****"
$BuildsUrl = "$azureDevops/_apis/build/builds"
$filterBuilds = "$($BuildsUrl)?statusFilter=notStarted&api-version=6.0"
(Invoke-RestMethod -Method Get -Uri $filterBuilds -Headers $AuthHeader).value | % {
$uri = "$($BuildsUrl)/$($.id)?api-version=6.0" # Azure Devops URI
$body = '{"status":4}' # body
$result = Invoke-RestMethod -Method Patch -Uri $uri -Headers $AuthHeader -ContentType 'application/json' -Body $body -Verbose #cancel build
Write-Output "$($.definition.name) cancaled"
}
For easy use of REST API, you can use Postman.
Firstly, you can use this REST API Builds - Get to check the status and the result of your target build.
GET https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}?api-version=6.0
If your pipeline is still running, the status is inProgress.
If your build is deleted while running, the status will be completed and the result will be canceled.
At the same time, you will see information about the build being deleted, such as the date of deletion, who deleted it, and the reason for deletion.
Secondly, if the result obtained through the above REST API is that your build is still running, you can cancel the build through the REST API Builds - Update Build.
PATCH https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}?api-version=6.0
The request body should be:
{
"status": "cancelling"
}
The Powershell scripts for your reference:
$token = "<Your PAT>"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))
$url="https://dev.azure.com/<org name>/<project name>/_apis/build/builds/<build id>?api-version=6.0"
$body = #'
{
"status": "cancelling"
}
'#
$head = #{ Authorization =" Basic $token" }
$response = Invoke-RestMethod -Uri $url -Method PATCH -Headers $head -Body $body -ContentType application/json
$response | ConvertTo-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?

PowerShell Error when queuing a build via Invoke-RestMethod and put

Getting this error when trying to update a role to an endpoint using Powershell. It is crating the endpoints, just the roles update is giving error. same role update api call command works from postman.
$ApplyRole="https://Myorg/_apis/securityroles/scopes/distributedtask.serviceendpointrole/roleassignments/resources/72505f4d-564c-41cf-14508b977f52_f6a1c4f9-a043-4399-1aad7b5cf19c/?api-version=5.0-preview"
$ApplyRole = "https://Myorg/_apis/securityroles/scopes/distributedtask.serviceendpointrole/roleassignments/resources/72505f4d-564c-41cf-14508b977f52_f6a1c4f9-a043-4399-1aad7b5cf19c/?api-version=5.0-preview"
$Body1 = #{
roleName = "User"
userId = "f0e736e3-0e73-4fd2-8b7a-615126eac692"
}
$Bodyjson = $Body1 | ConvertTo-Json
Invoke-RestMethod -uri $ApplyRole -Method Put -Credential $mycreds -Body $Bodyjson -ContentType "application/json"
Error:
Invoke-RestMethod : {"$id":"1","innerException":null,"message":"Object reference not set to an instance of an object.","typeName":"System.NullReferenceException,
mscorlib","typeKey":"NullReferenceException","errorCode":0,"eventId":0}
Thanks for the reply.
Actually it was an issue with the body syntax.
Added like this and it works.
$Body1 = #"
[{
"roleName":"User",
"userId":"f0e736e3-0e73-4fd2-8b7a-615126eac692"
}]"#
Open pipeline definition->click the tab variables->add variable pat and change variable type to secret.
Add task powershell and enter the script.
$connectionToken="$(pat)"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$ApplyRole = "https://Myorg/_apis/securityroles/scopes/distributedtask.serviceendpointrole/roleassignments/resources/{project id}_{endpoint id}/?api-version=5.0-preview"
$body ="[{
`"roleName`": `"User`",
`"userId`": `"{group or user id}`"
}]"
$Roles = Invoke-RestMethod -Uri $ApplyRole -ContentType "application/json" -Body $body -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method PUT
Result:

Trigger Azure DevOps Release pipeline Stage from Spinnaker

I have created Release pipeline in Azure DevOps.
I'm doing deployment inside spinnaker. Once Deployment got success/fail, the deployment status report should be come to Release pipeline stage in Azure DevOps.
How to achieve this? Is it possible with Rest-Api?
It is possible to trigger azure devops release pipeline stage via rest api.
You can first use Releases-Create rest api to create a release.
POST https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/releases?api-version=6.1-preview.8
If you want to trigger a specific stage in this release. You can then use Releases - Update Release Environment.
PATCH https://vsrm.dev.azure.com/{organization}/{project}/_apis/Release/releases/{releaseId}/environments/{environmentId}?api-version=6.1-preview.7
See below example in powershell script: You can follow the steps here to get a personal access token.
$url = "https://vsrm.dev.azure.com/{org}/{proj}/_apis/release/releases?api-version=6.1-preview.8"
$PAT="Personnal Access Token"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($PAT)"))
$body = '{
"definitionId": releaseDefinitionId,
}'
#Create a release
$releaseInfo = Invoke-RestMethod -Uri $url -Headers #{Authorization = ("Basic {0}" -f $base64AuthInfo)} -Method post -Body $body -ContentType "application/json"
#Trigger a specific stage
$releaseId = $releaseInfo.id
$EnvironmentIds = $releaseInfo.environments | select id
#Trigger the second stage
$EnvUrl = "https://vsrm.dev.azure.com/{org}/{proj}/_apis/Release/releases/$($releaseId)/environments/$($EnvironmentIds[1].id)?api-version=6.1-preview.7"
$envBody='{
"status": "inProgress"
}'
Invoke-RestMethod -Uri $EnvUrl -Headers #{Authorization = ("Basic {0}" -f $base64AuthInfo)} -Method patch -Body $envBody -ContentType "application/json"

How to check if a previous release has been completed before deploying a new release

As part of our release pipeline we have a task (the last task) to merge the release branch back to master.
I was wondering whether there is a way to check that this task or the previous release has completed before allowing the new release to be queued. Can a gate be used for this?
Ideally, the release manager would then be able to decide whether they want to continue with the release or to cancel.
You can't use the Invoke Rest API gate with an Azure DevOps API url because for checking the last release status you need to check the environment (stage) status, and for this, you need to the release id (so you can't know what it will be and put it in the rest API gate URL).
But, you can use PowerShell to check the last release and if it is not succeeded just fail the stage.
Add a PowerShell task in your release to check the last release:
$headers = #{ Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN" }
# Replace {org} with your organization
# Replace {project} with your project
# Replace {defId} with your release definition id
$url = "https://vsrm.dev.azure.com/{org}/{project}/_apis/release/releases?definitionId={defId}&api-version=5.1"
$releases = Invoke-RestMethod -Method Get -Uri $url -Headers $headers -ContentType 'application/json'
$releaseUrl = "https://vsrm.dev.azure.com/{org}/{project}/_apis/release/releases/$($releases.value[1].id)?api-version=5.1"
$releaseInfo = Invoke-RestMethod -Method Get -Uri $releaseUrl -Headers $headers -ContentType 'application/json'
$releaseEvnriomentId = $releaseInfo.environments.Where({ $_.name -eq 'THE STAGE NAME WHERE YOU DO MERGE' }).id
$envUrl = "https://vsrm.dev.azure.com/{org}/{project}/_apis/Release/releases/$($releases.value[1].id)/environments/$($releaseEvnriomentId)?api-version=5.1-preview.1"
$environment = Invoke-RestMethod -Method Get -Uri $envUrl -Headers $headers -ContentType 'application/json'
$envStatus = $environment.status
if($envStatus -ne "succeeded")
{
Write-Error "Previous release not succeeded!"
}
else
{
Write-Host "Previous release succeeded :)"
}
In the agent job options you need to allow scripts to access the OAuth token:
Azure functions also support PowerShell so you do it also with Azure functions gate:
1) Create a new Azure Function with VS Code like explained here.
2) In your run.ps1 file replace the code to this code:
using namespace System.Net
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)
# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."
$defnitionId = $Request.Query.DefinitionId
# Generate PAT and put it in the {YOUR PAT}
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,"{YOUR PAT}")))
$headers = #{Authorization=("Basic {0}" -f $base64AuthInfo)}
# Replace {org} with your organization
# Replace {project} with your project
$url = "https://vsrm.dev.azure.com/{org}/{project}/_apis/release/releases?definitionId=$($defnitionId)&api-version=5.1"
$releases = Invoke-RestMethod -Method Get -Uri $url -Headers $headers -ContentType 'application/json'
Write-Debug $releases
$releaseUrl = "https://vsrm.dev.azure.com/{org}/{project}/_apis/release/releases/$($releases.value[1].id)?api-version=5.1"
$releaseInfo = Invoke-RestMethod -Method Get -Uri $releaseUrl -Headers $headers -ContentType 'application/json'
Write-Debug $releaseInfo
$releaseEvnriomentId = $releaseInfo.environments.Where({ $_.name -eq 'THE STAGE NAME WHERE YOU DO MERGE' }).id
$envUrl = "https://vsrm.dev.azure.com/{org}/{project}/_apis/Release/releases/$($releases.value[1].id)/environments/$($releaseEvnriomentId)?api-version=5.1-preview.1"
$environment = Invoke-RestMethod -Method Get -Uri $envUrl -Headers $headers -ContentType 'application/json'
Write-Debug $environment
$envStatus = $environment.status
Write-Debug $envStatus
if($envStatus -ne "succeeded")
{
$status = [HttpStatusCode]::BadRequest
$body = "failed"
}
else
{
$status = [HttpStatusCode]::OK
$body = "success"
}
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]#{
StatusCode = $status
Body = $body
})
3) Publish the function to Azure.
4) Create an Invoke Azure Function gate in your release:
Another option, take the above code, convert him to C# or another language ans use Rest API, deploy to it web server and use the Invoke Rest API gate.