Creating a yaml build template with access to all repositories - azure-devops

I have a build that uses the Azure DevOps REST api to do analysis across a collection of repositories in a single Azure DevOps project.
To speed up the build, it only checks out a single repository containing certain build utilities, such as powershell scripts - the rest of the analysis is done via querying specific information via the REST api.
NOTE: This build is running on Azure DevOps Server 2020, which still calls the setting "Limit job authorization scope to referenced Azure DevOps repositories". Looking at doc history, I believe this is equivalent to "Protect access to repositories in YAML pipeline", I use the more recent term below.
This all worked fine until "Protect access to repositories in YAML pipelines" was turned on. With that setting turned on, the REST api only returns information about the repository containing the build utilities. This is due to the reduced scope of the Job Access Token (see Protect access to repositories in YAML pipelines)
I've attempted to create a template containing the list of all repositories, so that a few select builds can continue to easily access all repositories. Previously, no explicit list of repositories was needed, but now it appears they will have to manually be listed, and I'd like to do that in a single file.
Both yaml files below are in the same repository.
Template allRepos.yaml:
parameters:
- name: steps
type: stepList
default: []
jobs:
- job:
pool: 'swimming'
uses:
repositories:
- R1
- R2
- R3
- Rnnn
steps:
- ${{ parameters.steps }}
Yaml for pipeline:
extends:
template: allRepos.yaml
parameters:
steps:
- checkout: self
- task: PowerShell#2
displayName: multiRepoAnalysis
inputs:
filePath: analysis.ps1
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
It seems like this should work according to:
access tokens - Protect access to repositories in YAML pipelines)
repos - Protect access to repositories in YAML pipelines
jobs.job definition
However, attempting to run this pipeline results in the errors:
Job 'Job1' references the repository 'R1' which is not defined by the pipeline.
Job 'Job1' references the repository 'R2' which is not defined by the pipeline.
Job 'Job1' references the repository 'R3' which is not defined by the pipeline.
Job 'Job1' references the repository 'Rnnn' which is not defined by the pipeline.
How can I create a template that:
allows the access token for specific builds to access all repositories when "Protect access to repositories in YAML pipelines" is turned on
do so without checking out each repository

Limitations
This solution only works for a list of at most 20 repositories
- checkout: self counts toward the 20 repository limit
You must include submodule repositories in the list, which also counts toward the 20 repository limit.
Exceeding 20 repositories will still result in an error:
##[error]Tokens may be scoped to a maximum of 20 repositories. Reference fewer repositories in YAML or disable Scoped Tokens.
This limitation could be worked around by splitting the build into multiple definitions - but note if your analysis includes accessing submodule repositories, those submodule repositories must be referenced in any list of the primary repositories.
To my current knowledge, there is not a way to scope the access token for a particular pipeline with a generic "all repositories" permission.
Solution
The original templates were on the right track - but missed the fact that any uses: repositories must previously have been declared as a resources: repository.
There is a github issue to clarify the Microsoft documentation: uses: keyword is not explained, does not work as described
The working solution is:
Template allRepos.yaml:
parameters:
- name: steps
type: stepList
default: []
resources:
repositories:
- repository: R1
type: git
name: MyDevOpsProject/R1
- repository: R2
type: git
name: MyDevOpsProject/R2
- repository: R3
type: git
name: MyDevOpsProject/R3
- repository: Rnnn
type: git
name: MyDevOpsProject/Rnnn
jobs:
- job:
pool: 'swimming'
uses:
repositories:
- R1
- R2
- R3
- Rnnn
steps:
- ${{ parameters.steps }}
Yaml for pipeline:
extends:
template: allRepos.yaml
parameters:
steps:
- checkout: self
- task: PowerShell#2
displayName: multiRepoAnalysis
inputs:
filePath: analysis.ps1
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)

Related

Can I reference the same BitBucket Repository under two different names for enable custom triggering on Azure DevOps Services YAML?

You think is possible to reference the same BitBucket Repository under 2 different names with 2 different paths in order to achieve and trigger 2 different stages ? I want to build and publish 7 different microservices on K8s but the repos are only 3 (divided in subfolders) you this this can be achievable? The idea is to create different blocks of template one for each microservice. But during the template checkout the 3 macrorepository only (for dev purposes). Let me show you my idea.
resources:
repositories:
############## 3 BITBUCKET BIG REPOS ##############
- repository: omni-omsf-api
type: bitbucket
endpoint: OMNI-OMSF-BitBucket-SC
name: ovsdev/omni-omsf-api
trigger: none
- repository: omni-omsf-extension
type: bitbucket
endpoint: OMNI-OMSF-BitBucket-SC
name: ovsdev/omni-omsf-extension
trigger: none
- repository: omni-omsf-core
type: bitbucket
endpoint: OMNI-OMSF-BitBucket-SC
name: ovsdev/omni-omsf-core
trigger: none
###################################################
############# 7 SUB-REPOS ONLY FOR TRIGGERING #########
- repository: ovs-api-service
type: bitbucket
endpoint: OMNI-OMSF-BitBucket-SC
name: ovsdev/omni-omsf-api
trigger:
branches:
include:
- release_qa
- master
paths:
include:
- ovs-api-service/*
###################################################
stages:
- ${{ if or( and( eq( parameters.ovsapiservice, true), eq( variables['Build.Reason'], 'Manual') ), eq( variables['Build.Repository.Name'], 'ovs-api-service') ) }}:
- template: microservice-buildRelease.template.yml
parameters:
dockerFilePath: omni-omsf-api/ovs-api-service/Dockerfile
dockerImageName: ovs-api-service
tag: $(Build.BuildId)
microservicename: ovs-api-service
- ${{ else }}:
- stage:
jobs:
- job:
steps:
- task: Bash#3
displayName: Showing folder hierarchy
inputs:
targetType: 'inline'
script: |
tree $(Pipeline.Workspace)
Can I reference the same BitBucket Repository under two different
names
The answer is Yes. Different alias can refer from the same repository.
enable custom triggering on Azure DevOps Services YAML
I read the YAML definition you provided, if you are talking about trigger of the resources section, then the answer is NO.
It should be pointed out that the usage you are using does not exist.
Please check these official articles, both of them mentioned this point:
resources.repositories.repository definition
trigger: trigger # CI trigger for this repository, no CI trigger if
skipped (only works for Azure Repos).
Triggers Usage in resources
Repository resource triggers only work for Azure Repos Git
repositories in the same organization at present. They do not work for
GitHub or Bitbucket repository resources.
So trigger via resources section of YAML is unable to achieve, you can only set YAML on bitbucket side and the condition should based on common trigger on bitbucket side.

Azure devops yaml pipelines get branches from different repo to use them as a value list in a param

Scenario:
I have a azure git repo for all my infrastructure code (basically all my yaml files are there and are triggered from there for any other jobs needed).
I want to be able to get all branches from repository x and use them as a value list in a parameter.
Basically:
resources:
repositories:
- repository: repo_x
type: git
name: Proj/repo_x
"""
Something should happen here and give me a list of branches from repo_x
in a variable 'branch_list'
"""
parameters:
- name: branch
displayName: Target branch
type: string
default: 'main'
values: [branch_list]
when we trigger a pipeline, the branch list is already available, this defines in which version the pipeline will run, is this what you want ?

Can you make templates for resources and combine it with steps in a YAML pipeline?

I have a pipeline that has a section like this that lists the pipelines that would trigger the pipeline.
resources:
# List all the microservice pipelines to be watched plus infrastructure, the pipeline name is the name
# of the stack. Note template-maven and template-gradle are not to be part of this build.
pipelines:
- pipeline: auth
project: services
source: auth
branch: master
trigger:
branches:
include:
- master
- pipeline: ai
project: services
source: artificial-intelligence
branch: master
trigger:
branches:
include:
- master
- pipeline: ui
project: frontend
source: ui CI
branch: master
trigger:
branches:
include:
- master
I then have a job with the following steps (because deployment pulls all files, I just need one folder from each pipeline
- job: publishDeploymentPipelineFiles
condition: not(canceled())
steps:
- checkout: none
- download: auth
artifact: drop
- download: ai
artifact: drop
- download: ui
artifact: drop
What I am hoping for is some form of template that does
steps:
- checkout: none
- template: pull-deployment-manifests.yml
parameters:
sources:
- project: services
source: auth
stackName: auth
- project: services
source: artificial-intelligence
stackName: ai
- project: frontend
source: ui CI
stackName: ui
Which only lists the project and CI pipeline and create the appropriate pipeline ID from stackName and create the resources and the steps.
My workaround right now is to create a project that takes a CSV containing those items and generating the azure-pipelines.yml
As far as I know you can't dynamically create resources. So you create this
steps:
- checkout: none
- template: pull-deployment-manifests.yml
parameters:
sources:
- project: services
source: auth
stackName: auth
- project: services
source: artificial-intelligence
stackName: ai
- project: frontend
source: ui CI
stackName: ui
and run checkout inside the template unless you defined resources with those names on root level.
As documentation says here:
Resources are defined at one place and can be consumed anywhere in your pipeline.
Sure you can set up a template with resources, and use this template in a YAML pipeline. You can reference "Extend from a template with resources".
However, please note that if you have defined resources and steps in the template, you can't use it under the steps key in the YAML pipeline. You should use the extends key to extend the resources from the template, just like as the example shows in the document.
You may need to defined all the required steps in the template, or use the steps from other step template into the template.

Azure Devops RestAPI to access Resources in YAML pipelines

In Azure DevOps Multi Stage YAML Pipeline, under resources section I had defined 2 repo resources Demo2 and Demo3. I want to access the changes happening between the builds for the repo Demo2 and Demo3. In pipeline summary page, there is an option view changes, which gives the commits from the repo and I am trying to get that details via RestAPI.
I tried to find details via Azure DevOps RestAPI page and az devops CLI but can't find anything helpful, so reaching out here for help.
resources:
repositories:
- repository: Demo2
type: git
name: 'Test/Repo2'
- repository: Demo3
type: git
name: 'Test/Repo3'
trigger:
- main
pool:
vmImage: ubuntu-latest
steps:
- checkout: Demo2
- checkout: Demo3
- script: echo Hello, world!
displayName: 'Run a one-line script'
Azure Devops RestAPI to access Resources in YAML pipelines
I am afraid there is no such documented REST API to get the details via option view changes.
But we could try to use F12 to grab the URL:
https://dev.azure.com/{organization}/{project}/_traceability/runview/changes?currentRunId={Build Id}
Then we will get the feedback with HTML type, we could convert it the Json type, we could get some info about the commit:
If we need to check the context of the commit, we could use the REST API [Commits - Get] 2 to get the details.

Azure pipeline - specify branch name in multiple repository

As a continuation to Azure DevOps - Handling single release for separate code repositories for UI and Dotnet API layer I am trying to proceed with checking out multiple repos in my yaml by defining it under repositories as shows below. I am unable to understand where to change the branch to make sure, my tasks such as checkout does not happen on master, but on my custom branch.
resources:
repositories:
- repository: mybitbucketrepo
type: bitbucket
endpoint: myserviceconnection
trigger: # CI trigger for this repository, no CI trigger if skipped (only works for Azure Repos)
branches:
include: [ custom-branch ]
name: orgname/reponame
What I tried so far is below for which I get the error - Only 'self', 'none' or a repository alias are supported. Any help will be appreciated.
- checkout: mybitbucketrepo#custom-branch
You need to define ref settings:
When using a repository resource, specify the ref using the ref property. The following example checks out the features/tools/ branch of the designated repository.
resources:
repositories:
- repository: MyGitHubRepo
type: github
endpoint: MyGitHubServiceConnection
name: MyGitHubOrgOrUser/MyGitHubRepo
ref: features/tools
and then just
steps:
- checkout: MyGitHubRepo
IT's not support to use #, please use inline ref syntax
steps:
- checkout: self
- checkout: git://MyProject/MyToolsRepo#features/mytools
By appending #<ref>, the agent can be instructed to check out a different ref. In this case, it's assumed to be a branch called features/mytools. Branches can also be prefixed with refs/heads/ to make it unambiguous that it's a branch.
Other valid refs (and ref-like things):
refs/tags/
commit ID
For more details, please take a look at this link: Multi-checkout: checking out multiple repos
You could also define it in resource, check our official doc --Checking out a specific ref A sample as below:
resources:
repositories:
- repository: app
type: github
name: org1/repoA
ref: master
endpoint: 'GitHub endpoint'
trigger:
- master
- release/*