Azure Devops - How to force a CI to be triggered on new branch, or work with Release branches? - azure

It used to be the case that Azure DevOps would run a new CI build when you pushed a new branch to Origin. My company relied on this, as we would issue releases by creating a release/* branch off of develop which would trigger a build and a subsequent release into our testing environment. If everything passed UAT/QA, we would deploy the that same build into production.
Our Build Pipelines are both Classic UI and have two Branch filters, develop and release/*. The one product in question has two build pipelines - one for the Webjob and one for the API, and as such each pipeline has a Path filter (to, or not to, include the Webjob folder). Creating a release/* branch does not trigger either CI pipeline.
Our Release Pipeline looks like the following, where DEV is triggerd on artifacts produced from develop and TEST->PROD is triggered on artifacts built from release/* -
This allows us to have a release environment where we iteratively make changes to get it ready, while we simultaneously make changes to develop for the next release. This is a common Gitflow model.
The Problem
Now that Azure no longer triggers a build on branch creation, I'm forced to manually run a build on Release in order to trigger the build and subsequent TEST deployment depicted in the image above.
What can I do to have automated builds and deployments in Azure while maintaining Gitflow?

I was also stuck not knowing why my TEST build wouldn't trigger. This post helped explain why. More searching found the way to resolve it. Simple as removing any path checks from your TEST build.
From the linked documentation:
If your pipeline has path filters, it will be triggered only if the new branch has changes to files that match that path filter.
If your pipeline does not have path filters, it will be triggered even if there are no changes in the new branch.
See:
Behavior of triggers when new branches are created

Not sure if you are using YAML or not but using the GUI you can add a 'path' filter for Continuous Integration and set the build to run anytime a path contains 'release'.

YAML pipelines are configured by default with a CI trigger on all branches.
YAML pipelines are configured by default with a CI trigger on all branches.
When defining pipelines using YAML and defining a repository resource (repo for shorthand). A new pipeline run gets triggered when a commit has occurred. You can further configure the trigger to ONLY act on certain branches.
See:
CI triggers - MSDN
Repo triggers
Example (All branches by default):
resources:
- repo: self
clean: true
pool:
vmImage: 'ubuntu-20.04'
steps:
- task: CMake#1
displayName: 'Generate Makefile'
inputs:
workingDirectory: $(Build.SourcesDirectory)
cmakeArgs: '-B$(Agent.BuildDirectory) -H.'
- task: Bash#3
displayName: 'Build project'
inputs:
workingDirectory: $(Agent.BuildDirectory)
targetType: 'inline'
script: 'make -j4'
Limit to release branches (add trigger to repository resource):
trigger: # Optional; Triggers are enabled by default
branches: # branch conditions to filter the events, optional; Defaults to all branches.
include:
- release/*

Related

How to trigger additional PR commit builds in Azure DevOps?

I am building a DevOps pipeline through yaml file which triggers a build for PR. Structure below:
pr:
- dev2
stages:
- stage: PR
condition: and(eq(variables['Build.Reason'], 'PullRequest')
displayName: prBuild
jobs:
- job: DowndSecureFile
if i raise a PR for the first time to the dev2 branch from another branch ex: dev3 it triggers.
Another build fails to trigger in this case:
If the PR is not yet merged:
and I have made additional commit to dev3 then build is skipped for the PR
I understand this is due to this condition where Build.Reason changes to CI:
condition: eq(variables['Build.Reason'], 'PullRequest')
But I am trying to do, that if a pr is still open and if i put additional commits to the PR branch dev3, i need to trigger a build again for that PR. Is there any suitable condition for that? or
Update:
I am using github enterprise, for the repository, no Azure Repos is used here.
should i do something else?
Can anyone help me here? Thanks.
The Build.Reason variable have a value of PullRequest when the build is triggered by a branch policy as indicated in the docs
This documentation shows how you can setup build validation as a part of your branch policy. The branch policy helps ensure the PR can only be merged if the build is succesful and also require a minimum number of code reviewers.
The manual describes that a new build is triggered for each updated commit to the pull request.
#Roderick Bant has given the doc for Build.Reason.On the base of his answer, i want to make additional information.
If you want to trigger a build for both PR and CI, you can modify your condition:
condition: and(succeeded(), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI'))

Is there a way to translate a yaml build pipeline to a release pipeline using Azure Devops?

In my build pipeline I am running Pester tests and reporting to the output folder. During release I want to run these and only go to the next stage (deploy) if all tests pass. I am not concerned about the results, I just want to make sure that they all pass. I have tried to 'copy' my existing yaml file using the GUI however not sure of the best way to do this and variable scope. Is it possible to translate a build pipeline directly to an Azure release pipeline in Azure Devops and if so, what is the best approach for doing this?
I tried to translate it to json however i had an undefined error when I tried to import the json pipeline. I should also add that I can't see a solution by looking at the preview features for this.
I am afraid it is not possible to translate a build pipeline directly to an Azure release pipeline.
You need to manually add the same tasks which are in the build pipeline to the release stage. I believe it is not a complex work to create a stage with the same tasks in the release pipeline. You just need to add each tasks with the same configurations(copy and paste mostly). And create the same variables in Variables tab. Check document about classic CD release pipeline.
There is another workaround using multiple stages yaml pipeline instead of classic release pipepline.
With multiple stage yaml pipeline. You can just easily move your build yaml content in a stage. Check here for more information. See below:
trigger: none
stages:
- stage: Test
jobs:
- job: Pester tests
pool:
vmImage: windows-latest
steps:
..
- stage: Deploy
jobs:
- job: DeployJob
pool:
vmImage: windows-latest
steps:
..

Azure DevOps Build Pipeline triggers on pull request

I have a .Net project that uses the Azure DevOps pipelines. The setup is that I have a build pipeline that creates an artifact. The artifact then automatically gets published through the release pipeline. This is working perfectly.
The problem is after I turned on the policy Build Validation, pull requests now triggers the build pipeline which then triggers the release pipeline. So every pull requests gets published. The build step is correct, but the release should not happen. The pre-deployment trigger "Pull request deployment" is disabled.
What I did to try to solve this is that I added a condition to the build step where the artifact gets created. So pull requests does not create artifacts, while merges does. This also works as intended. However, the release pipe still gets triggered, but this time without an artifact (which fails the pipe).
TLDR:
Release pipe triggers on pull requests, settings for this behavior is off. WTD?
My CI/CD settings:
Your release triggers on any of your builds and branches (PR also has a branch). You have to add the branch filter: Continuous deployment triggers. Restrict your filter with the master branch or any other. Also, you can define 2 build definitions:
A pipeline to validate your pull requests without linked releases.
CI pipeline that triggers a release.
Additionally, I think, this is a bug. Because the PR trigger is not enabled. Let's check dev community comments: https://developercommunity.visualstudio.com/content/problem/1292039/release-pipelines-ignore-pull-request-settings.html
What we have here is that we've set up build pipelines tied to YAML files stored in the repository, together with source code. And release pipelines have their Source set up to each of the build pipelines.
This is part of the Master Build:
trigger:
batch: false
branches:
include:
- master
And this is part of the Pull Request Build:
trigger: none
pr:
- master
We have Release pipelines for each of the Source builds, having Pull Request triggers enabled in one of them only, but you can have only one for your master artifacts, so PRs won't be published.

What is the purpose of `Build branch filters` in Continuous deployment trigger?

A build pipeline can be tied to only 1 source branch.
In release pipeline, we configure an artifact by selecting the source build pipeline. So a release artifact can be tied to only 1 build pipeline.
What is the purpose of Build branch filters in Continuous deployment trigger?
Let say that your code base was updated. You want deploy only if build was made over specific branch (example develop).
In that scenario Build Branch Filter looks fairly redundant... but what if:
You want to trigger new deployment for every latest artifact, built from each feature branch to get them tested. You have to filter for feature/*.
You want to trigger new deployments if your release branches are updated, but some of them are deprecated and you need to filter them out. I that scenario specify one include filter release/* and second exclude filter release/old*.
Anyway.. in most of the cases the filter and the branch name (in artifact) will match each other. Still sometimes it can be heady to trigger deployment from multiple branches or filter something out.
In regards to your comment, I uploaded part of the yaml build. In fact one build can create artifacts from all branches in repository if you want.
trigger:
branches:
include:
- feature/*
- bugfix/*
- release/*
- develop
- master
exclude:
- experimental/*

Triggering an Azure Devops pipeline from another pipeline

I'm having problems triggering a pipeline from another Pipeline in Azure DevOps. I have a CI pipeline and I want to trigger a Deploy Pipeline whenever CI passes on a master branch. This seems to be technically possible, but the documentation is unclear.
I see the following:
# this is being defined in app-ci pipeline
resources:
pipelines:
- pipeline: securitylib
source: security-lib-ci
trigger:
branches:
- releases/*
- master
But it's unclear as to a) whether this goes in the triggering pipeline (in my case the CI pipeline) or the triggered pipeline (in my case, the deploy pipeline).
It's also unclear as to what the pipeline and source refer to, and how I find out these variables? Are they both the name of the pipeline? I've tried various different permutations and nothing seems to be working.
EDIT 2
Finally Microsoft has improved their documentation with regards to the pipeline triggers in YAML! Here's the link.
EDIT
After having written my answer, Microsoft has come up with another solution to solve this problem, by using a build completion trigger via a classic pipeline. Their solution can be found here.
If you're not publishing an artifact from the triggering pipeline, it won't trigger the triggered pipeline.
Also, there is a very big restriction on the use of these types of triggers. It is necessary to change the defaultBranch for manual and scheduled builds in the depends pipeline, to the working branch. Otherwise it won't kick in at the end of the source pipeline execution. So, let's say you're working on feature branch, and defaultBranch is set to feature. You commit your code, and everything will run as expected: the source pipeline kicks in, and at its end, the depends pipeline will be triggered. All good! But when you will merge into master, if you do not change the defaultBranch, the depends pipeline won't be triggered at the end of the source pipeline. I explain how to change the defaultBranch at the end of the answer.
How to setup a pipeline trigger
I managed to get this up and running on a minimalistic project. Here you can have the code and here the project on Azure DevOps. I will try to guide you through how I did it, and answer the questions you've asked in your post.
I will be calling the triggered pipeline as depends pipeline and the triggering pipeline as source pipeline.
On the source pipeline, there's no need to do anything except publishing an artifact. If you don't publish an artifact from the source pipeline, it won't work. Below you can find the code I am using for my dummy source pipeline. I want it to be triggered for master branch, and at the end I want to be sure to publish an artifact.
trigger:
branches:
include: # branch names which will trigger a build
- master
pr: none
steps:
# required to cause pipeline triggering downstream
- task: CopyFiles#2
inputs:
contents: $(System.DefaultWorkingDirectory)/**/*.yml
targetFolder: $(Build.ArtifactStagingDirectory)
- task: PublishBuildArtifacts#1
inputs:
pathtoPublish: $(Build.ArtifactStagingDirectory)
artifactName: dummy-$(Build.BuildId)
On the depends pipeline (code shown below), I have to disable CI and PR triggers, otherwise when I commit to this repo, this pipeline will be triggered by the CI trigger, and then by the end of the execution of the source pipeline. This is done by the two first lines of my code. Then I want that the pipeline named source (this is the source property in the YAML below), within the project named Pipelining (project property in the YAML) will trigger the current (depends) pipeline when this updates master branch.
trigger: none
pr: none
resources:
pipelines:
- pipeline: source
project: Pipelining
source: source
trigger:
branches:
include:
- master
steps:
- checkout: none
- script: echo 'triggered depends'
Does it make sense? It is important for your project name on Azure DevOps to match the property in the YAML depends pipeline code.For me it is Pipelining
As well as the source property, again in the YAML depends pipeline code.
Change the default branch
In order to change the defaultBranch, because of the issue mentioned above, you should edit the pipeline (in this case, the depends pipeline), then on the three dots on the top right corner pick Triggers. Then choose the YAML tab, and you will get to the screen shown in the image below, where you can set the working branch.
Above yaml pipeline trigger should be defined in the triggered pipeline(deploy pipeline).
- pipeline: string the string here is identifier you give to this pipeline resource. It can any string.
source: string the string here is the definition name of the triggering pipeline(the name of your CI pipeline).
Below yaml is from the document pipeline resource.
resources:
pipelines:
- pipeline: string # identifier for the pipeline resource
project: string # project for the build pipeline; optional input for current project
source: string # source pipeline definition name
branch: string # branch to pick the artifact, optional; defaults to all branches
version: string # pipeline run number to pick artifact, optional; defaults to last successfully completed run
trigger: # optional; triggers are not enabled by default.
branches:
include: [string] # branches to consider the trigger events, optional; defaults to all branches.
exclude: [string] # branches to discard the trigger events, optional; defaults to none.
Option: You can also set the pipeline triggers from Ui page. Go the edit page of the triggered yaml pipeline(Deploy pipeline), Click the 3dots and choose Triggers
Go to Triggers--> Build completion and click add--> Select your triggering pipeline(CI pipeline)
Update:
I saw the pipeline resource in azure-deploy.yml is defined as below.
resources:
pipelines:
- pipeline: 'Deploy to Development'
source: 'DFE-Digital.dfe-teachers-payment-service'
trigger:
branches:
include:
- "master"
- "release-stuff"
please try changing the indentation of trigger element the same as source element. Check below example:
resources:
pipelines:
- pipeline: 'Deploy to Development'
source: 'DFE-Digital.dfe-teachers-payment-service'
trigger:
branches:
include:
- "master"
- "release-stuff"
I found the following:
In source pipeline I didn't need to create an artifact
In depends pipeline if I wanted to build after any commit to the source branch I could get it to work with this:
trigger: none
pr: none
resources:
pipelines:
- pipeline: 'depends'
source: 'common-gulp-trigger'
trigger: true
I may assume you are not working on the master branch, right? I have the same issue previously. But after I read the section Default branch for triggers of MS's doc. I understand why. The trigger only examine master's branch's yaml file by default. This means the pipeline will only be triggered by the definition of triggers in master branch's yaml file.
Therefore, whatever branches you add in the trigger section of yaml file in other branches(not master), tirgger is not active. You need to change the pipeline to look the yaml file in your current branch, not master. Just follow the doc's instruction, change the default trigger branch. You will get it working.
Once you merge your work into master, you probably need to change the dedault trigger branch back to master.

Resources