6
votes

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.

1
Based on my understand, what you want is no matter the PR is merging or merge finished, you all hope CD could not be triggered. (Correct me if I have any misunderstand). If this, I'm afraid the work around you are using and @Shamrai's answer would be the best choices for you, though these would be little complex or bring another trouble. Because CD means continues deployment which would be run once source has any update.Merlin Liang - MSFT
@MerlinLiang-MSFT hey Merlin. Thanks for chiming in. Yes I believe you have it correctly. When a PR is created or updated, a build is triggered via branch policy and we don’t want to CD that build. Thanks for your input. I will look into potentially setting up special builds for pull requests.Zam

1 Answers

8
votes

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'))