模板类型 & 用法
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
模板用于定义可重用的内容、逻辑和参数。 模板以两种方式发挥作用。 可以使用模板插入可重复使用的内容,也可以使用模板来控制管道中允许的内容。 第二种方法可用于 使用模板生成安全管道。
如果使用模板来包含内容,它在许多编程语言中的工作方式类似于 include 指令。 一个文件中的内容插入到另一个文件中。 当模板控制管道中允许的内容时,该模板定义另一个文件必须遵循的逻辑。
使用模板定义逻辑一次,然后多次重复使用。 模板将多个 YAML 文件的内容合并到一个管道中。 可以将参数从父管道传递到模板中。
parameters
可以在模板中指定参数及其数据类型,并将这些参数传递给管道。 还可以 在模板外部使用参数。 只能将文本用于参数默认值。
快速参考
参数必须包含名称和数据类型。 在 中 azure-pipelines.yml
,当 参数 yesNo
设置为布尔值时,生成会成功。 当 设置为字符串(如 apples
)时yesNo
,生成将失败。
# File: simple-param.yml
parameters:
- name: yesNo # name of the parameter; required
type: boolean # data type of the parameter; required
default: false
steps:
- script: echo ${{ parameters.yesNo }}
# File: azure-pipelines.yml
trigger:
- main
extends:
template: simple-param.yml
parameters:
yesNo: false # set to a non-boolean value to have the build fail
用于在运行时选择模板的参数
可以根据条件从管道 YAML 调用不同的模板。 在此示例中, experimental.yml
当 参数 experimentalTemplate
为 true 时,YAML 将运行。
#azure-pipeline.yml
parameters:
- name: experimentalTemplate
displayName: 'Use experimental build process?'
type: boolean
default: false
steps:
- ${{ if eq(parameters.experimentalTemplate, true) }}:
- template: experimental.yml
- ${{ if not(eq(parameters.experimentalTemplate, true)) }}:
- template: stable.yml
参数数据类型
数据类型 | 说明 |
---|---|
string |
字符串 |
number |
可能限制为 values: ,否则接受任何类似数字的字符串 |
boolean |
true 或 false |
object |
任何 YAML 结构 |
step |
一个步骤 |
stepList |
步骤序列 |
job |
单个作业 |
jobList |
作业序列 |
deployment |
单个部署作业 |
deploymentList |
部署作业序列 |
stage |
单个阶段 |
stageList |
阶段序列 |
步骤、stepList、作业、jobList、deployment、deploymentList、stage 和 stageList 数据类型都使用标准 YAML 架构格式。 此示例包括 string、number、boolean、object、step 和 stepList。
parameters:
- name: myString
type: string
default: a string
- name: myMultiString
type: string
default: default
values:
- default
- ubuntu
- name: myNumber
type: number
default: 2
values:
- 1
- 2
- 4
- 8
- 16
- name: myBoolean
type: boolean
default: true
- name: myObject
type: object
default:
foo: FOO
bar: BAR
things:
- one
- two
- three
nested:
one: apple
two: pear
count: 3
- name: myStep
type: step
default:
script: echo my step
- name: mySteplist
type: stepList
default:
- script: echo step one
- script: echo step two
trigger: none
jobs:
- job: stepList
steps: ${{ parameters.mySteplist }}
- job: myStep
steps:
- ${{ parameters.myStep }}
可以循环访问对象并打印对象中的每个字符串。
parameters:
- name: listOfStrings
type: object
default:
- one
- two
steps:
- ${{ each value in parameters.listOfStrings }}:
- script: echo ${{ value }}
此外,还可以循环访问 对象中的嵌套元素。
parameters:
- name: listOfFruits
type: object
default:
- fruitName: 'apple'
colors: ['red','green']
- fruitName: 'lemon'
colors: ['yellow']
steps:
- ${{ each fruit in parameters.listOfFruits }} :
- ${{ each fruitColor in fruit.colors}} :
- script: echo ${{ fruit.fruitName}} ${{ fruitColor }}
从模板扩展
若要提高安全性,可以强制管道从特定模板进行扩展。 文件 start.yml
定义参数 ,该参数 buildSteps
随后在管道 azure-pipelines.yml
中使用。
在 中 start.yml
, buildStep
如果通过脚本步骤传递 ,则会拒绝该步骤,并且管道生成失败。
从模板扩展时,可以通过添加 所需的模板审批来提高安全性。
# File: start.yml
parameters:
- name: buildSteps # the name of the parameter is buildSteps
type: stepList # data type is StepList
default: [] # default value of buildSteps
stages:
- stage: secure_buildstage
pool:
vmImage: windows-latest
jobs:
- job: secure_buildjob
steps:
- script: echo This happens before code
displayName: 'Base: Pre-build'
- script: echo Building
displayName: 'Base: Build'
- ${{ each step in parameters.buildSteps }}:
- ${{ each pair in step }}:
${{ if ne(pair.value, 'CmdLine@2') }}:
${{ pair.key }}: ${{ pair.value }}
${{ if eq(pair.value, 'CmdLine@2') }}:
# Step is rejected by raising a YAML syntax error: Unexpected value 'CmdLine@2'
'${{ pair.value }}': error
- script: echo This happens after code
displayName: 'Base: Signing'
# File: azure-pipelines.yml
trigger:
- main
extends:
template: start.yml
parameters:
buildSteps:
- bash: echo Test #Passes
displayName: succeed
- bash: echo "Test"
displayName: succeed
# Step is rejected by raising a YAML syntax error: Unexpected value 'CmdLine@2'
- task: CmdLine@2
inputs:
script: echo "Script Test"
# Step is rejected by raising a YAML syntax error: Unexpected value 'CmdLine@2'
- script: echo "Script Test"
从包含资源的模板进行扩展
还可以使用 extends
从 Azure 管道中包含资源的模板进行扩展。
# File: azure-pipelines.yml
trigger:
- none
extends:
template: resource-template.yml
# File: resource-template.yml
resources:
pipelines:
- pipeline: my-pipeline
source: sourcePipeline
steps:
- script: echo "Testing resource template"
使用 templateContext 将属性传递给模板
可以使用 templateContext
将其他属性传递给用作模板中参数的阶段、步骤和作业。 具体而言,可以在 、 deploymentList
或 stageList
参数数据类型中jobList
指定 templateContext
。
可以使用 templateContext
在处理每个作业时更轻松地设置环境。 通过将作业及其环境属性对象捆绑在一起, templateContext
可帮助你拥有更易于维护且更易于理解的 YAML。
在此示例中,中的 testing-template.yml
参数testSet
的数据类型jobList
为 。 模板testing-template.yml
使用 each 关键字创建新变量testJob
。 然后,模板会引用 testJob.templateContext.expectedHTTPResponseCode
,该元素在 中 azure-pipeline.yml
设置并传递给模板。
当响应代码为 200 时,模板会发出 REST 请求。 当响应代码为 500 时,模板将输出所有环境变量以供调试。
templateContext
可以包含属性。
#testing-template.yml
parameters:
- name: testSet
type: jobList
jobs:
- ${{ each testJob in parameters.testSet }}:
- ${{ if eq(testJob.templateContext.expectedHTTPResponseCode, 200) }}:
- job:
steps:
- powershell: 'Invoke-RestMethod -Uri https://blogs.msdn.microsoft.com/powershell/feed/ | Format-Table -Property Title, pubDate'
- ${{ testJob.steps }}
- ${{ if eq(testJob.templateContext.expectedHTTPResponseCode, 500) }}:
- job:
steps:
- powershell: 'Get-ChildItem -Path Env:\'
- ${{ testJob.steps }}
#azure-pipeline.yml
trigger: none
pool:
vmImage: ubuntu-latest
extends:
template: testing-template.yml
parameters:
testSet:
- job: positive_test
templateContext:
expectedHTTPResponseCode: 200
steps:
- script: echo "Run positive test"
- job: negative_test
templateContext:
expectedHTTPResponseCode: 500
steps:
- script: echo "Run negative test"
插入模板
可以从一个 YAML 复制内容,并在不同的 YAML 中重复使用它。 将内容从一个 YAML 复制到另一个 YAML 可避免在多个位置手动包含相同的逻辑。 文件 include-npm-steps.yml
模板包含在 中 azure-pipelines.yml
重复使用的步骤。
注意
模板文件需要在管道运行开始时存在于文件系统上。 不能引用项目中的模板。
# File: templates/include-npm-steps.yml
steps:
- script: npm install
- script: yarn install
- script: npm run compile
# File: azure-pipelines.yml
jobs:
- job: Linux
pool:
vmImage: 'ubuntu-latest'
steps:
- template: templates/include-npm-steps.yml # Template reference
- job: Windows
pool:
vmImage: 'windows-latest'
steps:
- template: templates/include-npm-steps.yml # Template reference
步骤重用
可以插入模板,以便跨多个作业重复使用一个或多个步骤。 除了模板中的步骤外,每个作业还可以定义更多步骤。
# File: templates/npm-steps.yml
steps:
- script: npm install
- script: npm test
# File: azure-pipelines.yml
jobs:
- job: Linux
pool:
vmImage: 'ubuntu-latest'
steps:
- template: templates/npm-steps.yml # Template reference
- job: macOS
pool:
vmImage: 'macOS-latest'
steps:
- template: templates/npm-steps.yml # Template reference
- job: Windows
pool:
vmImage: 'windows-latest'
steps:
- script: echo This script runs before the template's steps, only on Windows.
- template: templates/npm-steps.yml # Template reference
- script: echo This step runs after the template's steps.
作业重用
与步骤非常类似,作业可与模板一起重复使用。
# File: templates/jobs.yml
jobs:
- job: Ubuntu
pool:
vmImage: 'ubuntu-latest'
steps:
- bash: echo "Hello Ubuntu"
- job: Windows
pool:
vmImage: 'windows-latest'
steps:
- bash: echo "Hello Windows"
# File: azure-pipelines.yml
jobs:
- template: templates/jobs.yml # Template reference
使用多个作业时,请记得在模板文件中删除作业的名称,以避免冲突
# File: templates/jobs.yml
jobs:
- job:
pool:
vmImage: 'ubuntu-latest'
steps:
- bash: echo "Hello Ubuntu"
- job:
pool:
vmImage: 'windows-latest'
steps:
- bash: echo "Hello Windows"
# File: azure-pipelines.yml
jobs:
- template: templates/jobs.yml # Template reference
- template: templates/jobs.yml # Template reference
- template: templates/jobs.yml # Template reference
阶段重用
阶段还可以与模板一起重复使用。
# File: templates/stages1.yml
stages:
- stage: Angular
jobs:
- job: angularinstall
steps:
- script: npm install angular
# File: templates/stages2.yml
stages:
- stage: Build
jobs:
- job: build
steps:
- script: npm run build
# File: azure-pipelines.yml
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: Install
jobs:
- job: npminstall
steps:
- task: Npm@1
inputs:
command: 'install'
- template: templates/stages1.yml
- template: templates/stages2.yml
包含参数的作业、阶段和步骤模板
# File: templates/npm-with-params.yml
parameters:
- name: name # defaults for any parameters that aren't specified
default: ''
- name: vmImage
default: ''
jobs:
- job: ${{ parameters.name }}
pool:
vmImage: ${{ parameters.vmImage }}
steps:
- script: npm install
- script: npm test
在管道中使用模板时,请指定模板参数的值。
# File: azure-pipelines.yml
jobs:
- template: templates/npm-with-params.yml # Template reference
parameters:
name: Linux
vmImage: 'ubuntu-latest'
- template: templates/npm-with-params.yml # Template reference
parameters:
name: macOS
vmImage: 'macOS-latest'
- template: templates/npm-with-params.yml # Template reference
parameters:
name: Windows
vmImage: 'windows-latest'
还可以将参数与步骤模板或阶段模板一起使用。 例如,包含参数的步骤:
# File: templates/steps-with-params.yml
parameters:
- name: 'runExtendedTests' # defaults for any parameters that aren't specified
type: boolean
default: false
steps:
- script: npm test
- ${{ if eq(parameters.runExtendedTests, true) }}:
- script: npm test --extended
在管道中使用模板时,请指定模板参数的值。
# File: azure-pipelines.yml
steps:
- script: npm install
- template: templates/steps-with-params.yml # Template reference
parameters:
runExtendedTests: 'true'
注意
没有指定类型的标量参数被视为字符串。
例如, eq(true, parameters['myparam'])
将返回 true
,即使 myparam
参数是单词 false
,如果未 myparam
显式设置 boolean
。
非空字符串在布尔上下文中强制转换为 true
。
可以重写该 表达式 以显式比较字符串: eq(parameters['myparam'], 'true')
。
参数不限于标量字符串。
请参阅 数据类型列表。
例如,使用 object
类型:
# azure-pipelines.yml
jobs:
- template: process.yml
parameters:
pool: # this parameter is called `pool`
vmImage: ubuntu-latest # and it's a mapping rather than a string
# process.yml
parameters:
- name: 'pool'
type: object
default: {}
jobs:
- job: build
pool: ${{ parameters.pool }}
变量重用
变量可以在一个 YAML 中定义,并包含在另一个模板中。 如果要将所有变量存储在一个文件中,这可能很有用。 如果使用模板在管道中包含变量,则包含的模板只能用于定义变量。 从模板进行扩展时,可以使用步骤和更复杂的逻辑。 如果要限制类型,请使用 参数 而不是变量。
在此示例中, 变量 favoriteVeggie
包含在 中 azure-pipelines.yml
。
# File: vars.yml
variables:
favoriteVeggie: 'brussels sprouts'
# File: azure-pipelines.yml
variables:
- template: vars.yml # Template reference
steps:
- script: echo My favorite vegetable is ${{ variables.favoriteVeggie }}.
带参数的变量模板
可以使用模板将参数传递给变量。 在此示例中,你要将 DIRECTORY
参数传递给变量 RELEASE_COMMAND
。
# File: templates/package-release-with-params.yml
parameters:
- name: DIRECTORY
type: string
default: "." # defaults for any parameters that specified with "." (current directory)
variables:
- name: RELEASE_COMMAND
value: grep version ${{ parameters.DIRECTORY }}/package.json | awk -F \" '{print $4}'
在管道中使用模板时,请指定模板参数的值。
# File: azure-pipelines.yml
variables: # Global variables
- template: package-release-with-params.yml # Template reference
parameters:
DIRECTORY: "azure/checker"
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: Release_Stage
displayName: Release Version
variables: # Stage variables
- template: package-release-with-params.yml # Template reference
parameters:
DIRECTORY: "azure/todo-list"
jobs:
- job: A
steps:
- bash: $(RELEASE_COMMAND) #output release command
引用模板路径
模板路径应相对于执行 包括 的文件。 下面是一个嵌套层次结构示例。
|
+-- fileA.yml
|
+-- dir1/
|
+-- fileB.yml
|
+-- dir2/
|
+-- fileC.yml
然后,在 中 fileA.yml
,可以引用 fileB.yml
和 fileC.yml
喜欢此。
steps:
- template: dir1/fileB.yml
- template: dir1/dir2/fileC.yml
如果 fileC.yml
是起点,则可以包括 fileA.yml
和 fileB.yml
,如下所示。
steps:
- template: ../../fileA.yml
- template: ../fileB.yml
当是起点时 fileB.yml
,可以包括 fileA.yml
和 fileC.yml
,如下所示。
steps:
- template: ../fileA.yml
- template: dir2/fileC.yml
使用其他存储库
可以将模板保留在其他存储库中。 例如,假设你有一个核心管道,你希望所有应用管道都使用该管道。 可以将模板放在核心存储库中,然后从每个应用存储库中引用它:
# Repo: Contoso/BuildTemplates
# File: common.yml
parameters:
- name: 'vmImage'
default: 'ubuntu 16.04'
type: string
jobs:
- job: Build
pool:
vmImage: ${{ parameters.vmImage }}
steps:
- script: npm install
- script: npm test
现在可以在多个管道中重复使用此模板。
resources
使用规范提供核心存储库的位置。
引用核心存储库时,请使用 @
并在 中 resources
提供它的名称。
# Repo: Contoso/LinuxProduct
# File: azure-pipelines.yml
resources:
repositories:
- repository: templates
type: github
name: Contoso/BuildTemplates
jobs:
- template: common.yml@templates # Template reference
# Repo: Contoso/WindowsProduct
# File: azure-pipelines.yml
resources:
repositories:
- repository: templates
type: github
name: Contoso/BuildTemplates
ref: refs/tags/v1.0 # optional ref to pin to
jobs:
- template: common.yml@templates # Template reference
parameters:
vmImage: 'windows-latest'
对于 type: github
, name
如 <identity>/<repo>
上例所示。
对于type: git
(Azure Repos) ,name
为 <project>/<repo>
。
如果该项目位于单独的 Azure DevOps 组织中,则需要配置具有项目访问权限的服务 连接 类型 Azure Repos/Team Foundation Server
,并将其包含在 YAML 中:
resources:
repositories:
- repository: templates
name: Contoso/BuildTemplates
endpoint: myServiceConnection # Azure DevOps service connection
jobs:
- template: common.yml@templates
当管道启动时,存储库仅解析一次。 之后,在管道的持续时间内使用相同的资源。 仅使用模板文件。 完全扩展模板后,最终管道就如同完全在源存储库中定义一样运行。 这意味着不能在管道中使用模板存储库中的脚本。
如果要使用模板的特定固定版本,请确保固定到 ref
。
是 refs
分支 (refs/heads/<name>
) 或标记 (refs/tags/<name>
) 。
如果要固定特定提交,请先创建一个指向该提交的标记,然后固定到该标记。
注意
ref
如果未指定 ,则管道将默认使用 refs/heads/main
。
还可以使用 @self
引用找到原始管道的存储库。
如果要引用扩展管道存储库中 extends
的内容,这在模板中使用起来很方便。
例如:
# Repo: Contoso/Central
# File: template.yml
jobs:
- job: PreBuild
steps: []
# Template reference to the repo where this template was
# included from - consumers of the template are expected
# to provide a "BuildJobs.yml"
- template: BuildJobs.yml@self
- job: PostBuild
steps: []
# Repo: Contoso/MyProduct
# File: azure-pipelines.yml
resources:
repositories:
- repository: templates
type: git
name: Contoso/Central
extends:
template: template.yml@templates
# Repo: Contoso/MyProduct
# File: BuildJobs.yml
jobs:
- job: Build
steps: []
模板表达式
使用模板 表达式 指定如何在管道初始化期间动态解析值。
将模板表达式包装在此语法中: ${{ }}
。
模板表达式可以扩展模板参数以及变量。
可以使用参数来影响模板的扩展方式。
对象parameters
的工作方式类似于variables
表达式中的 对象。 在模板表达式中只能使用预定义变量。
注意
表达式仅在) 中resources
展开stages
jobs
、、 steps
和 containers
(。
例如,不能使用 内部 trigger
的表达式或资源(例如 repositories
)。
此外,在 Azure DevOps 2020 RTW 上,不能在 中使用 containers
模板表达式。
例如,定义模板:
# File: steps/msbuild.yml
parameters:
- name: 'solution'
default: '**/*.sln'
type: string
steps:
- task: msbuild@1
inputs:
solution: ${{ parameters['solution'] }} # index syntax
- task: vstest@2
inputs:
solution: ${{ parameters.solution }} # property dereference syntax
然后,引用模板并向其传递可选 solution
参数:
# File: azure-pipelines.yml
steps:
- template: steps/msbuild.yml
parameters:
solution: my.sln
上下文
在模板表达式中,可以访问 parameters
包含传入的参数值的上下文。
此外,还可以访问 variables
包含 YAML 文件中指定的所有变量的上下文,以及) 主题中每个变量 (许多 预定义变量 。
重要的是,它没有运行时变量(例如管道中存储的变量),也没有在启动运行时给定的运行时变量。
模板扩展 发生在运行初期,因此这些变量不可用。
必需的参数
可以在模板的开头添加验证步骤,以检查所需的参数。
以下示例使用 Bash (检查 solution
参数,使参数能够在任何平台) 工作:
# File: steps/msbuild.yml
parameters:
- name: 'solution'
default: ''
type: string
steps:
- bash: |
if [ -z "$SOLUTION" ]; then
echo "##vso[task.logissue type=error;]Missing template parameter \"solution\""
echo "##vso[task.complete result=Failed;]"
fi
env:
SOLUTION: ${{ parameters.solution }}
displayName: Check for required parameters
- task: msbuild@1
inputs:
solution: ${{ parameters.solution }}
- task: vstest@2
inputs:
solution: ${{ parameters.solution }}
若要显示模板在缺少所需的参数时失败,请执行以下操作:
# File: azure-pipelines.yml
# This will fail since it doesn't set the "solution" parameter to anything,
# so the template will use its default of an empty string
steps:
- template: steps/msbuild.yml
模板表达式函数
可以在模板中使用 常规函数 。 还可以使用一些模板表达式函数。
format
- 简单字符串令牌替换
- 最小参数:2。 最大参数:N
- 示例:
${{ format('{0} Build', parameters.os) }}
→'Windows Build'
coalesce
- 计算结果为第一个非空、非 null 字符串参数
- 最小参数:2。 最大参数:N
- 例如:
parameters:
- name: 'restoreProjects'
default: ''
type: string
- name: 'buildProjects'
default: ''
type: string
steps:
- script: echo ${{ coalesce(parameters.foo, parameters.bar, 'Nothing to see') }}
插入
可以使用模板表达式来更改 YAML 管道的结构。 例如,若要插入序列:
# File: jobs/build.yml
parameters:
- name: 'preBuild'
type: stepList
default: []
- name: 'preTest'
type: stepList
default: []
- name: 'preSign'
type: stepList
default: []
jobs:
- job: Build
pool:
vmImage: 'windows-latest'
steps:
- script: cred-scan
- ${{ parameters.preBuild }}
- task: msbuild@1
- ${{ parameters.preTest }}
- task: vstest@2
- ${{ parameters.preSign }}
- script: sign
# File: .vsts.ci.yml
jobs:
- template: jobs/build.yml
parameters:
preBuild:
- script: echo hello from pre-build
preTest:
- script: echo hello from pre-test
将数组插入数组时,嵌套数组将平展。
若要插入到映射中,请使用特殊属性 ${{ insert }}
。
# Default values
parameters:
- name: 'additionalVariables'
type: object
default: {}
jobs:
- job: build
variables:
configuration: debug
arch: x86
${{ insert }}: ${{ parameters.additionalVariables }}
steps:
- task: msbuild@1
- task: vstest@2
jobs:
- template: jobs/build.yml
parameters:
additionalVariables:
TEST_SUITE: L0,L1
条件插入
如果要有条件地插入到序列或模板中的映射中,请使用插入和表达式计算。 只要使用 if
模板语法,还可以在 模板外部 使用语句。
例如,若要在模板中插入序列,请执行以下操作:
# File: steps/build.yml
parameters:
- name: 'toolset'
default: msbuild
type: string
values:
- msbuild
- dotnet
steps:
# msbuild
- ${{ if eq(parameters.toolset, 'msbuild') }}:
- task: msbuild@1
- task: vstest@2
# dotnet
- ${{ if eq(parameters.toolset, 'dotnet') }}:
- task: dotnet@1
inputs:
command: build
- task: dotnet@1
inputs:
command: test
# File: azure-pipelines.yml
steps:
- template: steps/build.yml
parameters:
toolset: dotnet
例如,若要插入模板中的映射,请执行以下操作:
# File: steps/build.yml
parameters:
- name: 'debug'
type: boolean
default: false
steps:
- script: tool
env:
${{ if eq(parameters.debug, true) }}:
TOOL_DEBUG: true
TOOL_DEBUG_DIR: _dbg
steps:
- template: steps/build.yml
parameters:
debug: true
还可以对变量使用条件插入。 在此示例中,start
始终打印 ,并且this is a test
仅当变量等于 test
时打印foo
。
variables:
- name: foo
value: test
pool:
vmImage: 'ubuntu-latest'
steps:
- script: echo "start" # always runs
- ${{ if eq(variables.foo, 'test') }}:
- script: echo "this is a test" # runs when foo=test
迭代插入
指令 each
允许基于 YAML 序列 (数组) 或映射 (键值对) 进行迭代插入。
例如,可以使用其他前步骤和后步骤包装每个作业的步骤:
# job.yml
parameters:
- name: 'jobs'
type: jobList
default: []
jobs:
- ${{ each job in parameters.jobs }}: # Each job
- ${{ each pair in job }}: # Insert all properties other than "steps"
${{ if ne(pair.key, 'steps') }}:
${{ pair.key }}: ${{ pair.value }}
steps: # Wrap the steps
- task: SetupMyBuildTools@1 # Pre steps
- ${{ job.steps }} # Users steps
- task: PublishMyTelemetry@1 # Post steps
condition: always()
# azure-pipelines.yml
jobs:
- template: job.yml
parameters:
jobs:
- job: A
steps:
- script: echo This will get sandwiched between SetupMyBuildTools and PublishMyTelemetry.
- job: B
steps:
- script: echo So will this!
还可以操作要循环访问的任何属性。 例如,添加更多依赖项:
# job.yml
parameters:
- name: 'jobs'
type: jobList
default: []
jobs:
- job: SomeSpecialTool # Run your special tool in its own job first
steps:
- task: RunSpecialTool@1
- ${{ each job in parameters.jobs }}: # Then do each job
- ${{ each pair in job }}: # Insert all properties other than "dependsOn"
${{ if ne(pair.key, 'dependsOn') }}:
${{ pair.key }}: ${{ pair.value }}
dependsOn: # Inject dependency
- SomeSpecialTool
- ${{ if job.dependsOn }}:
- ${{ job.dependsOn }}
# azure-pipelines.yml
jobs:
- template: job.yml
parameters:
jobs:
- job: A
steps:
- script: echo This job depends on SomeSpecialTool, even though it's not explicitly shown here.
- job: B
dependsOn:
- A
steps:
- script: echo This job depends on both Job A and on SomeSpecialTool.
转义值
如果需要转义字面上包含 ${{
的值,请将该值包装在表达式字符串中。 例如,${{ 'my${{value' }}
或 ${{ 'my${{value with a '' single quote too' }}
施加的限制
模板和模板表达式可能会导致管道的大小和复杂性的爆炸性增长。 为了帮助防止失控增长,Azure Pipelines 施加了以下限制:
- 不能直接或间接包含超过 100 个单独的 YAML 文件 ()
- 不超过 20 个级别的模板嵌套 (模板,包括其他模板)
- 实际上,分析 YAML (时消耗的内存不超过 10 MB,这通常介于 600 KB - 2 MB 的磁盘 YAML 之间,具体取决于使用的特定功能)
模板参数
可以将参数传递给模板。
节 parameters
定义模板中可用的参数及其默认值。
模板在管道运行前进行扩展,以便将周围 ${{ }}
值替换为它从封闭管道接收的参数。 因此,参数中只能使用 预定义变量 。
若要跨多个管道使用参数,请参阅如何创建 变量组。
包含参数的作业、阶段和步骤模板
# File: templates/npm-with-params.yml
parameters:
name: '' # defaults for any parameters that aren't specified
vmImage: ''
jobs:
- job: ${{ parameters.name }}
pool:
vmImage: ${{ parameters.vmImage }}
steps:
- script: npm install
- script: npm test
在管道中使用模板时,请指定模板参数的值。
# File: azure-pipelines.yml
jobs:
- template: templates/npm-with-params.yml # Template reference
parameters:
name: Linux
vmImage: 'ubuntu-latest'
- template: templates/npm-with-params.yml # Template reference
parameters:
name: macOS
vmImage: 'macOS-10.13'
- template: templates/npm-with-params.yml # Template reference
parameters:
name: Windows
vmImage: 'windows-latest'
还可以将参数与步骤模板或阶段模板一起使用。 例如,包含参数的步骤:
# File: templates/steps-with-params.yml
parameters:
runExtendedTests: 'false' # defaults for any parameters that aren't specified
steps:
- script: npm test
- ${{ if eq(parameters.runExtendedTests, 'true') }}:
- script: npm test --extended
在管道中使用模板时,请指定模板参数的值。
# File: azure-pipelines.yml
steps:
- script: npm install
- template: templates/steps-with-params.yml # Template reference
parameters:
runExtendedTests: 'true'
注意
标量参数始终被视为字符串。
例如, eq(parameters['myparam'], true)
几乎总是返回 true
,即使 myparam
参数是单词 false
。
非空字符串在布尔上下文中强制转换为 true
。
可以重写该 表达式 以显式比较字符串: eq(parameters['myparam'], 'true')
。
参数不限于标量字符串。 只要参数展开的位置需要映射,参数就可以是映射。 同样,可以在需要序列的位置传递序列。 例如:
# azure-pipelines.yml
jobs:
- template: process.yml
parameters:
pool: # this parameter is called `pool`
vmImage: ubuntu-latest # and it's a mapping rather than a string
# process.yml
parameters:
pool: {}
jobs:
- job: build
pool: ${{ parameters.pool }}
使用其他存储库
可以将模板保留在其他存储库中。 例如,假设你有一个核心管道,你希望所有应用管道都使用该管道。 可以将模板放在核心存储库中,然后从每个应用存储库中引用它:
# Repo: Contoso/BuildTemplates
# File: common.yml
parameters:
vmImage: 'ubuntu 16.04'
jobs:
- job: Build
pool:
vmImage: ${{ parameters.vmImage }}
steps:
- script: npm install
- script: npm test
现在可以在多个管道中重复使用此模板。
resources
使用规范提供核心存储库的位置。
引用核心存储库时,请使用 @
并在 中 resources
提供它的名称。
# Repo: Contoso/LinuxProduct
# File: azure-pipelines.yml
resources:
repositories:
- repository: templates
type: github
name: Contoso/BuildTemplates
jobs:
- template: common.yml@templates # Template reference
# Repo: Contoso/WindowsProduct
# File: azure-pipelines.yml
resources:
repositories:
- repository: templates
type: github
name: Contoso/BuildTemplates
ref: refs/tags/v1.0 # optional ref to pin to
jobs:
- template: common.yml@templates # Template reference
parameters:
vmImage: 'windows-latest'
对于 type: github
, name
如 <identity>/<repo>
上例所示。
对于type: git
(Azure Repos) ,name
为 <project>/<repo>
。
项目必须位于同一组织中;不支持跨组织引用。
当管道启动时,存储库仅解析一次。 之后,在管道期间使用相同的资源。 仅使用模板文件。 完全扩展模板后,最终管道就如同完全在源存储库中定义一样运行。 这意味着不能在管道中使用模板存储库中的脚本。
如果要使用模板的特定固定版本,请确保固定到引用。ref 是分支 (refs/heads/<name>
) 或标记 (refs/tags/<name>
) 。
如果要固定特定提交,请先创建一个指向该提交的标记,然后固定到该标记。
表达式
使用模板 表达式 指定如何在管道初始化期间动态解析值。
将模板表达式包装在此语法中: ${{ }}
。
模板表达式可以扩展模板参数以及变量。
可以使用参数来影响模板的扩展方式。
对象parameters
的工作方式类似于variables
表达式中的 对象。
例如,定义模板:
# File: steps/msbuild.yml
parameters:
solution: '**/*.sln'
steps:
- task: msbuild@1
inputs:
solution: ${{ parameters['solution'] }} # index syntax
- task: vstest@2
inputs:
solution: ${{ parameters.solution }} # property dereference syntax
然后,引用模板并向其传递可选 solution
参数:
# File: azure-pipelines.yml
steps:
- template: steps/msbuild.yml
parameters:
solution: my.sln
上下文
在模板表达式中,可以访问 parameters
上下文,其中包含传入的参数的值。
此外,还可以访问 variables
上下文,其中包含 YAML 文件中指定的所有变量以及 系统变量。
重要的是,它没有运行时变量(例如管道中存储的变量),也没有在启动运行时给定的运行时变量。
模板扩展 发生在运行早期,因此这些变量不可用。
必需的参数
可以在模板的开头添加验证步骤,以检查所需的参数。
以下示例使用 Bash (检查 solution
参数,使参数能够在任何平台) 工作:
# File: steps/msbuild.yml
parameters:
solution: ''
steps:
- bash: |
if [ -z "$SOLUTION" ]; then
echo "##vso[task.logissue type=error;]Missing template parameter \"solution\""
echo "##vso[task.complete result=Failed;]"
fi
env:
SOLUTION: ${{ parameters.solution }}
displayName: Check for required parameters
- task: msbuild@1
inputs:
solution: ${{ parameters.solution }}
- task: vstest@2
inputs:
solution: ${{ parameters.solution }}
若要显示模板在缺少所需的参数时失败,请执行以下操作:
# File: azure-pipelines.yml
# This will fail since it doesn't set the "solution" parameter to anything,
# so the template will use its default of an empty string
steps:
- template: steps/msbuild.yml
模板表达式函数
可以在模板中使用 常规函数 。 还可以使用一些模板表达式函数。
format
- 简单字符串令牌替换
- 最小参数:2。 最大参数:N
- 示例:
${{ format('{0} Build', parameters.os) }}
→'Windows Build'
coalesce
- 计算结果为第一个非空、非 null 字符串参数
- 最小参数:2。 最大参数:N
- 例如:
parameters:
restoreProjects: ''
buildProjects: ''
steps:
- script: echo ${{ coalesce(parameters.foo, parameters.bar, 'Nothing to see') }}
插入
可以使用模板表达式来更改 YAML 管道的结构。 例如,若要插入序列:
# File: jobs/build.yml
parameters:
preBuild: []
preTest: []
preSign: []
jobs:
- job: Build
pool:
vmImage: 'windows-latest'
steps:
- script: cred-scan
- ${{ parameters.preBuild }}
- task: msbuild@1
- ${{ parameters.preTest }}
- task: vstest@2
- ${{ parameters.preSign }}
- script: sign
# File: .vsts.ci.yml
jobs:
- template: jobs/build.yml
parameters:
preBuild:
- script: echo hello from pre-build
preTest:
- script: echo hello from pre-test
将数组插入数组时,嵌套数组将平展。
若要插入到映射中,请使用特殊属性 ${{ insert }}
。
# Default values
parameters:
additionalVariables: {}
jobs:
- job: build
variables:
configuration: debug
arch: x86
${{ insert }}: ${{ parameters.additionalVariables }}
steps:
- task: msbuild@1
- task: vstest@2
jobs:
- template: jobs/build.yml
parameters:
additionalVariables:
TEST_SUITE: L0,L1
条件插入
如果要有条件地插入序列或映射,请使用插入和表达式计算。
例如,在序列中插入:
# File: steps/build.yml
parameters:
toolset: msbuild
steps:
# msbuild
- ${{ if eq(parameters.toolset, 'msbuild') }}:
- task: msbuild@1
- task: vstest@2
# dotnet
- ${{ if eq(parameters.toolset, 'dotnet') }}:
- task: dotnet@1
inputs:
command: build
- task: dotnet@1
inputs:
command: test
# File: azure-pipelines.yml
steps:
- template: steps/build.yml
parameters:
toolset: dotnet
例如,若要插入到映射中:
# File: steps/build.yml
parameters:
debug: false
steps:
- script: tool
env:
${{ if eq(parameters.debug, 'true') }}:
TOOL_DEBUG: true
TOOL_DEBUG_DIR: _dbg
steps:
- template: steps/build.yml
parameters:
debug: true
迭代插入
指令 each
允许基于 YAML 序列 (数组) 或映射 (键值对) 进行迭代插入。
例如,可以使用额外的前步骤和后步骤包装每个作业的步骤:
# job.yml
parameters:
jobs: []
jobs:
- ${{ each job in parameters.jobs }}: # Each job
- ${{ each pair in job }}: # Insert all properties other than "steps"
${{ if ne(pair.key, 'steps') }}:
${{ pair.key }}: ${{ pair.value }}
steps: # Wrap the steps
- task: SetupMyBuildTools@1 # Pre steps
- ${{ job.steps }} # Users steps
- task: PublishMyTelemetry@1 # Post steps
condition: always()
# azure-pipelines.yml
jobs:
- template: job.yml
parameters:
jobs:
- job: A
steps:
- script: echo This will get sandwiched between SetupMyBuildTools and PublishMyTelemetry.
- job: B
steps:
- script: echo So will this!
还可以操作要循环访问的任何属性。 例如,添加更多依赖项:
# job.yml
parameters:
jobs: []
jobs:
- job: SomeSpecialTool # Run your special tool in its own job first
steps:
- task: RunSpecialTool@1
- ${{ each job in parameters.jobs }}: # Then do each job
- ${{ each pair in job }}: # Insert all properties other than "dependsOn"
${{ if ne(pair.key, 'dependsOn') }}:
${{ pair.key }}: ${{ pair.value }}
dependsOn: # Inject dependency
- SomeSpecialTool
- ${{ if job.dependsOn }}:
- ${{ job.dependsOn }}
# azure-pipelines.yml
jobs:
- template: job.yml
parameters:
jobs:
- job: A
steps:
- script: echo This job depends on SomeSpecialTool, even though it's not explicitly shown here.
- job: B
dependsOn:
- A
steps:
- script: echo This job depends on both Job A and on SomeSpecialTool.
转义
如果需要转义字面上包含 ${{
的值,请将该值包装在表达式字符串中。 例如,${{ 'my${{value' }}
或 ${{ 'my${{value with a '' single quote too' }}
限制
模板和模板表达式可能会导致管道的大小和复杂性的爆炸性增长。 为了帮助防止失控增长,Azure Pipelines 施加了以下限制:
- 不能直接或间接包含超过 50 个单独的 YAML 文件 ()
- 实际上,分析 YAML (时消耗的内存不超过 10 MB,这通常介于 600 KB - 2 MB 的磁盘 YAML 之间,具体取决于使用的特定功能)
- 每个模板表达式不允许超过 2000 个字符