防止拉取请求构建触发持续部署触发器 Azure DevOps 服务器

Zam*_*Zam 6 git powershell azure-devops azure-pipelines

TL; 博士

我们希望阻止 Azure Devops 中的 Pull Request 分支策略构建通过该Continuous deployment trigger机制触发发布。

问题

我们目前是 Azure DevOps Server 2019 版本 Dev17.M153.3 的用户

我们同时使用构建和发布管道。当用户提交一个 Pull Request 时,我们有一个Branch Policy将构建排队以确保代码编译和任何测试通过的。此构建的完成会触发Continuous deployment trigger我们在相应版本的构建工件上配置的 - 这对我们来说不是理想的行为。

我们的理想行为是让分支策略构建通过拉取请求排队,不会触发Continuous deployment trigger发布,因此不会排队发布。Continuous deployment trigger如果我们手动将构建排入队列,我们只想通过 触发发布。我们永远不希望这种情况发生在基于Pull Request.

我们曾尝试在Build branch filters中使用Continuous deployment trigger,但没有成功。我试过设置此使用Exclude和设置Build branchpull/*refs/pull/*merge但还没有与这些过滤器运气好的话,释放仍在排队。

我想知道是否有更好的方法来处理这种情况,或者是否可以向 中添加额外的过滤器Continuous deployment trigger以减少不需要的发布排队。

Sha*_*der 8

我们已经确定目前没有针对此问题的“最佳解决方案”,以下是一些替代方案。

简单的解决方法

  • 将您当前的 PR 策略构建定义与发布定义取消链接并创建新的构建定义(或克隆退出)。将此新构建定义链接到您的版本并手动运行它。
  • 从您的发布定义中删除持续部署,并从您完成的构建中手动创建您的发布。
  • 使用继续部署并将其设置为某个分支。那么你的部署只会在 PR 完成后触发(如果你为你的构建设置了 CI)。

在此处输入图片说明


发布变量和自定义条件(单个工件)

如果您的发布中只有一个工件,则可以使用Build.SourceBranchName 发布变量跳过作业级别的任务:

在此处输入图片说明

当变量表达式解析时,如果Build.SourceBranchName变量等于merge它,则跳过以下所有任务:

在此处输入图片说明


发布变量和自定义条件(多个工件)

最后,如果您在发布中使用多个工件,您仍然可以完成上述行为,尽管您需要使用 PowerShell 脚本做一些额外的工作。

您使用 PowerShell 脚本查看RELEASE_TRIGGERINGARTIFACT_ALIAS环境变量,然后查看相应的RELEASE_ARTIFACTS_<RELEASE_TRIGGERINGARTIFACT_ALIAS>_SOURCEBRANCHNAME变量。

您的环境变量(在Initialize Job发布步骤中可见)如下所示。

...
[RELEASE_ARTIFACTS_PROJECT1_SOURCEBRANCHNAME] --> [master]
...
[RELEASE_ARTIFACTS_PROJECT2_SOURCEBRANCHNAME] --> [merge]
...
[RELEASE_ARTIFACTS_PROJECT3_SOURCEBRANCHNAME] --> [master]
...
[RELEASE_TRIGGERINGARTIFACT_ALIAS] --> [PROJECT2]
...
Run Code Online (Sandbox Code Playgroud)

这在标准发布视图中也可见。

在此处输入图片说明

在此处输入图片说明

最终,我们想查看触发工件的源分支名称变量是否设置为merge,如果是,我将发布短路并通过 跳过所有后续任务Control Options Custom conditions。这不是一个理想的情况,因为 Pull Request 构建仍然会触发不必要的发布,但是,它会阻止任何实际的发布操作发生。

PowerShell 任务

下面是我目前在第一个任务中使用的 PowerShell

# 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"
Run Code Online (Sandbox Code Playgroud)

自定义条件

然后对于每个任务中的自定义条件,我使用以下内容,如果TriggeringArtifactSourceBranchName设置为merge.

and(succeeded(), ne(variables['TriggeringArtifactSourceBranchName'], 'merge'))
Run Code Online (Sandbox Code Playgroud)

  • 所以有一些注意事项 - 我们之前已经走过了多次构建的道路。它肯定可以解决问题,但由于我们拥有如此多的构建,管理起来变得很困难。我认为分支过滤器将是一个完美的解决方案,但是,我们经常从功能分支手动构建,并且我们希望这些构建也能够通过持续部署来获取。最后,删除持续部署确实可以解决问题,但它非常方便,我不想把它扔到路边:( (2认同)