Azure Yaml Pipeline - Update Workitems from multiple Repositories - azure

In a nutshell, I am looking to get a list of work items linked to a git branch.
In more detail
I am working with 4 repositories that I add as resources to my pipeline
- repository: Cms # code repository
name: <ProjectName>/Cms
type: git
ref: develop2022
- repository: QA-Automation # Automated Testing Repo
name: <ProjectName>/QA-Automation
type: git
ref: main
- repository: TdsWDPExplorer # Generate Reports Repo
name: <ProjectName>/TdsWDPExplorer
type: git
ref: master
The Pipeline yaml files them self's are in the 4th Repo and checked out as self
- checkout: Self
path: s/DE-DevOps
I am trying to update the work items associated with the Cms Repository.
I tried using the Workitem Updater task https://marketplace.visualstudio.com/items?itemName=BlueBasher.bluebasher-workitemupdater
But it only sees the workitems associated with the Repository holding the yaml Files (Self).
I also looked at the API to get a list of the work items.
_apis/git/repositories//refs?filter=heads%2fBRANCHNAME&includeLinks=true
Gives me details to a branch but I didn't find the linked work items
Also looking at the workitem I dint see that info
_apis/wit/workitems?ids=ITEM-ID's&$expand=all&api-version=6.0
I am thinking it might be somewhere in _apis/wit/reporting/workitemlinks but haven been able to get the info.

I found a answer that works for me, in a response to Obtain all work items from Azure DevOps that have been merged into a branch via JavaScript
we link the work items to pull requests, I can use the API to query the pull requests in to the given branch and get the linked work items like:
https://dev.azure.com/Organisation/Project/_apis/git/repositories/Cms/pullrequests?searchCriteria.status=completed&searchCriteria.targetRefName=refs/heads/BRANCHNAME&api-version=6.0
I should now be able to extract the ID's and pass them in a PS loop to the Item Updater Task https://marketplace.visualstudio.com/items?itemName=BlueBasher.bluebasher-workitemupdater or using the API to update the workitem
There is also the option to call the API for the pipeline run info https://learn.microsoft.com/en-us/rest/api/azure/devops/pipelines/runs/get?view=azure-devops-rest-7.1#runresources
But I didn't see a way to extract the work items but the information must be somewhere there as well because I can see the work items listed in the pipeline view by resource

Related

How to get branch name from commit id using azure Devops REST API?

Scenario: I need to get when was the latest commit done in the repo and by whom, and to which branch did that user do the commit on?
Solution:
I'm using python azure.devops module. and here is my code:
cm_search_criteria = models.GitQueryCommitsCriteria(history_mode='firstParent', top=10)
commits = git_client.get_commits(repo.id, search_criteria=cm_search_criteria, project=project.name)
for i in commits:
datetimeobj = datetime.strptime(i.committer.date.strftime("%x"), '%m/%d/%y')
last_commit_on = datetimeobj.date()
last_commit_by = i.committer.email
break
Now how do I get the branch name to which the user had committed the code? In the UI we can see the branch name... how can i get the same data using Azure Devops REST API ?
enter image description here
you may need to use Stats - List to retrieve statistics about all branches within a repository, then evaluate the latest commit, you also need to consider argument of baseVersionDescriptor.versionOptions of firstParent
I'm not sure if Python wrapper module support this seems like the github project is achieved now.

Deleting branches on Azure DevOps with Powershell

I am trying to delete old branches which are x days old from Azure DevOps by using Powershell, but it is unsuccessful. Could you please help me out on this matter or if you have any better idea to execute this task, I am more than welcome to hear them out! I have been stuck with it for a few weeks now.
Thanks.
Deleting branches on Azure DevOps with Powershell
You could use the REST API to delete those Branch.
However, we do not recommend you to do this. It is not safe to use scripts to delete some old branches, because the script cannot determine whether the branch is important, but it is risky to delete based on the date. So you need to be clear about this before deleting.
First, we could use the REST API Refs - List to list all the branches for the Repo:
GET https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/refs?api-version=6.0
Then, we loop each branch with REST API Commits - Get Commits:
GET https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/commits?&searchCriteria.compareVersion.version=<YouBranchName>&api-version=6.0
And compare creation date or activation date, use the REST API to delete those branches:
POST https://dev.azure.com/{organization name}/{project name}/_apis/git/repositories/{repositoryId}/refs?api-version=5.1
Request Body:
[
{
"name": "{branchName}",
"oldObjectId": "{branchObjectId}",
"newObjectId": "0000000000000000000000000000000000000000"
}
]
Alternatively, if you want use git command line to delete, you could refer below document for some more details:
Deleting Old Local Branches With PowerShell

Can't determine pipeline which triggered a build

I'm using Azure DevOps's multiple repository functionality, documented here:
​https://learn.microsoft.com/en-us/azure/devops/pipelines/repos/multi-repo-checkout?view=azure-devops
I have my YAML file in one repo, and the pipeline points to that YAML. The YAML has a trigger set up for another repository resource, so that when that repo gets updated, the pipeline will be triggered:
resources:
repositories:
- repository: MyRepo
endpoint: 'MyRepos'
type: git
name: RepoName
trigger:
- '*'
The documentation claims that the 'Build.SourceBranch' variable will allow me to determine which branch in MyRepo triggered the pipeline build: "When an update to one of the repositories triggers a pipeline, then the following variables are set based on triggering repository"
However, this doesn't seem to be the case. No matter what branch triggers the build, 'Build.SourceBranch' is always 'refs/heads/master', presumably because the repo that holds the YAML has 'master' as its default branch.
I can't find any environment variable that gets set to the name of the branch that triggered the build, either. So how can I get the name of the branch that triggered the build? If there's no possible way, I think this needs to be added!
The issue is:
According to the document, Build.SourceBranch is set based on triggering repository. However, its value is determined by repo in which the YAML file resides in practice.
I have done following tests. There are two repos, 'RepoA' and 'RepoB'. Both repos have two branches, 'master' and 'bran'. And the YAML file is in 'master' of 'RepoA'
Commit a change in 'bran' of 'RepoB'. The value of Build.SourceBranch is refs/heads/master. It is not consistent with the documentation.
Commit a change in 'bran' of 'RepoA'. The value of Build.SourceBranch is refs/heads/bran. It is consistent with the documentation.
Commit a change in 'master' of 'RepoB'. The value of Build.SourceBranch is refs/heads/master. It is consistent with the documentation.
Commit a change in 'master' of 'RepoA'. The value of Build.SourceBranch is refs/heads/master. It is consistent with the documentation.
Thus, if the build is triggered by 'RepoA', Build.SourceBranch can successfully represent the true branch. However, if the build is triggered by 'RepoB', the value of Build.SourceBranch are always refs/heads/master.
We have reported this issue to the product group.

How to download the latest build artifacts from Azure DevOps via REST API without mentioning buildId?

URl mention in documentation:
GET https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/artifacts?artifactName={artifactName}&api-version=4.1
How to get the buildid via REST API or can we download the artifact without buildId
That worked for me, it was on preview back then:
GET https://dev.azure.com/{organization}/{project}/_apis/build/latest/{definition}?branchName={branchName}&api-version=5.0-preview.1
The following API gets a specific artifact for a build:
GET https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/artifacts?artifactName={artifactName}&api-version=5.1
You could get a list of builds, including buildid via the following API:
GET https://dev.azure.com/{organization}/{project}/_apis/build/builds?api-version=5.1
With optional parameters:
GET https://dev.azure.com/{organization}/{project}/_apis/build/builds?definitions={definitions}&queues={queues}&buildNumber={buildNumber}&minTime={minTime}&maxTime={maxTime}&requestedFor={requestedFor}&reasonFilter={reasonFilter}&statusFilter={statusFilter}&resultFilter={resultFilter}&tagFilters={tagFilters}&properties={properties}&$top={$top}&continuationToken={continuationToken}&maxBuildsPerDefinition={maxBuildsPerDefinition}&deletedFilter={deletedFilter}&queryOrder={queryOrder}&branchName={branchName}&buildIds={buildIds}&repositoryId={repositoryId}&repositoryType={repositoryType}&api-version=5.1
While the following API gets the latest build for a definition, optionally scoped to a specific branch:
GET https://dev.azure.com/{organization}/{project}/_apis/build/latest/{definition}?branchName={branchName}&api-version=5.1-preview.1
You could get a list of definitions:
GET https://dev.azure.com/{organization}/{project}/_apis/build/definitions?api-version=5.1
With optional parameters:
GET https://dev.azure.com/{organization}/{project}/_apis/build/definitions?name={name}&repositoryId={repositoryId}&repositoryType={repositoryType}&queryOrder={queryOrder}&$top={$top}&continuationToken={continuationToken}&minMetricsTime={minMetricsTime}&definitionIds={definitionIds}&path={path}&builtAfter={builtAfter}&notBuiltAfter={notBuiltAfter}&includeAllProperties={includeAllProperties}&includeLatestBuilds={includeLatestBuilds}&taskIdFilter={taskIdFilter}&processType={processType}&yamlFilename={yamlFilename}&api-version=5.1

How to use a pipeline template for multiple pipelines (in multiple projects) in Azure devops

I am new to working with Azure DevOps and I am trying to set up build pipelines for multiple projects and share a yml template between them. I will demonstrate more clearly what I want to achieve but first let me show you our projects' structure:
proj0-common/
|----src/
|----azure-pipelines.yml
|----pipeline-templates/
|----build-project.yml
|----install-net-core
proj1/
|----src/
|----azure-pipelines.yml
proj2/
|----src/
|----azure-pipelines.yml
proj3/
|----src/
|----azure-pipelines.yml
The first folder is our Common project in which we want to put our common scripts and packages and use them in the projects. The rest of the folders (proj1-proj3) are .net core projects and act as microservice projects. As you can see, each project has its own azure-pipelines.yml pipeline file and each project resides in its own repository in Github. Then there are the template pipeline files (build-project.yml and install-net-core) which reside in the common project.
All the projects have the same build steps, therefore I would like to use the build-project.yml template for all the three projects (instead of hardcoding every step in every file).
My problem is that since they reside in distinct projects, I cannot access the template files simply, let's say from project3, by just addressing it like this:
.
.
.
- template: ../proj0-common/pipeline-templates/build-project.yml
.
.
.
And [I believe] the reason is that each project will have its own isolated build pool(please do correct me on this if I am wrong).
I was thinking if Azure DevOps had similar functionality to the variable groups but for pipeline templates, that could solve my problem, however, I cannot find such a feature. Could someone suggest a solution to this problem?
Could you copy this use case? I experimented a bit after checking out some of the docs. It had some gaps though, like most of Microsoft's other docs around Azure DevOps.
Say you have azdevops-settings.yml that specifies the pipeline in one of your service branches. In the example below it has two task steps that runs an external template in another repository, but in one of them I supply a parameter that is otherwise set to some default in the template.
Notice I had to use the endpoint tag, otherwise it will complain. Something that could be further specified in the docs.
# In ThisProject
# ./azdevops-settings.yml
resources:
repositories:
- repository: templates
type: bitbucket
name: mygitdomain/otherRepo
endpoint: MyNameOfTheGitServiceConnection
steps:
- template: sometemplate.yml#templates
parameters:
Param1: 'Changed Param1'
- template: sometemplate.yml#templates
In the template I first have the available parameters that I want to pipe to the template. I tried out referencing parameters without pipeing them, like build id and other predefined variables and they worked fine.
I also tried using an inline script as well as a script path reference. The 'test.ps1' just prints a string, like the output below.
# otherRepo/sometemplate.yml
parameters:
Param1: 'hello there'
steps:
- powershell: |
Write-Host "Your parameter is now: $env:Param"
Write-Host "When outputting standard variable build id: $(Build.BuildId)"
Write-Host "When outputting standard variable build id via env: $env:BuildNumber"
Write-Host "The repo name is: $(Build.Repository.Name)"
Write-Host "The build definition name is: $(Build.DefinitionName)"
env:
Param: ${{parameters.Param1}}
BuildNumber: $(Build.BuildId)
- powershell: './test.ps1'
And the separate powershell script:
# otherRepo/test.ps1
Write-Host "Running script from powershell specification"
Output:
========================== Starting Command Output ===========================
Your parameter is now: Changed Param1
When outputting standard variable build id: 23
When outputting standard variable build id via env: 23
The repo name is: mygitdomain/thisRepo
The build definition name is: ThisProject
Finishing: PowerShell
========================== Starting Command Output ===========================
Running script from powershell specification
Finishing: PowerShell
..and so on..
I found only one solution to actually do that. You can reference the parent directory by using an absolute path. The key was to populate the root path using a system variable. The solution for your example:
- template: ${{variables['System.DefaultWorkingDirectory']}}/proj0-common/pipeline-templates/build-project.yml

Resources