Create an automatic PR and complete it Azure DevOps - azure-devops

I'm trying to create a flow where when a PR from branch a -> b is completed, an automatic PR from branch c -> d is created and completed.
I looked in this question but it doesn't mention auto complete
CI/CD pipelines Azure devops automatic merge after deploy release
Also, can I set a specific policy to the automated PR so it would be auto complete?
Update
I tried using the following call:
https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull%20requests/update?view=azure-devops-rest-5.1
But I got the error:
Invoke-RestMethod : {"$id":"1","innerException":null,"message":"Invalid argument value.\r\nParameter name: Invalid
pull request auto complete set by id. Valid values are either the current user identity id, or an empty guid (to unset
auto complete)."
I tried to get the creator ID from the response but it's empty.
I tried to assign Project Collection Build Service (msazure) like I saw here:
https://developercommunity.visualstudio.com/content/problem/298596/autocompletesetby-ignored-in-pull-request-rest-api.html
But I'm getting the error.

After you create the PR you can get the creator ID:
$response = Invoke-RestMethod -Uri $url -Method Post -Headers $head -Body $jsonBody -ContentType "application/json;charset=UTF-8"
$currentUserId = $response.createdBy.id
And send him in the update json body:
$body = #{
autoCompleteSetBy = #{ id = "$buildUserId" }
completionOptions = ""
}
$response = Invoke-RestMethod -Uri $url -Method Patch -Headers $head -Body $jsonBody -ContentType application/json

Here after creation of PR, run the update operation to set Autocomplet. Check the below link
https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull%20requests/update?view=azure-devops-rest-5.1

Related

Managing branches with Azure DevOps Classic Build Pipelines and TFVC

How do you manage building from branches when using Azure DevOps Classic Build Pipelines and TFVC?
I believe that the only viable option is to copy the build pipeline with a new name and update the source code mapping to point to the new TFVC branch.
I see the ADO web UI provides the option to clone an individual build definition, yet as I have over 200+ build pipelines to clone whenever I branch is there a more efficient way to do this? Or is the only option to write a custom tool to leverage the ADO REST Api?
Since you need to clone pipelines in batches, using scripts to run the Rest API will be a reasonable method. As far as I know, there is no easy way out of the box other than this.
You could try the following PowerShell Script Sample:
$DefinitionIds = "PipelineIDs" #InPut All Pipelineids(e.g. "324,323,xxx" )
$DefinitionId = $DefinitionIds.split(",");
$token = "PAT Token"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))
foreach ($i in $DefinitionId)
{
echo $i
$url="https://dev.azure.com/{OrganizationName}/{ProjectName}/_apis/build/definitions/$($i)?api-version=6.0"
$response = Invoke-RestMethod -Uri $url -Headers #{Authorization = "Basic $token"} -Method Get -ContentType application/json
Write-Host "$($response | ConvertTo-Json -Depth 100)"
$response.repository.properties.tfvcMapping= '{"mappings":[{"serverPath":"$/TFVCBranchName","mappingType":"map","localPath":"\\"}]}' # ServerPath is the Branch name
$response.repository.name = "TFVCRepoName" #Repo Source Name
$response.name = "Pipeline $i Clone" # Cloned PipelineName
echo $response.name
$url1= "https://dev.azure.com/{OrganizationName}/{ProjectName}/_apis/build/definitions?api-version=6.0"
$json = #($response) | ConvertTo-Json -Depth 100
$response1 = Invoke-RestMethod -Uri $url1 -Headers #{Authorization = "Basic $token"} -Method Post -Body $json -ContentType application/json
}
Here are the Two Rest APIs used in the Script:
Definitions - Get
Definitions - Create
Result:
The cloned Pipeline will be set to the new TFVC branch and Build definition name.

How can I read the PR tag inside a pipeline triggered by another pipeline?

I had my first question answered here Is it possible to read the PR tag on a pipeline task? but my scenario is a little bit different. I need to read the PR tag from a pipeline that was triggered by another pipeline.
PR triggers the CI which checks if everything's ok for merge. If it is, the CI triggers the CD which will in turn read the PR tag.
PR -> CI -> CD (access the tag here)
I have a PowerShell task named Get PR tag with the following script (courtesy of Lance):
$url = "$($env:SYSTEM_TEAMFOUNDATIONSERVERURI)$env:SYSTEM_TEAMPROJECTID/_apis/git/repositories/$($env:BUILD_REPOSITORY_NAME)/pullRequests/$($env:SYSTEM_PULLREQUEST_PULLREQUESTID)/labels?api-version=5.1-preview.1"
$response = Invoke-RestMethod -Uri $url -Method Get -Headers #{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
Write-Host "##vso[task.setvariable variable=PullRequestTag;isOutput=true]$($response.value.name)"
But I keep getting "The request is invalid.":
========================== Starting Command Output ===========================
/usr/bin/pwsh -NoLogo -NoProfile -NonInteractive -Command . '/home/vsts/work/_temp/74b14931-e33a-4389-b19f-3db7faa53e8d.ps1'
Invoke-RestMethod: /home/vsts/work/_temp/74b14931-e33a-4389-b19f-3db7faa53e8d.ps1:3
Line |
3 | $response = Invoke-RestMethod -Uri $url -Method Get -Headers #{
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| {"count":1,"value":{"Message":"The request is invalid."}}
##[error]PowerShell exited with code '1'.
Finishing: Get PR tag
My agent job is set to use the OAuth token:
Update
In release pipeline, the variable name is not the same as the variable name in build, we need update the url info in the script, we can also check the release pipeline variable in the Initialize job log.
Steps:
a. Configure branch policy and add the policy Build Validation-> add build pipeline A
b. Create release->select the build A as the Source type->Enable the feature Pull request trigger->open Pre-deployment conditions and enable the option Pull request deployment
c. Open the release->enable the feature Allow scripts to access the OAuth token (Click Agent Job Name=>Additional options) add task powershell and enter the script below
$url = "$($env:SYSTEM_TASKDEFINITIONSURI)$env:BUILD_PROJECTID/_apis/git/repositories/$($env:BUILD_REPOSITORY_NAME)/pullRequests/$($env:BUILD_PULLREQUEST_ID)/labels?api-version=5.1-preview.1"
$response = Invoke-RestMethod -Uri $url -Method Get -Headers #{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
Write-Host "##vso[task.setvariable variable=PullRequestTag;isOutput=true]$($response.value.name)"
d. Configure the Reference name as PS and add task cmd to output the tags.
CMD script:
echo $(PS.PullRequestTag)
e. Create pull request and add tags
Result:
Update2
The pull request triggers the CI build pipeline(power shell), after the build pipeline is completed, another build pipeline(power shell test) will be triggered.
b. Open the build pipeline power shell test and add a new variable PullRequestID and grant test Build Service (xxx) account the Edit build pipeline permission. (open the build pipeline(power shell test)--> ... --> Security --> Edit build pipeline set to Allow)
c. enable the feature Allow scripts to access the OAuth token (Click Agent Job Name=>Additional options) add task powershell(Get the tag value) and enter the script below. click the powershell task->Output Variables->enter PS->add a task cmd and use the code echo $(PS.PullRequestTag) to output the tag value
$url = "$($env:SYSTEM_TEAMFOUNDATIONSERVERURI)$env:SYSTEM_TEAMPROJECTID/_apis/git/repositories/$($env:BUILD_REPOSITORY_NAME)/pullRequests/$(PullRequestID)/labels?api-version=5.1-preview.1"
$response = Invoke-RestMethod -Uri $url -Method Get -Headers #{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
Write-Host "##vso[task.setvariable variable=PullRequestTag;isOutput=true]$($response.value.name)"
d. Open build pipeline power shell, enable the feature Allow scripts to access the OAuth token (Click Agent Job Name=>Additional options) add task powershell and enter the script below to update the pipeline(power shell test) variable PullRequestID value.
$url = "$($env:SYSTEM_TEAMFOUNDATIONSERVERURI)$env:SYSTEM_TEAMPROJECTID/_apis/build/definitions/55?api-version=5.1"
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 PullRequestID to its new value pull request ID
$pipeline.variables.PullRequestID.value= $($env:SYSTEM_PULLREQUEST_PULLREQUESTID)
####****************** 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 'PullRequestID ' is updated to" $updatedef.variables.PullRequestID.value
write-host "=========================================================="

Capture commit count per pull request in Azure DevOps

I would like to get info on the number of commits per pull request. For now, semi-automated would be fine. Just looking for a simple approach, say, a PowerShell script. I'll likely need to create similar types of reports with different data in the future.
Does any approach lend itself to such a quick and dirty approach with Azure DevOps data?
There is a special Rest API for this: Pull Request Commits - Get Pull Request Commits:
GET https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/pullRequests/{pullRequestId}/commits?api-version=5.1
So, simple PowerShell script:
$pat = "YOUR-PERSONAL-ACCESS-TOKEN"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,"$pat")))
$headers = #{Authorization=("Basic {0}" -f $base64AuthInfo)}
$url = "https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/pullRequests/{pullRequestId}/commits?api-version=5.1"
$commitsCount = (Invoke-RestMethod -Method Get -Uri $url -Headers $headers -Body $jsonBody -ContentType 'application/json').count

How to get status of the release (success, failure) with powershell using Azure DevOps Rest API

I am using post method to create release in Azure DevOps:
$url = "https://vsrm.dev.azure.com/"+$organization+"/"+$project+"/_apis/release/releases?api-version=5.1"
$body = #{definitionId = 9} | ConvertTo-Json -Depth 4
Invoke-RestMethod -Uri $url -Method POST -Body $body -ContentType "application/json" -Headers #{Authorization = ("Basic {0}" -f $base64AuthInfo)}
My pipeline is simple with single stage which executes automatically. Release creation and execution works fine.
But how to get status of my stage/s using powershell and REST API. I need to keep executing script while Release is in progress and initiate script failure if any of the stages fails.
Any ideas?
Using DefinitionID and EnvironmentIDs (you will get this from your initial POST response), you can query the last release and check for "deploymentStatus" value in intervals and exit when the status changes to "succeeded/failed/cancelled".
(collectionURL)/(teamproject)/_apis/Release/deployments?definitionId="+RELEASE_DEFINITIONID+"&definitionEnvironmentId="+RELEASE_DEFINITIONENVIRONMENTID?api-version=1.0

VSTS REST API - Updating a release

I'm trying to automated the tagging of VSTS releases, using the REST API documented here, using PowerShell, and it seems like it's impossible to add / edit Release tags using the API.
I'm able to GET a release OK using:
$release = Invoke-RestMethod -Method GET -Uri $releaseUri -Headers $headers
But when I try to update the release, I either get an error, or the tags remain unchanged. I'm trying to set the release to be retained, and to be tagged with a semantic version number, so first I tried, as the docs say, a PUT request:
$body = ConvertTo-Json #{ keepForever = "true"; tags = #($semanticVersion)}
Invoke-RestMethod -Method PUT -Uri $releaseUri -Headers $headers -ContentType "application/json" -Body $body
Which gives an error:
"VS402892: The ID of the release does not match the ID of the original
release resource. Ensure that you are trying to update the correct
resource."
If I try adding the ID to match, it says I need a name, if I add a name I get an error
"VS402886: Adding or deleting environments from the release is not
allowed."
So it seems like it needs ALL of the release info to be provided in the body to work..? So I instead try to just add the info to the Release info I got from the GET request:
$release = Invoke-RestMethod -Method GET -Uri $releaseUri -Headers $headers
$release.tags += "$semanticVersion"
$release.keepForever = "True"
$body = ConvertTo-Json $release
Invoke-RestMethod -Method PUT -Uri $releaseUri -Headers $headers -ContentType "application/json" -Body $body
Which gives the error:
"VS402897: Artifact source with alias: 'build alias' has been
modified. Field changed: 'DefinitionReference'"
I then try removing the Artifacts property from $body, and I get another error:
"VS402885: Adding or deleting artifacts from the release is not
allowed."
I've just noticed that the DefinitionReference property doesn't have any info in it - could this be what's causing the error? And why would that not be getting returned when I GET get the release?
So it just seems like at this point a PUT request isn't going to do it, so I try using PATCH instead. This seems to work better - I don't get any errors with the following:
$body = ConvertTo-Json #{ keepForever = "true"; tags = #($semanticVersion)}
Invoke-RestMethod -Method PATCH -Uri $releaseUri -Headers $headers -ContentType "application/json" -Body $body
This correctly updates the 'keepForever' property, but the tags remain unchanged. I've also tried getting the full release info with GET again, and just adding the tags, but I still get the same thing where it updates the keepForever info, but not the tags.
I've also tried using POST, but I again get the same errors as with PUT:
"VS402897: Artifact source with alias: 'build alias' has been
modified. Field changed: 'DefinitionReference'"* and *"VS402885:
Adding or deleting artifacts from the release is not allowed."
Any ideas what I'm doing wrong here? It looks like it should work to me, and I'm able to do similar operations on builds in VSTS, and it updates some properties correctly - just not tags! I'm able to add the tags manually through my browser, just not through the API.
Looks like the Tags API for releases just issues a PATCH against the Tags property of the release. Captured from the UI:
Invoke-WebRequest
-Uri "https://{account}.vsrm.visualstudio.com/{team-project}/_apis/Release/releases/{id}/tags/{tagname}"
-Method "PATCH"
-Headers
#{
"X-TFS-FedAuthRedirect"="Suppress";
"Origin"="https://{account}.visualstudio.com";
"X-VSS-ReauthenticationAction"="Suppress";
"Accept-Encoding"="gzip, deflate, br";
"Accept-Language"="nl,en-US;q=0.9,en;q=0.8,nl-NL;q=0.7";
"Accept"="application/json;api-version=5.0-preview.1;excludeUrls=true";
}
-ContentType "application/json"