我希望能够一直通过我的YAML管道传递管道参数,而不必在每个YAML文件中都定义参数。
基本上,我有一个主要的YAML文件,该文件称为阶段YAML,该文件具有多个嵌套作业YAML,而该嵌套作业又称为嵌套步骤YAML;实质上是按照我应该使用的模板来构建我的管道:https://docs.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops
这是一个树形列表示例文件夹;
E:.
├───01_stage (many files per folder)
├───02_jobs (many files per folder)
├───03_steps (many files per folder)
└───...main pipeline files
理想情况下,我想根据管道是PROD还是NON-PROD在签出存储库时运行IF条件。我可以将其定义为参数很好,但也可以将其定义为变量。 据我所知;您不能对变量使用IF条件。
这很好
- ${{ if eq(parameters.pester, true) }}: # or even as variables['pester']
- name: pester
value: yes
这不好
- ${{ if eq(variables.pester, true) }}: # or even as variables['pester']
- name: pester
value: yes
我想让它运行的条件是嵌套在许多模板下面,而必须重新编码所有内容以确认在每个文件中声明并传递的参数值绝对是痛苦的。
这是我想要的地方:
steps:
- ${{ if eq(parameters['masterTagged'], 'true') }}: # here
- checkout: masterTagged
displayName: Repo Tagged
- ${{ if ne(parameters['masterTagged'], 'true') }}: # here
- checkout: self
displayName: Repo Self
- template: /.pipelines/03_steps/ssh_install.yml
- template: /.pipelines/03_steps/tf_install.yml
parameters:
terraformVersion: ${{ parameters['terraformVersion'] }}
- ...many more templates
这是我的主要YAML管道文件:
parameters:
- name: artifactory_base
type: boolean
default: true
# ...many more params
- name: pester
type: boolean
default: true
- name: planDeploy
type: boolean
default: true
- name: useBackupAgent
type: boolean
default: false
- name: masterTagged # key param
type: boolean
default: true
name: Team2
pr: none
resources:
repositories:
- repository: masterTagged
endpoint: nationwide-ccoe
name: my-github-org/my-github-repo
type: github
ref: refs/tags/v2.0.3
trigger: none
variables:
- template: /.pipelines/config/sub-asdfasdf.config.yml
- template: /.pipelines/config/namingstd.config.yml
- ${{ if eq(parameters.artifactory_base, true) }}:
- name: artifactory_base
value: yes
# ...many more conditions
- ${{ if eq(parameters.pester, true) }}:
- name: pester
value: yes
- ${{ if eq(parameters.planDeploy, true) }}:
- name: planDeploy
value: yes
stages:
- template: /.pipelines/01_stage/lz_deploy.yml
parameters:
${{ if eq(parameters.useBackupAgent, false) }}:
pool:
vmImage: Ubuntu 18.04
${{ if eq(parameters.useBackupAgent, true) }}:
pool:
name: backupAgents
terraformVersion: $(TERRAFORM_VERSION)
是否可以设置此masterTagged
参数并对其进行向下过滤,而不必每次都声明?
也;是否有可能以这种方式使用变量而不是参数(我知道参数会在变量之前扩展):
- ${{ if eq(variables.pester, true) }}: # or even as variables['pester']
- name: pester
value: yes
...如果是,我一直都在做错事吗?
注意:
我了解您可以在结帐任务上使用标准任务条件(如下所示);但是,在两个任务上执行“切换”操作将破坏检出存储库的文件夹路径。即使我们只检查存储库,它也会向$ SYSTEM_DEFAULTWORKINGDIRECTORY添加另一个文件夹级别。以这种方式进行操作将需要对YAML管道的当前结构进行更多的重新编码。
- checkout: masterTagged
condition: eq(variables['masterTagged'], 'true')
displayName: Repo Tagged
- checkout: self
condition: ne(variables['masterTagged'], 'true')
displayName: Repo Self
如果可以,但我知道这是不可能的(从其他人的请求中可以看出),我可以在存储库引用中启用参数或变量:
resources:
repositories:
- repository: masterTagged
endpoint: nationwide-ccoe
name: my-github-org/my-github-repo
type: github
ref: ${{ parameters.repoRef }} # here
答案 0 :(得分:0)
是否可以设置此masterTagged参数并对其进行向下过滤,而不必每次都声明?
否,因为参数“作用域”到定义它们的文件。这是由于在第一次编译管道时它们被扩展了。 (请参阅> Pipeline run sequence)
您可以在变量上使用IF条件,但是不能在模板内部的变量上使用模板表达式(用{{}}包裹),因为变量不存在/在模板扩展时尚未填充。 / p>
一个选择就是按照您建议的方式使用签出任务中的条件,并将额外的文件夹级别处理为默认工作目录。我不得不做一些类似的事情,我们的解决方案是将repo文件夹的内容复制到默认的工作目录中。
您的另一个选择是在顶级管道文件中进行检出。这样一来,您就可以使用参数来模板化结帐步骤,而不必完全将其传递给文件。我建议使用此选项,因为您不必处理第一个选项的文件夹结构问题。
这看起来像这样:
parameters:
- name: masterTagged
default: true
type: boolean
resources:
repositories:
- repository: masterTagged
endpoint: nationwide-ccoe
name: my-github-org/my-github-repo
type: github
ref: refs/tags/v2.0.3
steps:
- ${{ if eq(parameters.masterTagged, true) }}:
- checkout: masterTagged
- ${{ if eq(parameters.masterTagged, false) }}:
- checkout: self
- template: ./path/to/template.yml
我希望这能回答您的问题。