Azure Pipelines 将 YAML 用于具有不同变量值但没有 YAML 重复的多个环境(阶段)
Azure Pipelines using YAML for multiple environments (stages) with different variable values but no YAML duplication
假设我在 Azure 上有 3 个环境:开发、测试和生产。我有相同的管道来为每个环境构建和部署资源和代码,除了两个区别:
- 不同的触发分支
- 不同的变量值
这种情况的正确方法是什么?因为我至少想到了 3 个,其中 none 个是完美的:
选项 1: 我想我可以在 Azure DevOps 上创建一个管道(由 3 个分支中的任何一个触发),每个环境有 3 个阶段,每个阶段添加一个条件到 运行 取决于源分支,像这样:
condition: eq(variables['Build.SourceBranch'], 'refs/heads/a-branch-name')
并且在每个阶段引用不同的变量。但这会在每个阶段引入代码重复 - 添加或修改步骤时我必须记住编辑 3 个阶段 - 不可取。
选项 2: 在我的存储库中创建 3 个单独的 YAML 文件,每个文件都有指定的触发器分支并引用相同的变量名,然后在 Azure DevOps 上创建 3 个不同的管道,它们中的每一个都有不同的变量值。但这也会引入代码重复。
选项 3: 创建 1 个 build-and-deploy.yaml
文件作为模板,其中定义了步骤,然后创建另外 3 个引用该模板的 YAML 文件,每个文件具有不同的触发分支并在每个 Azure 管道中使用不同的变量值,如下所示:
trigger:
branches:
include:
- a-branch-name
steps:
- template: build-and-deploy.yaml
parameters:
parameterName1: $(parameterValue1)
parameterName2: $(parameterValue2)
这似乎是最好的选择,但我没有看到它在示例中的任何地方使用过,所以也许我只是不知道它的缺点,如果有的话。
根据你的描述,如果你想让不同的阶段共享同一个repo资源,但是它们的触发分支和变量值不同。
关于触发分支,可以使用表达式{{if ......}}来判断触发分支条件。
关于变量值,可以定义模板和变量组,通过参数指定。
这里有一个例子,你可以参考一下:
首先转到管道下的库,点击变量组 添加一个变量组。您可以向该变量组添加多个变量。
回购结构:
天蓝色-pipelines.yml:
样本:
stages:
- template: stage/test.yml
parameters:
${{if contains(variables['Build.SourceBranch'], 'master')}}:
variableGroup: devGroup
stageName: Dev
test: a
${{if contains(variables['Build.SourceBranch'], 'test')}}:
stageName: test
test: b
stage/test。 yml:
parameters:
- name: stageName
displayName: Test
type: string
default: test
- name: test
displayName: Test
type: string
default: test
- name: variableGroup
displayName: Test
type: string
default: test
stages:
- stage: Test_${{ parameters.stageName }}
variables:
- group: ${{parameters.variableGroup}}
jobs:
- job: Test1
pool:
vmImage: vs2017-win2016
steps:
- script: echo "Hello Test1"
- script: echo ${{ parameters.test }}
- script: echo $(dev1)
当然,如果要使用单个变量,可以直接在yaml中定义变量,不用加变量组。
以下是使用包含在环境特定管道中的共享管道配置的方法。
要支持 2 种环境(dev
和 prod
),您需要:
- 1 个共享管道 yaml
- 2 个环境特定的 yaml,每个环境一个
- 在 Azure DevOps 中创建了 2 个管道,每个环境一个;每个管道引用相应的 yaml
pipeline-shared.yml
:
variables:
ARTIFACT_NAME: ApiBuild
NPM_CACHE_FOLDER: $(Pipeline.Workspace)/.npm
stages:
- stage: Build
displayName: Build
pool:
vmImage: 'ubuntu-latest'
demands: npm
jobs:
...
- stage: Release
displayName: Release
dependsOn: Build
pool:
vmImage: 'ubuntu-latest'
jobs:
...
pipeline-dev.yml
:
# Trigger builds on commits to branches
trigger:
- dev
# Do not trigger builds on PRs
pr: none
extends:
template: pipeline-shared.yml
pipeline-prod.yml
trigger:
- master
pr: none
extends:
template: pipeline-shared.yml
假设我在 Azure 上有 3 个环境:开发、测试和生产。我有相同的管道来为每个环境构建和部署资源和代码,除了两个区别:
- 不同的触发分支
- 不同的变量值
这种情况的正确方法是什么?因为我至少想到了 3 个,其中 none 个是完美的:
选项 1: 我想我可以在 Azure DevOps 上创建一个管道(由 3 个分支中的任何一个触发),每个环境有 3 个阶段,每个阶段添加一个条件到 运行 取决于源分支,像这样:
condition: eq(variables['Build.SourceBranch'], 'refs/heads/a-branch-name')
并且在每个阶段引用不同的变量。但这会在每个阶段引入代码重复 - 添加或修改步骤时我必须记住编辑 3 个阶段 - 不可取。
选项 2: 在我的存储库中创建 3 个单独的 YAML 文件,每个文件都有指定的触发器分支并引用相同的变量名,然后在 Azure DevOps 上创建 3 个不同的管道,它们中的每一个都有不同的变量值。但这也会引入代码重复。
选项 3: 创建 1 个 build-and-deploy.yaml
文件作为模板,其中定义了步骤,然后创建另外 3 个引用该模板的 YAML 文件,每个文件具有不同的触发分支并在每个 Azure 管道中使用不同的变量值,如下所示:
trigger:
branches:
include:
- a-branch-name
steps:
- template: build-and-deploy.yaml
parameters:
parameterName1: $(parameterValue1)
parameterName2: $(parameterValue2)
这似乎是最好的选择,但我没有看到它在示例中的任何地方使用过,所以也许我只是不知道它的缺点,如果有的话。
根据你的描述,如果你想让不同的阶段共享同一个repo资源,但是它们的触发分支和变量值不同。
关于触发分支,可以使用表达式{{if ......}}来判断触发分支条件。
关于变量值,可以定义模板和变量组,通过参数指定。
这里有一个例子,你可以参考一下:
首先转到管道下的库,点击变量组 添加一个变量组。您可以向该变量组添加多个变量。
回购结构:
天蓝色-pipelines.yml:
样本:
stages: - template: stage/test.yml parameters: ${{if contains(variables['Build.SourceBranch'], 'master')}}: variableGroup: devGroup stageName: Dev test: a ${{if contains(variables['Build.SourceBranch'], 'test')}}: stageName: test test: b
stage/test。 yml:
parameters:
- name: stageName
displayName: Test
type: string
default: test
- name: test
displayName: Test
type: string
default: test
- name: variableGroup
displayName: Test
type: string
default: test
stages:
- stage: Test_${{ parameters.stageName }}
variables:
- group: ${{parameters.variableGroup}}
jobs:
- job: Test1
pool:
vmImage: vs2017-win2016
steps:
- script: echo "Hello Test1"
- script: echo ${{ parameters.test }}
- script: echo $(dev1)
当然,如果要使用单个变量,可以直接在yaml中定义变量,不用加变量组。
以下是使用包含在环境特定管道中的共享管道配置的方法。
要支持 2 种环境(dev
和 prod
),您需要:
- 1 个共享管道 yaml
- 2 个环境特定的 yaml,每个环境一个
- 在 Azure DevOps 中创建了 2 个管道,每个环境一个;每个管道引用相应的 yaml
pipeline-shared.yml
:
variables:
ARTIFACT_NAME: ApiBuild
NPM_CACHE_FOLDER: $(Pipeline.Workspace)/.npm
stages:
- stage: Build
displayName: Build
pool:
vmImage: 'ubuntu-latest'
demands: npm
jobs:
...
- stage: Release
displayName: Release
dependsOn: Build
pool:
vmImage: 'ubuntu-latest'
jobs:
...
pipeline-dev.yml
:
# Trigger builds on commits to branches
trigger:
- dev
# Do not trigger builds on PRs
pr: none
extends:
template: pipeline-shared.yml
pipeline-prod.yml
trigger:
- master
pr: none
extends:
template: pipeline-shared.yml