How to organize azure-pipeline.yaml files - azure-devops

I've read the official documents to put the yaml file in the root of a project. I'm thinking to create a some sort of pipeline repo that contains several yaml files in charge of different pipeline workflow for different project. But Azure pipeline only recognise the azure-pipeline.yaml file name.
Issue:
It is obviously not possible to create several yaml files with the same azure-pipeline.yaml name under the same folder. What's the best practice to organise the azure pipeline yaml files? Shall it be just put in the root of the project?

It sounds like templates might be what you're looking for. This assumes you have a single project/repo and a large pipeline that you'd like to split up so it's easier to read or reason about individual parts.
Taking an example from the linked documentation page, you can define a template yaml file like this (ex: include-npm-steps.yml):
steps:
- script: npm install
- script: yarn install
- script: npm run compile
And then include it as a "module" in the main azure-pipelines.yml file like this:
jobs:
- job: Linux
pool:
vmImage: 'ubuntu-latest'
steps:
- template: templates/include-npm-steps.yml # Template reference
- job: Windows
pool:
vmImage: 'windows-latest'
steps:
- template: templates/include-npm-steps.yml # Template reference

It is obviously not possible to create several yaml files with the
same azure-pipeline.yaml name under the same folder.
Yes, it's not possible to create several yaml pipelines with same name under same folder. Cause the yaml pipeline is under version control and Azure Devops git doesn't support two files with same name in same folder...
What we can do is to create several pipelines with different names in same folder, like azure-pipeline.yaml,azure-pipelines-1.yml,azure-pipelines-2.yml and so on.
Not sure if you know this option when editing yaml pipeline:
We can easily change the yaml file's name in source control, and we just need to modify the path here:
What's the best practice to organise the azure pipeline yaml files?
Shall it be just put in the root of the project?
Assuming you own one Team Project with two repos A and B:
If A and B both represent the module of one final product, then you should have corresponding pipelines for A and B. It means in most scenarios, you should have at least one pipeline in RepoA and one in RepoB. They all need corresponding azure-pipeline.yaml file.
Now if azure-pipeline.yaml in RepoA and azure-pipeline.yaml in RepoB have many same variables/tasks/jobs, we can consider moving the duplicate contents into templates. We can create a RepoC in same project to store the templates, and in this templates repo, we don't need to create yaml pipeline here.
About how to reference templates in RepoC in RepoA's pipeline, see this document. If the source is in github, you can check Krzysztof's link. And if the RepoC is in Azure Devops Repos and same project with your RepoA and RepoB, you can should this format:
resources:
repositories:
- repository: templates
type: git
name: RepoC
ref: refs/heads/master
To sum up, functional repos (those with source code) should have corresponding yaml pipeline in it. And if you want to monitor the changes in one repo (without source code) for some purpose, you can also have one yaml pipeline in that. For templates repo, yaml pipelines are not necessary.
Also, apart from yaml pipelines you may sometimes use Classic Build/Release pipelines which are not under Version Control. See this.

Related

Single yaml file for multiple azure repos

Background -
I have multiple web service projects under multiple azure repos. All these projects have same structure as they are ASP.NET core web applications. I have written separate yaml pipelines and created separate yaml jobs for each project which has similar steps and placed them in separate azure repos.
Issue -
I have created separate yaml pipeline jobs (multistage - build and deploy) depending on each yaml. Is there any way to consolidate these yaml to one and place to shared azure repo and trigger the pipelines on the code commit to respective azure repos and deploy it to their related environments on azure web services?
Is there any way to consolidate these yaml to one and place to shared azure repo and trigger the pipelines on the code commit to respective azure repos and deploy it to their related environments on azure web services?
The answer is yes.
You could create a new repo with a new YAML file in it, or you could select one repo as main repo and set the YAML with Repository resource:
resources:
repositories:
- repository: A
type: git
name: MyProject/A
ref: main
trigger:
- main
- repository: B
type: git
name: MyProject/B
ref: release
trigger:
- main
- release
The best way to manage these is a separate repo as template. Essentially your template contains the pipeline steps that you want to run, and for each pipeline you need you have a yaml file that extends the template by defining what triggers you want for that pipeline and pass any pipeline dependant parameters you are using to the template.
Templates

How to get information about resources in an Azure Pipelines run?

I work in a platform team that builds and supports Azure Pipelines YAML templates and various custom scripting for these pipelines. People in my organisation use these YAML templates like:
resources:
repositories:
- repository: templates
type: git
name: PROJECT/cicd_stuff
ref: refs/heads/releases/v0.21
extends:
template: our_awesome_template.yml#templates
parameters:
...
In order to reliably match the version of our scripts to the version of the YAML templates, we now include an extra build stage in our pipeline templates that checks out the repo templates repo and puts all our scripts in an artifact to be used in that run. Using "release branches" allows us to safely put out and test new features and fixes to our pipelines: Teams can upgrade their pipeline on their own pace, with older version remaining supported for a while.
I'd like to start using Azure Artifacts for our script artifacts, but now I'm wondering "how can I determine which version of my scripts I should be downloading from Azure Artifacts?" The information included in the resources block would work for me, but I can't seem to access that with an expression or with a predefined variable. The only solution I can currently think of is to use the az pipelines cli. Any thoughts?
how can I determine which version of my scripts I should be downloading from Azure Artifacts?
If the feature verion is the target version, you could try the following yaml to get its value. See: Repository details for details.
resources:
repositories:
- repository: templates
type: git
name: PROJECT/cicd_stuff
ref: releases/v0.21
variables:
tools.ref: $[ resources.repositories['templates'].ref ]
pool:
vmImage: ubuntu-latest
steps:
- bash: |
echo "Tools version: $TOOLS_REF"
Also you could try Daniel's solution using tagref: refs/tags/v1.0 # optional ref to pin to by reference to this doc: Use other repositories and Checking out a specific ref.
Update>>Currently there is no available predefined variables regarding to the name that was used to include the repository resource ('templates' in this case). If we know the repository alias, the repository name can be parsed via $[ resources.repositories['templates'].name].
Another finding is that the repository resource will be added as the build artifacts, and we can get it from API:GET https://dev.azure.com/{organization}/{project}/_build/results?buildId={buildId}&view=artifacts&__rt=fps&type=consumedArtifacts(I grab this API from browser developer tool). And buildId can be got using variable Build.BuildId. See: Build variables (DevOps Services) for details. From the response, search consumedSources field to find below json segment, which will return all artifacts, you could find repository resource and all its detailed information.

How to call yml script from other yml in azure devops

I want to call yml script (which will run end to end test) from another yml script in Azure DevOps.Both yml scripts are in different repositories.
I have used queue build task plugin to run but its not able to find the definition.
Can't find the definition name.
How to call yml script from other yml in azure devops
You can use the resource specification to provide the location of the repo where another yml file is located. When you refer to the another repo, use # and the name you gave it in resources:
resources:
repositories:
- repository: templates
type: github
name: Contoso/BuildTemplates
jobs:
- template: common.yml#templates # Template reference
You can check the document Job and step templates for some more details.
Hope this helps.

Reuse same build pipeline for different repository on Azure DevOps

I have a project on Azure DevOps containing multiple forks of the same main repository. I created a build pipeline for that repository which unfortunately cannot be reused for the present forks since a pipeline can only be configured for a single repository.
This solution is not ideal because leads to multiple identical pipelines, one for each fork, and maintaining all of them can be difficult.
Is there a way to use one pipeline for multiple repositories?
you can create a template file and reference that file from each pipeline, that way you can edit a single file and every pipeline will change.
example how to reuse a step file from different repo
resources:
repositories:
- repository: DevOps
type: git
name: DevOps
trigger: none
jobs:
- template: vsts/yaml/build.yaml#DevOps
parameters:
solutionName: xxx
registryName: yyy
You can take a look at the official docs for more examples
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops
It's on the roadmap for 2019 Q3:
Multi-repository support for YAML pipelines
https://dev.azure.com/mseng/AzureDevOpsRoadmap/_workitems/edit/1454026
Update: this is now implemented:
https://learn.microsoft.com/en-us/azure/devops/pipelines/repos/multi-repo-checkout?view=azure-devops#triggers
"Triggers
You can trigger a pipeline when an update is pushed to the self repository or to any of the repositories declared as resources."

Can I have multiple build pipelines for the same repository?

I have a repository with two solutions in it. Both solution files exist in the root directory, essentially like this:
/WebsiteOneDirectory/
/WebsiteTwoDirectory/
/.gitignore
/WebsiteOne.sln
/WebsiteTwo.sln
Is it possible for me to build multiple pipelines pointed at this repository to build the different solutions? When I create my first pipeline it is generating a azure-pipelines.yml file for the repo, so I am unsure how/if I am going to be able to have multiple pipeline configurations if that is a fixed name it expects.
In addition to James Reed's answer, if you prefer using the .yml files, what I would recommend is to create multiple .yml definitions, one for each pipeline.
Here's what one would look like:
trigger:
branches:
include:
- master
paths:
include:
- WebsiteOneDirectory/*
exclude:
- WebsiteTwoDirectory/*
For building, you'd need to specify which solution to build. For a (.net core) example:
variables:
buildConfiguration: 'Release'
pool:
vmImage: 'Ubuntu-16.04'
steps:
- script: dotnet build WebsiteOne --configuration $(buildConfiguration)
Yes, you can use path filters in your trigger
Edit your build and go to the Triggers tab. Here you can add or remove branches, and also add path filters.
You have the option to either explicitly include or exclude paths. In the image below you can see that I'm explicitly excluding the "docs" folder from the master branch.