如何在包含许多 Dockerfile 的单一存储库中构建一个特定的 Docker 映像

问题描述 投票:0回答:1

我有一个包含 8 个不同 Dockerfile 的存储库,用于构建不同的映像。它们都在同一个存储库中,因为它们共享 80% 的相同代码。每个 Dockerfile 对应一个单独的产品。我目前有一个 azure-pipeline.yaml 文件来将 8 个 Dockerfile 构建到映像中。在制作 PR 或合并到我的主分支时,我通常只更新 8 个产品之一的功能。所以更新所有 8 张图像是没有意义的。

我想知道我可以选择哪些选项来触发我更改的产品的构建。但偶尔会触发所有 8 个构建(如果更新了共享方法)。例如,是否有一个标志功能可以用来表示当识别出该标志时,仅运行管道的这一部分?

旁注:我知道我可以将我的单一存储库拆分为许多不同的存储库,并创建一个允许共享公共代码的包。然而,这需要大量的时间投入,想知道是否有更简单的方法。

azure docker azure-devops pipeline
1个回答
0
投票

您可以在 yaml 文件中使用路径过滤器和条件的组合,根据拉取请求或提交中的更改有选择地运行构建。

1.路径过滤器

您可以使用路径过滤器来指定哪些路径应触发管道。例如,如果每个 Dockerfile 都位于单独的目录中,则可能有如下内容:

trigger:
  paths:
    include:
      - 'productA/*'

仅当

productA
目录发生更改时才会触发构建。

2.条件步骤

您可以向步骤或作业添加条件来决定它们是否应该运行。例如,您可以定义变量并使用它们有条件地运行步骤:

variables:
  isFullBuild: $[eq(variables['Build.Reason'], 'Manual')]

steps:
- script: echo Building ProductA...
  condition: or(eq(variables.isFullBuild, true), changesContain('productA/*'))

您可以将两者结合起来添加触发器并调节您的管道,如下所示。

trigger:
  branches:
    include:
    - main
  paths:
    include:
    - 'productA/*'
    - 'productB/*'
    - 'common/*'

- job: BuildProductA
  condition: or(eq(variables.isFullBuild, true), changesContain('productA/*', 'common/*'))
  steps:
  - script: echo Building ProductA...

- job: BuildProductB
  condition: or(eq(variables.isFullBuild, true), changesContain('productB/*', 'common/*'))
  steps:
  - script: echo Building ProductB...
© www.soinside.com 2019 - 2024. All rights reserved.