Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent Pull Request builds from triggering Continuous deployment trigger Azure DevOps Server

TL;DR

We want to prevent Pull Request branch policy builds in Azure Devops from triggering releases via the Continuous deployment trigger mechanism.

Problem

We are currently users of Azure DevOps Server 2019 Version Dev17.M153.3

We are utilizing both Build and Release pipelines. When a user submits a Pull Request, we have a Branch Policy that queues a build to ensure that code compiles and any tests pass. The completion of this build triggers the Continuous deployment trigger we have configured on the Build artifact of the corresponding release - this is NOT ideal behavior for us.

Our ideal behavior is to have the Branch Policy build queued by a Pull Request NOT trigger the Continuous deployment trigger and therefore NOT queue a release. We only want to trigger a release via the Continuous deployment trigger if we MANUALLY queue a build. We never want this to happen with a branch policy build on a Pull Request.

We've tried using the Build branch filters in the Continuous deployment trigger, but have had no luck. I've tried setting this using Exclude and setting Build branch to pull/*, refs/pull/* and merge but have not had any luck with these filters, the release is still being queued.

I want to know if there is potentially a better way to handle this scenario, or if additional filters can be added to the Continuous deployment trigger to mitigate unwanted releases from being queued.

like image 820
Zam Avatar asked Nov 19 '19 18:11

Zam


People also ask

How do you stop continuous integration on Azure DevOps?

Navigate to your team project on Azure DevOps. Navigate to Pipelines | Pipelines. Not to have two pipelines triggered later in the lab, disable the CI trigger for the template created pipeline (uncheck) and Save.

How do you trigger a build on Azure DevOps pull request?

Create a pull request trigger You can set up pull request triggers for both Azure Repos or GitHub repositories. From within your project, Select Pipelines > Releases, and then select your release pipeline. Under the Pull request trigger section, select the toggle button to enable it.

Which trigger needs to be enabled to continuously create a release every time a new build is available?

Continuous deployment triggers allow you to create a release every time a new build artifact is available. Using the build branch filters you can trigger deployment for a specific target branch. A release will be triggered only if the Git push contains a commit on the specified branch.

What are the two categories of triggers in Azure DevOps?

Continuous deployment triggers help you start classic releases after a classic build or YAML pipeline completes. Scheduled release triggers allow you to run a release pipeline according to a schedule. Pull request release triggers are used to deploy a pull request directly using classic releases.


1 Answers

We've established that there is no "best solution" for this problem at the moment, below are some alternatives.

Easy work arounds

  • Unlink your current PR Policy build definition from release definition and create new build definition (or clone exiting). Link this new build definition to your releases and run it manually.
  • Remove Continuous deployment from your release definition and create your releases manually from your completed builds.
  • Use continues deployment and set it to some branch. Then your deployment will trigger only after completing of PR (if you set CI for your build).

enter image description here


Release variables and custom conditions (single artifact)

If you only have a single artifact in your release, you can skip tasks on the job level by using the Build.SourceBranchName release variable:

enter image description here

When the variable expression resolves, if the Build.SourceBranchName variable is equal to merge it skips all following tasks:

enter image description here


Release variables and custom conditions (multiple artifacts)

Finally, if you're using multiple artifacts in your release, you can still accomplish the above behavior, albeit, you need to do some extra work with a PowerShell script.

You use a PowerShell script to look at the RELEASE_TRIGGERINGARTIFACT_ALIAS environment variable and then looks at the corresponding RELEASE_ARTIFACTS_<RELEASE_TRIGGERINGARTIFACT_ALIAS>_SOURCEBRANCHNAME variable.

Your environment variables (visible in the Initialize Job step of a release look like the following.

...
[RELEASE_ARTIFACTS_PROJECT1_SOURCEBRANCHNAME] --> [master]
...
[RELEASE_ARTIFACTS_PROJECT2_SOURCEBRANCHNAME] --> [merge]
...
[RELEASE_ARTIFACTS_PROJECT3_SOURCEBRANCHNAME] --> [master]
...
[RELEASE_TRIGGERINGARTIFACT_ALIAS] --> [PROJECT2]
...

This is also visible in a standard release view.

enter image description here

enter image description here

Ultimately we want to see if the triggering artifact's source branch name variable is set to merge, if so I short-circuit the release and skip all following tasks via Control Options Custom conditions. This is not an ideal situation as Pull Request builds still trigger unnecessary releases, however, it prevents any actual release action from occurring.

PowerShell task

Below is the PowerShell I'm currently using in the very first task

# Use the triggering artifact alias and constructing the name of the variable that will ultimately get us the source branch that triggered the release
$SrcBranchName = "RELEASE_ARTIFACTS_$(('$(RELEASE.TRIGGERINGARTIFACT.ALIAS)' -replace '(^\s+|\s+$)','' -replace '\s+','_').ToUpper())_SOURCEBRANCHNAME"

# Get the environment variable that holds the name of the source branch
$SrcBranchName = Get-Item  env:$SrcBranchName | Select-Object -ExpandProperty Value
Write-Host "SrcBranchName: $SrcBranchName"

if ($SrcBranchName -eq "merge") {
    Write-Host "Release caused by a PR - no further steps will run."
}

# Set an environment variable with the source branch name for use in a Custom Conditions Control
Write-Host "##vso[task.setvariable variable=TriggeringArtifactSourceBranchName;]$SrcBranchName"

Custom Condition

Then for my custom conditions in each task, I use the following which skips the task if the TriggeringArtifactSourceBranchName is set to merge.

and(succeeded(), ne(variables['TriggeringArtifactSourceBranchName'], 'merge'))
like image 154
Shamrai Aleksander Avatar answered Sep 20 '22 01:09

Shamrai Aleksander