表达式
Azure DevOps Services | Azure DevOps Server 2020 | Azure DevOps Server 2019 | TFS 2018
注意
在 Microsoft Team Foundation Server (TFS) 2018 和更低版本中,生成和发布管道被称为“定义”,运行被称为“生成”,服务连接被称为“服务终结点”,阶段被称为“环境”,而作业被称为“阶段” 。
表达式可在许多位置使用,在创作管道时需要指定字符串、布尔值或数字值。 表达式的最常见用法是在确定作业还是步骤应运行 的情况下 。
# Expressions are used to define conditions for a step, job, or stage
steps:
- task: ...
condition: <expression>
表达式的另一个常见用途是定义变量。
可以在 编译时 或 运行时计算表达式。
可在任意位置使用编译时间表达式;运行时表达式可用于变量和条件。 运行时表达式旨在计算变量和状态 (示例的内容: condition) 。
# Two examples of expressions used to define variables
# The first one, a, is evaluated when the YAML file is compiled into a plan.
# The second one, b, is evaluated at runtime.
# Note the syntax ${{}} for compile time and $[] for runtime expressions.
variables:
a: ${{ <expression> }}
b: $[ <expression> ]
运行时和编译时间表达式语法之间的差异主要是可用的上下文。
在编译时表达式 (${{ <expression> }}) 中,可以访问 parameters 静态定义和静态定义 variables。
在运行时表达式 ($[ <expression> ]) 中,可以访问更多参数,但无权访问参数 variables 。
在此示例中,运行时表达式设置值 $(isMain)。 编译表达式中的静态变量设置值 $(compileVar)。
variables:
staticVar: 'my value' # static variable
compileVar: ${{ variables.staticVar }} # compile time expression
isMain: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')] # runtime expression
steps:
- script: |
echo ${{variables.staticVar}} # outputs my value
echo $(compileVar) # outputs my value
echo $(isMain) # outputs True
表达式可以是文本、对变量的引用、对依赖项的引用、函数或这些表达式的有效嵌套组合。
文本
作为表达式的一部分,可以使用布尔值、null、数字、字符串或版本文本。
# Examples
variables:
someBoolean: ${{ true }} # case insensitive, so True or TRUE also works
someNumber: ${{ -1.2 }}
someString: ${{ 'a b c' }}
someVersion: ${{ 1.2.3 }}
Boolean
True 是 False 布尔文本表达式。
Null
Null 是从字典未命中返回的特殊文本表达式,例如 () variables['noSuch'] 。 Null 可以是表达式的输出,但不能直接在表达式中调用。
数量
以“-”、“.”或“0”到“9”开头。
字符串
必须为单引号。 例如:'this is a string'。
若要表达文本单引号,请使用单引号对其进行转义。
例如:'It''s OK if they''re using contractions.'。
可以将管道字符 (|) 用于多行字符串。
myKey: |
one
two
three
版本
最多四个段的版本号。
必须以数字开头,并且包含两三个句点 (.) 字符。
例如:1.2.3.4。
变量
作为表达式的一部分,可以使用两种语法之一访问变量:
- 索引语法:
variables['MyVar'] - 属性取消引用语法:
variables.MyVar
若要使用属性取消引用语法,属性名称必须:
- "开始"菜单或
a-Z_ - 后跟
a-Z0-9或_
根据执行上下文,可以使用不同的变量。
变量始终是字符串。 如果要使用类型化值,则应改用 参数 。
注意
通过变量选项卡 UI 设置此类变量时,将变量与经典管道和 YAML 管道的表达式结合使用存在限制。 定义为表达式的变量不应依赖于具有值表达式的另一个变量 ,因为不能保证 两个表达式都将正确计算。 例如,我们有一个变量 a ,其值 $[ <expression> ] 用作变量 b值的一部分。 由于处理变量的顺序不能保证变量 b 在计算后可能具有不正确的变量 a 值。
仅当通过 YAML 管道中的 变量关键字设置变量 时,才允许使用描述的构造。 需要按变量的处理顺序放置变量,以便在处理后获取正确的值。
函数
以下内置函数可用于表达式。
和
- 评估结果为
True:所有参数是否为True - 最小参数:2。 最大参数:N
- 将参数强制转换为布尔值以供计算
- 第一次后短路
False - 示例:
and(eq(variables.letters, 'ABC'), eq(variables.numbers, 123))
coalesce
- 按顺序计算参数,并返回不等于 null 或空字符串的值。
- 最小参数:2。 最大参数:N
- 示例:
coalesce(variables.couldBeNull, variables.couldAlsoBeNull, 'literal so it always works')
contains
- 评估
True左参数字符串是否包含右参数 - 最小参数:2。 最大参数:2
- 将参数强制转换为字符串以供评估
- 执行序号忽略大小写比较
- 示例:
contains('ABCDE', 'BCD')(返回 True)
containsValue
- 计算
True左侧参数是否为数组,并且任何项是否等于右参数。 还计算True左参数是否为对象,并且任何属性的值是否等于右参数。 - 最小参数:2。 最大参数:2
- 如果左参数是数组,请转换每个项以匹配右参数的类型。 如果左侧参数是对象,请转换每个属性的值以匹配右侧参数的类型。 如果转换失败,则每个特定项的相等比较计算
False结果。 - 字符串的序号忽略大小写比较
- 第一场比赛后短路
注意
YAML 管道中没有用于指定数组的文本语法。 此函数在常规管道中使用有限。 它旨在用于 管道修饰器上下文 和系统提供的数组,例如步骤列表。
可以使用 containsValue 表达式在对象中查找匹配值。 下面是一个示例,演示如何在源分支列表中查找匹配 Build.SourceBranch项。
parameters:
- name: branchOptions
displayName: Source branch options
type: object
default:
- refs/heads/main
- refs/heads/test
jobs:
- job: A1
steps:
- ${{ each value in parameters.branchOptions }}:
- script: echo ${{ value }}
- job: B1
condition: ${{ containsValue(parameters.branchOptions, variables['Build.SourceBranch']) }}
steps:
- script: echo "Matching branch found"
convertToJson
- 获取复杂对象并将其输出为 JSON。
- 最小参数:1。 最大参数:1。
parameters:
- name: listOfValues
type: object
default:
this_is:
a_complex: object
with:
- one
- two
steps:
- script: |
echo "${MY_JSON}"
env:
MY_JSON: ${{ convertToJson(parameters.listOfValues) }}
脚本输出:
{
"this_is": {
"a_complex": "object",
"with": [
"one",
"two"
]
}
}
counter
- 此函数只能在定义变量的表达式中使用。 它不能用作步骤、作业或阶段条件的一部分。
- 计算一个数字,该数字随管道的每个运行而递增。
- 参数:2。
prefix和seed。 - 前缀是字符串表达式。 针对每个前缀的唯一值跟踪计数器的单独值。 应
prefix使用 UTF-16 个字符。 - 种子是计数器的起始值
可以创建一个计数器,该计数器在每次执行管道时自动递增一个。 定义计数器时,提供一个 prefix 和一个 seed。 下面是演示这一点的示例。
variables:
major: 1
# define minor as a counter with the prefix as variable major, and seed as 100.
minor: $[counter(variables['major'], 100)]
steps:
- bash: echo $(minor)
在管道的第一次运行中上述示例中的值 minor 将为 100。 第二次运行时,它将为 101,前提是该值 major 仍为 1。
如果编辑 YAML 文件,并将变量 major 的值更新为 2,则在管道的下一个运行中,该值 minor 将为 100。 后续运行会将计数器递增到 101、102、103、 ...
稍后,如果编辑 YAML 文件并将值 major 设置为 1,则计数器的值将恢复该前缀的离开位置。 在此示例中,它恢复为 102。
下面是将变量设置为以 100 开始的计数器的另一个示例,每个运行将递增 1,并每天重置为 100。
注意
pipeline.startTime 在表达式外部不可用。 pipeline.startTime 格式化 system.pipelineStartTime 为日期和时间对象,使其可用于处理表达式。
默认时区 pipeline.startTime 为 UTC。 可以 更改组织的时区 。
jobs:
- job:
variables:
a: $[counter(format('{0:yyyyMMdd}', pipeline.startTime), 100)]
steps:
- bash: echo $(a)
下面是一个计数器的示例,该计数器为 PR 和 CI 运行维护单独的值。
variables:
patch: $[counter(variables['build.reason'], 0)]
计数器的范围限定为管道。 换句话说,对于该管道的每个运行,其值会递增。 没有项目范围的计数器。
endsWith
True计算左参数字符串是否以右参数结尾- 最小参数:2。 最大参数:2
- 将参数强制转换为 String 进行求值
- 执行序号忽略大小写比较
- 示例:
endsWith('ABCDE', 'DE')(返回 True)
eq
- 评估
True参数是否相等 - 最小参数:2。 最大参数:2
- 将右参数转换为匹配左侧参数的类型。 如果转换失败,则
False返回。 - 字符串的序号忽略大小写比较
- 示例:
eq(variables.letters, 'ABC')
format
- 评估尾随参数并将其插入到前导参数字符串中
- 最小参数:1。 最大参数:N
- 示例:
format('Hello {0} {1}', 'John', 'Doe') - 对日期格式 (
yyyy、yy、fHHmmmssHsdKMMffffMffdd) 使用 .NET 自定义日期和时间格式说明符 - 示例:
format('{0:yyyyMMdd}', pipeline.startTime)。 在这种情况下pipeline.startTime,是一个特殊的日期时间对象变量。 - 通过翻倍大括号逃跑。 例如:
format('literal left brace {{ and literal right brace }}')
ge
- 计算
True左参数是否大于或等于右侧参数 - 最小参数:2。 最大参数:2
- 将右参数转换为匹配左侧参数的类型。 如果转换失败,则出错。
- 字符串的序号忽略大小写比较
- 示例:
ge(5, 5)(返回 True)
gt
- 计算
True左参数是否大于右侧参数 - 最小参数:2。 最大参数:2
- 将右参数转换为匹配左侧参数的类型。 如果转换失败,则出错。
- 字符串的序号忽略大小写比较
- 示例:
gt(5, 2)(返回 True)
in
- 计算
True左参数是否等于任何右参数 - 最小参数:1。 最大参数:N
- 将右参数转换为匹配左侧参数的类型。 相等比较计算
False转换是否失败。 - 字符串的序号忽略大小写比较
- 第一场比赛后的短路
- 示例:
in('B', 'A', 'B', 'C')(返回 True)
join
- 连接右参数数组中的所有元素,用左参数字符串分隔。
- 最小参数:2。 最大参数:2
- 数组中的每个元素都转换为字符串。 复杂对象转换为空字符串。
- 如果右参数不是数组,则结果为转换为字符串的正确参数。
在此示例中,在数组中的每个项之间添加分号。 参数类型是一个对象。
parameters:
- name: myArray
type: object
default:
- FOO
- BAR
- ZOO
variables:
A: ${{ join(';',parameters.myArray) }}
steps:
- script: echo $A # outputs FOO;BAR;ZOO
le
- 计算
True左参数是否小于或等于右侧参数 - 最小参数:2。 最大参数:2
- 将右参数转换为匹配左侧参数的类型。 如果转换失败,则出错。
- 字符串的序号忽略大小写比较
- 示例:
le(2, 2)(返回 True)
length
- 返回字符串或数组的长度,无论是来自系统还是来自参数的数组。
- 最小参数:1。 最大参数 1
- 示例:
length('fabrikam')返回 8
lower
- 将字符串或变量值转换为所有小写字符
- 最小参数:1。 最大参数 1
- 返回字符串的等效小写
- 示例:
lower('FOO')返回foo
lt
- 评估
True左参数是否小于右参数 - 最小参数:2。 最大参数:2
- 将右参数转换为匹配左参数的类型。 如果转换失败,则出错。
- 字符串的序号忽略大小写比较
- 示例:
lt(2, 5)(返回 True)
ne
True评估参数是否不相等- 最小参数:2。 最大参数:2
- 将右参数转换为匹配左参数的类型。 如果转换失败,则返回
True。 - 字符串的序号忽略大小写比较
- 示例:
ne(1, 2)(返回 True)
not
- 评估
True参数是否为False - 最小参数:1。 最大参数:1
- 将值转换为布尔值以供计算
- 示例:
not(eq(1, 2))(返回 True)
notIn
- 评估
True左参数是否不等于任何右参数 - 最小参数:1。 最大参数:N
- 将右参数转换为匹配左参数的类型。 相等比较计算
False是否转换失败。 - 字符串的序号忽略大小写比较
- 第一场比赛后短路
- 示例:
notIn('D', 'A', 'B', 'C')(返回 True)
或
- 评估
True任何参数是否为True - 最小参数:2。 最大参数:N
- 将参数强制转换为布尔值以供计算
- 第一次后短路
True - 示例:
or(eq(1, 1), eq(2, 3))(返回 True、短路)
replace
- 返回一个新字符串,在该字符串中,当前实例中的所有字符串都替换为另一个字符串
- 最小参数:3。 最大参数:3
replace(a, b, c):返回 a,其中 b 的所有实例都替换为 c- 示例:
replace('https://www.tinfoilsecurity.com/saml/consume','https://www.tinfoilsecurity.com','http://server')(返回http://server/saml/consume)
startsWith
- 评估
True左参数字符串是否以右参数开头 - 最小参数:2。 最大参数:2
- 将参数强制转换为字符串以供评估
- 执行序号忽略大小写比较
- 示例:
startsWith('ABCDE', 'AB')(返回 True)
upper
- 将字符串或变量值转换为所有大写字符
- 最小参数:1。 最大参数 1
- 返回与字符串等效的大写
- 示例:
upper('bah')返回BAH
xor
- 评估
True是否正好是一个参数True - 最小参数:2。 最大参数:2
- 将参数强制转换为布尔值以供计算
- 示例:
xor(True, False)(返回 True)
作业状态检查函数
可以将以下状态检查函数用作条件中的表达式,但不能在变量定义中使用。
通用
- 始终评估为
True(,即使取消) 也是如此。 注意:严重故障仍可能会阻止任务运行。 例如,如果获取源失败。
取消
- 计算结果为
True管道是否已取消。
“失败”
- 对于等效于
eq(variables['Agent.JobStatus'], 'Failed'). - 对于作业:
- 如果没有参数,则仅当依赖项关系图中的任何上一个作业失败时,才计算
True结果。 - 将作业名称用作参数时,仅当其中任一作业失败时才计算
True结果。
- 如果没有参数,则仅当依赖项关系图中的任何上一个作业失败时,才计算
succeeded
- 对于步骤,等效于
in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues') - 在处理作业时使用
dependsOn时,你希望评估以前的作业是否成功。 作业设计为在阶段按顺序运行时并行运行。 - 对于作业:
- 没有参数时,计算结果
True为仅当依赖项关系图中的所有以前的作业成功或部分成功时。 - 使用作业名称作为参数,计算结果为
True所有这些作业是否成功或部分成功。 - 计算结果为
False是否取消管道。
- 没有参数时,计算结果
succeededOrFailed
对于步骤,等效于
in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues', 'Failed')对于作业:
- 没有参数,无论依赖项关系图中的任何作业都成功还是失败,都计算
True结果。 - 使用作业名称作为参数,计算结果为
True其中任一作业是成功还是失败。
这类似于
always(),只是在取消管道时会评估False它。- 没有参数,无论依赖项关系图中的任何作业都成功还是失败,都计算
条件插入
可以使用if和elseifelse子句有条件地为任务分配变量值或设置输入。 还可以在满足条件时有条件地运行步骤。
条件仅在使用模板语法时起作用。 详细了解 变量语法。
对于模板,可以在添加序列或映射时使用条件插入。 详细了解 模板中的条件插入。
有条件地分配变量
variables:
${{ if eq(variables['Build.SourceBranchName'], 'main') }}: # only works if you have a main branch
stageName: prod
pool:
vmImage: 'ubuntu-latest'
steps:
- script: echo ${{variables.stageName}}
有条件地设置任务输入
pool:
vmImage: 'ubuntu-latest'
steps:
- task: PublishPipelineArtifact@1
inputs:
targetPath: '$(Pipeline.Workspace)'
${{ if eq(variables['Build.SourceBranchName'], 'main') }}:
artifact: 'prod'
${{ else }}:
artifact: 'dev'
publishLocation: 'pipeline'
有条件地运行步骤
如果没有变量集,或者值 foo 与条件不匹配 if ,则 else 语句将运行。 下面是条件中elseif返回 true 的值foo。
variables:
- name: foo
value: contoso # triggers elseif condition
pool:
vmImage: 'ubuntu-latest'
steps:
- script: echo "start"
- ${{ if eq(variables.foo, 'adaptum') }}:
- script: echo "this is adaptum"
- ${{ elseif eq(variables.foo, 'contoso') }}: # true
- script: echo "this is contoso"
- ${{ else }}:
- script: echo "the value is not adaptum or contoso"
Each 关键字
可以使用 each 关键字循环访问具有对象类型的参数。
parameters:
- name: listOfStrings
type: object
default:
- one
- two
steps:
- ${{ each value in parameters.listOfStrings }}:
- script: echo ${{ value }}
依赖项
表达式可以使用依赖项上下文来引用以前的作业或阶段。 可以使用依赖项来:
- 引用上一个作业的作业状态
- 引用上一阶段的阶段状态
- 在同一阶段引用上一个作业中的输出变量
- 在阶段中引用上一阶段的输出变量
- 在上一阶段的作业中引用输出变量
上下文针对作业和阶段进行调用 dependencies ,其工作原理与变量非常类似。
在作业中,如果引用另一个阶段中某个作业的输出变量,则会调用 stageDependencies上下文。
如果在输出变量中遇到引号字符 (' 或 ") 的问题,请参阅 此故障排除指南。
阶段到暂存依赖项
从结构上看,对象dependencies是作业和阶段名称resultsoutputs的映射。
表示为 JSON,如下所示:
"dependencies": {
"<STAGE_NAME>" : {
"result": "Succeeded|SucceededWithIssues|Skipped|Failed|Canceled",
"outputs": {
"jobName.stepName.variableName": "value"
}
},
"...": {
// another stage
}
}
使用此形式的映射 dependencies 在变量中或检查阶段级别的条件。
在此示例中,阶段 B 运行阶段 A 是成功还是跳过。
注意
以下示例使用标准管道语法。 如果使用部署管道,变量和条件变量语法将有所不同。 有关要使用的特定语法的信息,请参阅 部署作业。
stages:
- stage: A
condition: false
jobs:
- job: A1
steps:
- script: echo Job A1
- stage: B
condition: in(dependencies.A.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
jobs:
- job: B1
steps:
- script: echo Job B1
阶段还可以使用另一个阶段的输出变量。 在此示例中,阶段 B 依赖于阶段 A 中的变量。
stages:
- stage: A
jobs:
- job: A1
steps:
- bash: echo "##vso[task.setvariable variable=shouldrun;isOutput=true]true"
# or on Windows:
# - script: echo ##vso[task.setvariable variable=shouldrun;isOutput=true]true
name: printvar
- stage: B
condition: and(succeeded(), eq(dependencies.A.outputs['A1.printvar.shouldrun'], 'true'))
dependsOn: A
jobs:
- job: B1
steps:
- script: echo hello from Stage B
注意
默认情况下,管道中的每个阶段都依赖于 YAML 文件中的阶段。
如果需要引用当前阶段之前的阶段,可以通过将分区添加到 dependsOn 阶段来替代此自动默认阶段。
一个阶段内的作业到作业依赖项
在单个阶段内的作业级别, dependencies 数据不包含阶段级信息。
"dependencies": {
"<JOB_NAME>": {
"result": "Succeeded|SucceededWithIssues|Skipped|Failed|Canceled",
"outputs": {
"stepName.variableName": "value1"
}
},
"...": {
// another job
}
}
在此示例中,将始终跳过作业 A,作业 B 将运行。 作业 C 将运行,因为它的所有依赖项都成功或被跳过。
jobs:
- job: a
condition: false
steps:
- script: echo Job A
- job: b
steps:
- script: echo Job B
- job: c
dependsOn:
- a
- b
condition: |
and
(
in(dependencies.a.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'),
in(dependencies.b.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
)
steps:
- script: echo Job C
在此示例中,作业 B 依赖于作业 A 的输出变量。
jobs:
- job: A
steps:
- bash: echo "##vso[task.setvariable variable=shouldrun;isOutput=true]true"
# or on Windows:
# - script: echo ##vso[task.setvariable variable=shouldrun;isOutput=true]true
name: printvar
- job: B
condition: and(succeeded(), eq(dependencies.A.outputs['printvar.shouldrun'], 'true'))
dependsOn: A
steps:
- script: echo hello from B
跨阶段的作业到作业依赖项
在作业级别,还可以引用上一阶段作业的输出。
这需要使用 stageDependencies 上下文。
"stageDependencies": {
"<STAGE_NAME>" : {
"<JOB_NAME>": {
"result": "Succeeded|SucceededWithIssues|Skipped|Failed|Canceled",
"outputs": {
"stepName.variableName": "value"
}
},
"...": {
// another job
}
},
"...": {
// another stage
}
}
在此示例中,如果跳过作业 A1,则作业 B1 将运行。 作业 B2 将检查作业 A1 中的输出变量的值,以确定它是否应运行。
trigger: none
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: A
jobs:
- job: A1
steps:
- bash: echo "##vso[task.setvariable variable=shouldrun;isOutput=true]true"
# or on Windows:
# - script: echo ##vso[task.setvariable variable=shouldrun;isOutput=true]true
name: printvar
- stage: B
dependsOn: A
jobs:
- job: B1
condition: in(stageDependencies.A.A1.result, 'Skipped') # change condition to `Succeeded and stage will be skipped`
steps:
- script: echo hello from Job B1
- job: B2
condition: eq(stageDependencies.A.A1.outputs['printvar.shouldrun'], 'true')
steps:
- script: echo hello from Job B2
如果作业依赖于部署作业在不同阶段定义的变量,则语法不同。 In the following example, the job run_tests runs if the build_job deployment job set runTests to true. 请注意,用于字典的 outputs 键为 build_job.setRunTests.runTests.
stages:
- stage: build
jobs:
- deployment: build_job
environment:
name: Production
strategy:
runOnce:
deploy:
steps:
- task: PowerShell@2
name: setRunTests
inputs:
targetType: inline
pwsh: true
script: |
$runTests = "true"
echo "setting runTests: $runTests"
echo "##vso[task.setvariable variable=runTests;isOutput=true]$runTests"
- stage: test
dependsOn:
- 'build'
jobs:
- job: run_tests
condition: eq(stageDependencies.build.build_job.outputs['build_job.setRunTests.runTests'], 'true')
steps:
...
根据作业输出暂存
如果在生成后不需要任何更改,可能需要在特定条件下跳过管道中的阶段。 例如,使用 Terraform 计划时,并且仅当计划包含更改时才触发审批并应用。
在阶段中使用此条件时,必须使用 dependencies 变量,而不是 stageDependencies。
以下示例是一个简单的脚本,用于设置变量 (在阶段中的步骤中使用 Terraform Plan) 的实际信息,然后仅在变量具有特定值时才调用第二个阶段。
stages:
- stage: plan_dev
jobs:
- job: terraform_plan_dev
steps:
- bash: echo '##vso[task.setvariable variable=terraform_plan_exitcode;isOutput=true]2'
name: terraform_plan
- stage: apply_dev
dependsOn: plan_dev
condition: eq(dependencies.plan_dev.outputs['terraform_plan_dev.terraform_plan.terraform_plan_exitcode'], '2')
jobs:
- job: part_b
steps:
- bash: echo "BA"
如果某个阶段依赖于部署作业在不同阶段定义的变量,则语法不同。 在以下示例中,阶段test取决于要设置true的部署build_job设置shouldTest。 请注意,在阶段中conditiontest,build_job出现两次。
stages:
- stage: build
jobs:
- deployment: build_job
environment:
name: Production
strategy:
runOnce:
deploy:
steps:
- task: PowerShell@2
name: setRunTests
inputs:
targetType: inline
pwsh: true
script: |
$runTests = "true"
echo "setting runTests: $runTests"
echo "##vso[task.setvariable variable=runTests;isOutput=true]$runTests"
- stage: test
dependsOn:
- 'build'
condition: eq(dependencies.build.outputs['build_job.build_job.setRunTests.runTests'], 'true')
jobs:
...
筛选的数组
对项集合进行操作时,可以使用 * 语法来应用筛选的数组。 筛选后的数组返回所有对象/元素,而不考虑其名称。
As an example, consider an array of objects named foo. 我们希望获取数组中每个对象中属性值的 id 数组。
[
{ "id": 1, "a": "avalue1"},
{ "id": 2, "a": "avalue2"},
{ "id": 3, "a": "avalue3"}
]
我们可以执行以下操作:
foo.*.id
这会告知系统以筛选数组的形式运行 foo ,然后选择该 id 属性。
这将返回:
[ 1, 2, 3 ]
类型转换
表达式中的值可以在计算表达式时从一种类型转换为另一种类型。 计算表达式时,参数会合并到相关数据类型,然后重新转换为字符串。
例如,在此 YAML 中,值True和False转换到10表达式时以及计算表达式时。
当左参数小于右参数时,该函数 lt() 将 True 返回。
variables:
firstEval: $[lt(False, True)] # 0 vs. 1, True
secondEval: $[lt(True, False)] # 1 vs. 0, False
steps:
- script: echo $(firstEval)
- script: echo $(secondEval)
在此示例中,值 variables.emptyString 和空字符串都计算为空字符串。
该函数 coalesce() 按顺序计算参数,并返回不等于 null 或空字符串的第一个值。
variables:
coalesceLiteral: $[coalesce(variables.emptyString, '', 'literal value')]
steps:
- script: echo $(coalesceLiteral) # outputs literal value
下面进一步列出了详细的转换规则。
| 从/到 | Boolean | Null | Number | 字符串 | 版本 |
|---|---|---|---|---|---|
| 布尔值 | - | - | 是 | 是 | - |
| Null | 是 | - | 是 | 是 | - |
| 数字 | 是 | - | - | 是 | 部分 |
| 字符串 | 是 | 部分 | 部分 | - | 部分 |
| 版本 | 是 | - | - | 是 | - |
Boolean
要编号:
False→0True→1
字符串:
False→'False'True→'True'
Null
- 到布尔值:
False - 要编号:
0 - 字符串:
''(空字符串)
数量
- 到布尔值:
0→False,任何其他数字→True - 若要版本:必须大于零,并且必须包含非零小数。 必须小于 Int32.MaxValue (十进制组件也) 。
- 到字符串:将数字转换为没有千位分隔符和无小数分隔符的字符串。
字符串
- 若要布尔值:
''(空字符串) →False,任何其他字符串→True - 为 null:
''(空字符串) →Null,任何其他字符串不可转换 - 要编号:
''(空字符串) → 0,否则,使用 InvariantCulture 运行 C#Int32.TryParse,并使用以下规则:AllowDecimalPoint |AllowLeadingSign |AllowLeadingWhite |AllowThousands |AllowTrailingWhite。 如果TryParse失败,则无法转换。 - 版本:运行 C# 的
Version.TryParse. 必须至少包含主要组件和次要组件。 如果TryParse失败,则无法转换。
版本
- 到布尔值:
True - 要字符串:Major.Minor 或 Major.Minor.Build 或 Major.Minor.Build.Revision。
常见问题解答
我想执行表达式不支持的内容。 对于扩展Pipelines功能有哪些选项?
可以使用包含表达式的脚本自定义 Pipeline。 例如,此代码片段采用 BUILD_BUILDNUMBER 变量并将其与 Bash 拆分。 此脚本输出两个新变量, $MAJOR_RUN 对于 $MINOR_RUN主要和次要运行编号。
然后,这两个变量用于创建两个管道变量, $major 并使用 $minortask.setvariable。 这些变量可用于下游步骤。 若要跨管道共享变量,请参阅 变量组。
steps:
- bash: |
MAJOR_RUN=$(echo $BUILD_BUILDNUMBER | cut -d '.' -f1)
echo "This is the major run number: $MAJOR_RUN"
echo "##vso[task.setvariable variable=major]$MAJOR_RUN"
MINOR_RUN=$(echo $BUILD_BUILDNUMBER | cut -d '.' -f2)
echo "This is the minor run number: $MINOR_RUN"
echo "##vso[task.setvariable variable=minor]$MINOR_RUN"
- bash: echo "My pipeline variable for major run is $(major)"
- bash: echo "My pipeline variable for minor run is $(minor)"