Get the branch name from tag using Azure DevOps api - azure-devops

Can someone help me to get the actual branch name if I have the tag associate with it?
Azure DevOps API would be best in my case. Thanks in advance.
SO far I get the API that gives all the tags for particularly repo but this does not solve my issue.
https://dev.azure.com/{{organization}}/{{project}}/_apis/git/repositories/{{repository_id}}/refs?filter=tags/&api-version=6.0
But it does not give me any branch information associated with it.

There isn’t such REST API to get branch name by a tag or commit. In the Azure DevOps, Tags are created based on the commit id, and a commit or tag can belong more than one branches. Let’s illustrate by below graph:
A---B---E---F master
\ /
C---D dev
This is a branch structure with master and dev branch. And dev branch merge into master with commit F. If you want to get the branch name based on commit D, you will get two branch names. Commit D belongs to two branch: dev (first parent) and master (second parent).
We can get the branch name via condition and multiple REST APIs, also we could get the branch name via git cmd.
a. List all tags and get the objectId.
GET https://dev.azure.com/{Org name}/{Project name}/_apis/git/repositories/{repo ID}/refs?filter=tags/&api-version=6.0
b. Get the tag info and commit ID via objectId
Note: the field taggedObject.objectId is commit ID
GET https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/annotatedtags/{objectId}?api-version=6.0-preview.1
Workaround 1
Now we could get the commit details and get the branch name(s) contain the given commit, we can use git command:
git branch --contains <commit>
Workaround 2
We could list all commits info on a branch via this API
GET https://dev.azure.com/{Org name}/_apis/git/repositories/{repositoryId}/commits?searchCriteria.itemVersion.version={branch name}&api-version=6.0
And now, we get commit id which contain the tag and all commit ID on a branch, add if{} or eq() to check it, if it return True, we could know this branch contain the tag
Update1
My test repo contains branch main and test01, the branch main contains the tag Tag01, the branch test01 contains the tag Tag01 and tag02
Power shell script:
$ListAllTagsURL="https://dev.azure.com/{Org name}/{Project name}/_apis/git/repositories/{Repo ID}/refs?filter=tags/&api-version=6.0"
$PAT="{PAT}"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($PAT)"))
$ListAllTags = Invoke-RestMethod -Uri $ListAllTagsURL -Headers #{Authorization = "Basic {0}" -f $base64AuthInfo} -Method get
#List all tags name
#write-host $ListAllTags.value.name
foreach($Tag in $ListAllTags.value){
if($Tag.name -eq "{tag name such as refs/tags/Tag01}"){
$objectId = $Tag.objectId
$TagName = $Tag.name
}
}
#Get tag details and commit ID
$TagURL="https://dev.azure.com/{Org name}/{Project name}/_apis/git/repositories/{Repo ID}/annotatedtags/$($objectId)?api-version=6.0-preview.1"
$TagInfo = Invoke-RestMethod -Uri $TagURL -Headers #{Authorization = "Basic {0}" -f $base64AuthInfo} -Method get
$TagCommitID = $TagInfo.taggedObject.objectId
#write-host $TagCommitID
#List all branch
$url="https://dev.azure.com/{Org name}/{Project name}/_apis/git/repositories/{Repo ID}/refs?filter=heads&api-version=6.1-preview.1"
$BranchInfo = Invoke-RestMethod -Uri $url -Headers #{Authorization = "Basic {0}" -f $base64AuthInfo} -Method get
foreach($Branch in $BranchInfo.value){
#write-host $Branch.name
$BranchName = $Branch.name.split("/",3)[-1]
#write-host $BranchName
#List all commit ID via Branch Name
$BranchDetailUrl="https://dev.azure.com/v-viliu/_apis/git/repositories/{Repo ID}/commits?searchCriteria.itemVersion.version=$($BranchName)&api-version=6.0"
$BranchDetailInfo = Invoke-RestMethod -Uri $BranchDetailUrl -Headers #{Authorization = "Basic {0}" -f $base64AuthInfo} -Method get
#write-host $BranchDetailInfo.value.commitId
foreach($CommitID in $BranchDetailInfo.value.commitId){
If($CommitID -eq $TagCommitID){
write-host $BranchName "Contain this tag" $TagName
}
}
}
Result:

Related

How to query multiple data for a single PR and put it a .csv file in Powershell

I am trying to query the data of a pull request from Azure Devops and put it in a conditional way to .csv file.
Step1: I am fetching PRs and associated data with it.
Step2: Querying only commitID,status,comments, Author related to a particular PR.
Step3: Need a data of all those commits IDs and comments for a single PR and like that for all the listed PRs from the step 1.
$organization = "{organization name}" // organization name
$project = "{project name}" // project name
$repo = "{repo name}" // repo name
$pat = "<PAT>"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "", $pat)))
$baseUrl = 'https://dev.azure.com/{organization}/{project}/_apis/git/repositories/pullrequests?api-version=5.1'
$response = Invoke-RestMethod -Uri $baseUrl -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method GET -ContentType 'application/json'
$response.value | Select-Object -Property pullRequestId, #{n='Author';e={$_.authoredBy.displayName}}, #{n='CommitID';e={$_.lastMergeSourceCommit.commitId}}, status, creationDate | ConvertTo-csv -NoTypeInformation -Delimiter "`t" | Out-File C:\Temp\PRData.csv
From this I can able to query the data but I am getting only single reponses like "lastSourceCommitID" will be listed for a PR, but I need the data like for a single PR need to list all the associated commitIDs/comments like that
Get Pull Requests does not support the retrieving of commits and work items. For each pull request:
Use Get Pull Request with includeCommits=true&includeWorkItemRefs=true parameters
And Pull Request Threads - List and Pull Request Thread Comments - List

Azure DevOps | TFS | Rest API | power shell script to get latest changeset description of git repository

Does anyone has power shell script to call Azure DevOps API in order to get latest changeset description of git repository?
For git repositories, it should be a commit and not a changeset. If you want to get the latest commit comments from a specific git repository, then you can try the following PowerShell script to call the REST API (Commits - Get Commits):
Param(
[string]$collectionurl = “https://dev.azure.com/{organization}", #Or specific TFS collection url
[string]$project = “ProjectName”,
[string]$repoid = “e7ad43eb-ecad-4098-93b4-b63fdf88711a”, #The specific git repository ID.
[string]$user = “”,
[string]$token = “PAT”
)
# Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
$searchCriteria = "$" + "top=1"
$Url = "$collectionurl/$project/_apis/git/repositories/$repoid/commits?searchCriteria.$searchCriteria&api-version=5.0"
$commit = Invoke-RestMethod -Uri $Url -Method Get -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
cls
$commit.value | select commitId, comment,url

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 you programmatically raise a conditional PR?

We currently have the following branch strategy:
Develop > Release > Master
Devs create a local branch from Develop, make changes merge to develop. Our dev environment builds off that branch. When they want their changes tested they push to QA environment, which also uses the Develop branch. This cycle goes on until functional testing for the iteration is done. At that point the code is merged into the Release branch and is deployed through staging and then to prod. After deploying to prod the code should be merged to Master, but it's often forgotten about. This causes problems in niche scenarios.
Is there a way to use perhaps devops pipelines to conditionally raise a PR automatically? So I'm thinking this would need 2 PRs:
PR raised for Master branch after successful release to prod. Idea here would be once sign off has been granted someone from the team can just approve.
PR raised for Develop branch if the first PR is approved and the code in Master now differs from Develop. In a lot of cases it won't as therefore wouldn't need a PR.
I've been googling for this and found the api methods like this but I can't see how you could put this in a pipeline and make it conditional.
Additional Info:
My understanding is that the build definition needs to know what branch to build as per the image below. So, creating a new release branch every sprint would either result in having to update the build definition every time or creating a new build definition, that essentially would be a complete replica in most cases except for the branch name. Unless I'm misunderstanding, which I think I am.
The following PowerShell example creates a pull request from master to some target branch as a build task. You can add it to your release as an additional stage "Create PR to some branch" with one PowerShell task. Additionally, you can create periodically build to check diff and create pull requests.
$user = ""
$token = "$(System.AccessToken)"
$branchTarget = "$(Build.SourceBranch)"
$branchSource = "refs/heads/master"
$branchTragetPath = $branchTarget -replace "refs/heads/", ""
$teamProject = "$(System.TeamProject)"
$repoName = "$(Build.Repository.Name)"
$orgUrl = "$(System.CollectionUri)"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
$uriBranchStatus = "$orgUrl/$teamProject/_apis/git/repositories/$repoName/stats/branches?name=$branchTragetPath&api-version=5.1"
$uriCheckActivePR = "$orgUrl/$teamProject/_apis/git/repositories/$repoName/pullrequests?searchCriteria.targetRefName=$branchTarget&searchCriteria.sourceRefName=$branchSource&api-version=5.1"
$uriCreatePR = "$orgUrl/$teamProject/_apis/git/repositories/$repoName/pullrequests?api-version=5.1"
$resultStatus = Invoke-RestMethod -Uri $uriBranchStatus -Method Get -ContentType "application/json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
if ($resultStatus.behindCount -eq 0)
{
Write-Host "Current branch contains last changes from master"
Return
}
$resultActivePR = Invoke-RestMethod -Uri $uriCheckActivePR -Method Get -ContentType "application/json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
if ($resultActivePR.count -gt 0)
{
Write-Host "PR exists already"
Return
}
$bodyCreatePR = "{sourceRefName:'$branchSource',targetRefName:'$branchTarget',title:'Sync changes from $branchSource'}"
$result = Invoke-RestMethod -Uri $uriCreatePR -Method Post -ContentType "application/json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Body $bodyCreatePR
Write-Host "Created PR" $result.pullRequestId

Create an automatic PR and complete it 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