Azure DevOps - 分支策略导致在拉取请求期间运行多个构建

时间:2021-01-05 15:50:51

标签: azure-devops pull-request azure-devops-server-2019

我们的仓库有文件夹,文件夹中的代码有时依赖于其他文件夹中的代码,但只是一个方向。解释方式:

C 依赖于 B

B 依赖于 A

我们的主节点拉取请求策略需要 3 个构建:

我们有一个构建(BuildC),它只构建文件夹 C

我们有一个构建 B 和 C 的构建 (BuildB)

我们有一个构建 A、B 和 C 的构建 (BuildA)

政策规定:

文件夹 C 中的更改需要 BuildC

文件夹 B 中的更改需要 BuildB

文件夹 A 中的更改需要 BuildA

预期效果: 根据具体情况,我希望 Pull Request 只需要三个构建中的一个。以下是案例:

BuildA - 当文件夹 A 发生变化时应该运行(即使其他地方有变化)

BuildB - 当 B(和/或 C)中有变化但 A 中没有变化时应该运行。如果文件夹 A 中有变化,则不应运行此构建

BuildC - 当文件夹 C 中仅有更改时应运行...如果文件夹 A 和/或 B 中以及 C 中存在更改...此构建不应运行。

实际发生的情况是,如果您更改文件夹 A 和 C 中的某些内容,则会运行两个构建:BuildA 和 BuildC...如果文件夹 C 中的更改依赖于文件夹 A,则 BuildC 构建失败。无论如何,运行buildC都是一种浪费。

有没有办法让 Azure DevOps 队列只有 1 个构建......但最好的一个。因此,在我们的示例中,BuildA 将运行但不会运行 BuildC...但如果更改仅在文件夹 C 中,它会运行 Build C?

1 个答案:

答案 0 :(得分:1)

使用构建触发器或策略无法完成您想要的操作。没有“文件夹 X 中有更改时不构建”。虽然有一些选择,但它们需要一些重新思考:

选项 1:使用职位和条件

  • 使用构建阶段和 4 个作业创建单个流水线。
  • 第一个作业使用命令行工具来检测哪些项目需要重建并设置输出变量
  • 其他 3 个作业依赖于第一个作业,并对其设置了条件,仅在变量(在第一个作业中设置)具有特定值时才触发。

这样您就可以完全控制所有 3 个项目的构建顺序。

选项 2:使用编排管道

选项 3:使用流水线工件

不是在构建 C 中构建 A+B+C,而是从 A+B 下载结果,然后构建 C。这将需要在每个作业结束时上传管道工件,并为每个后续作业执行增量构建下载这些工件,从而跳过构建过程。

如果您想跳过构建代码,您甚至可以下载“最后一次成功”的结果。

选项 4:使用 NuGet

使用 nuget 包来发布构建 A 的输出并在构建 B 中使用它们,而不是管道工件。甚至,在作业 A 中发布 A 并在同一构建定义中从作业 B 使用它。

选项 5:依赖增量构建

If you're running on a self-hosted agent, you can turn off the "Clean" option for your pipeline, 小心相同的代理之前已经构建了您的构建,如果将简单地重复使用上一次运行的构建输出,以防输入文件没有更改(并且您没有进行任何更改)不正确的 msbuild 自定义)。 It will essentially skip building A if msbuild can calculate it won't need to build A.


具有多个作业的单个构建的优点是您可以指定作业 A、B、C 的顺序,并且可以控制每个作业中发生的事情。最大的缺点是每个作业都会增加获取源或下载工件的开销。您可以通过明确设置要发布和恢复的部分的通配符来稍微优化一下。

如果您在后续阶段不需要源(并且不使用 YAML 管道),您可以使用我的 Don't Sync Sources 任务(即使使用 Git)跳过同步步骤,让您控制详细了解每项工作中发生的情况。

其中许多选项依赖于您确定自上次成功构建以来哪些项目包含更改的文件。您可以使用 git 或 tfvc 命令行实用程序来告诉您更改了哪些文件,但是当您打开构建批处理时,创建完美的脚本可能会有点困难,在这种情况下,多个更改将同时触发您的构建,因此您可以不只是依赖“最新变化”。在这种情况下,您可能需要使用 REST API 向 Azure DevOps 询问与此构建关联的 commitIds 或所有变更集编号,以执行适当的差异以计算哪些项目包含变更。

从长远来看,依赖具有多个作业或 nuget 包的单个构建可能会更容易维护。

相关问题