定义变量
Azure DevOps Services |Azure DevOps Server 2022 - Azure DevOps Server 2019 |TFS 2018
注意
在 Microsoft Team Foundation Server (TFS) 2018 和更低版本中,生成和发布管道被称为“定义”,运行被称为“生成”,服务连接被称为“服务终结点”,阶段被称为“环境”,而作业被称为“阶段” 。
变量为你提供了一种简便方法,可以将关键数据位导入管道的各个部分。 变量的最常见用途是定义可在管道中使用的值。 所有变量都存储为字符串,并且是可变的。 变量的值可以从管道的运行更改为运行或作业。
在多个具有相同名称的位置定义同一变量时,本地范围最大的变量将获胜。 因此,在作业级别定义的变量可以替代在阶段级别设置的变量。 在阶段级别定义的变量将替代在管道根级别设置的变量。 管道根级别中设置的变量将替代管道设置 UI 中设置的变量。
可以将变量与 表达式 一起使用,以便有条件地分配值并进一步自定义管道。
变量不同于 运行时参数,运行时参数在模板分析期间类型化且可用。
用户定义的变量
定义变量时,可以使用 不同的语法 (宏、模板表达式或运行时) 使用哪种语法将决定变量在管道中呈现的位置。
在 YAML 管道中,可以在根级别、阶段级别和作业级别设置变量。 还可以在 UI 中指定 YAML 管道外部的变量。 在 UI 中设置变量时,可以加密该变量并将其设置为机密。
用户定义的变量可以 设置为只读。 示例 (变量存在命名限制 :不能在变量名称) 开头使用 secret
。
可以使用变量组使变量在多个管道中可用。
可以使用 模板 在一个文件中定义多个管道中使用的变量。
系统变量
除了用户定义的变量外,Azure Pipelines 还具有具有预定义值的系统变量。 如果使用 YAML 或经典生成管道,请参阅 预定义变量 以获取系统变量的完整列表。 如果使用经典发布管道,请参阅 发布变量。
运行管道时,系统变量是使用其当前值设置的。 某些变量是自动设置的。 作为管道作者或最终用户,可以在运行管道之前更改系统变量的值。
系统变量是只读的。
环境变量
环境变量特定于你使用的操作系统。 它们以特定于平台的方式注入到管道中。 格式对应于为特定脚本平台设置环境变量的格式的方式。
在 macOS 和 Linux) (UNIX 系统上,环境变量的格式 $NAME
为 。 在 Windows 上,格式 %NAME%
适用于批处理 和 $env:NAME
PowerShell 中的 。
系统变量和用户定义的变量也会作为平台的环境变量注入。 将变量转换为环境变量时,变量名称变为大写,句点变为下划线。 例如,变量名称 any.variable
将成为变量名称 $ANY_VARIABLE
。
(示例,环境变量存在变量 命名限制 :不能在变量名称) 开头使用 secret
。
变量命名限制
用户定义的和环境变量可以包含字母、数字、 .
和 _
字符。 请勿使用系统保留的变量前缀。 这些是: endpoint
、 input
、 secret
、 path
和 securefile
。 无论大小写) ,以这些字符串之一开头的任何变量 (都不适用于任务和脚本。
了解变量语法
Azure Pipelines 支持三种不同的方式来引用变量:宏、模板表达式和运行时表达式 。 每个语法都可用于不同的用途,并存在一些限制。
在管道中,模板表达式变量 (${{ variables.var }}
) 在运行时开始之前在编译时得到处理。 宏语法变量 ($(var)
) 任务运行前在运行时进行处理。 运行时表达式 ($[variables.var]
) 也会在运行时得到处理,但设计用于 条件 和 表达式。 使用运行时表达式时,该表达式必须占据定义的整个右侧。
在此示例中,可以看到模板表达式在更新变量后仍具有变量的初始值。 宏语法变量的值将更新。 模板表达式值不会更改,因为在任务运行之前,所有模板表达式变量都会在编译时得到处理。 相比之下,宏语法变量在运行每个任务之前进行计算。
variables:
- name: one
value: initialValue
steps:
- script: |
echo ${{ variables.one }} # outputs initialValue
echo $(one)
displayName: First variable pass
- bash: echo "##vso[task.setvariable variable=one]secondValue"
displayName: Set new variable value
- script: |
echo ${{ variables.one }} # outputs initialValue
echo $(one) # outputs secondValue
displayName: Second variable pass
宏语法变量
大多数文档示例使用宏语法 ($(var)
) 。 宏语法旨在将变量值内插到任务输入和其他变量中。
使用宏语法的变量在运行时执行任务之前得到处理。 运行时在 模板扩展后发生。 当系统遇到宏表达式时,它将表达式替换为变量的内容。 如果没有该名称的变量,则宏表达式保持不变。 例如,如果 $(var)
无法替换, $(var)
则 不会替换为任何内容。
宏语法变量保持不变,没有值,因为空值(如 ) $()
可能对正在运行的任务意味着一些内容,代理不应假定你希望替换该值。 例如,如果使用 $(foo)
引用 Bash 任务中的变量 foo
,则替换任务输入中的所有 $()
表达式可能会中断 Bash 脚本。
仅当宏变量用于值时,它们才会展开,而不是作为关键字。 值显示在管道定义的右侧。 以下内容有效: key: $(value)
。 以下内容无效: $(key): value
。 当用于以内联方式显示作业名称时,宏变量不会展开。 相反,必须使用 displayName
属性。
注意
宏语法变量仅针对 stages
、 jobs
和 steps
展开。
例如,不能在 或 trigger
中使用resource
宏语法。
在此示例中,宏语法用于 Bash、PowerShell 和脚本任务。 使用宏语法调用变量的语法对于这三者都是相同的。
variables:
- name: projectName
value: contoso
steps:
- bash: echo $(projectName)
- powershell: echo $(projectName)
- script: echo $(projectName)
模板表达式语法
可以使用模板表达式语法来扩展 模板参数 和变量 (${{ variables.var }}
) 。 模板变量在编译时进行处理,并在运行时启动之前被替换。 模板表达式旨在将 YAML 的某些部分重用为模板。
找不到替换值时,模板变量以无提示方式合并为空字符串。 与宏和运行时表达式不同,模板表达式可以显示为左侧) (键或 (右侧) 的值。 以下内容有效: ${{ variables.key }} : ${{ variables.value }}
。
运行时表达式语法
可以对在运行时扩展的变量使用运行时表达式语法, ($[variables.var]
) 。 找不到替换值时,运行时表达式变量以无提示方式合并为空字符串。 运行时表达式设计为在作业条件中使用,以支持作业的条件执行或整个阶段。
仅当运行时表达式变量用于值时,才会扩展它们,而不是作为关键字。 值显示在管道定义的右侧。 以下内容有效: key: $[variables.value]
。 以下内容无效: $[variables.key]: value
。 运行时表达式必须占据键值对的整个右侧。 例如, key: $[variables.value]
有效,但 key: $[variables.value] foo
无效。
语法 | 示例 | 何时处理? | 它在管道定义中的哪个位置进行扩展? | 找不到时如何呈现? |
---|---|---|---|---|
宏 | $(var) |
任务执行前的运行时 | 值 (右侧) | 指纹 $(var) |
模板表达式 | ${{ variables.var }} |
编译时间 (compile time) | 键或值 (左侧或右侧) | 空字符串 |
运行时表达式 | $[variables.var] |
Runtime — 运行时 | 值 (右侧) | 空字符串 |
应使用哪种语法?
如果要为任务提供输入,请使用宏语法。
如果使用的是 条件 和表达式,请选择运行时 表达式。 这种情况的例外情况是,如果管道会导致空变量打印出问题。例如,如果条件逻辑依赖于具有特定值或没有值的变量。 在这种情况下,应使用宏表达式。
如果要在模板中定义变量,请使用模板表达式。
在管道中设置变量
在最常见的情况下,设置变量并在 YAML 文件中使用它们。 这样,就可以跟踪版本控制系统中变量的更改。 还可以在管道设置 UI 中定义变量 (查看经典选项卡) 并在 YAML 中引用它们。
以下示例演示如何设置和 两个变量, configuration
platform
并在后续步骤中使用它们。 若要在 YAML 语句中使用变量,请将变量包装在 中 $()
。 变量不能用于在 YAML 语句中定义 repository
。
# Set variables once
variables:
configuration: debug
platform: x64
steps:
# Use them once
- task: MSBuild@1
inputs:
solution: solution1.sln
configuration: $(configuration) # Use the variable
platform: $(platform)
# Use them again
- task: MSBuild@1
inputs:
solution: solution2.sln
configuration: $(configuration) # Use the variable
platform: $(platform)
变量范围
在 YAML 文件中,可以在各种范围内设置变量:
- 在根级别,使其可用于管道中的所有作业。
- 在阶段级别,使其仅可用于特定阶段。
- 在作业级别,使其仅可用于特定作业。
在 YAML 顶部定义变量时,该变量将可用于管道中的所有作业和阶段,并且是全局变量。 YAML 中定义的全局变量在管道设置 UI 中不可见。
作业级别的变量将替代根级别和阶段级别的变量。 阶段级别的变量将替代根级别的变量。
variables:
global_variable: value # this is available to all jobs
jobs:
- job: job1
pool:
vmImage: 'ubuntu-latest'
variables:
job_variable1: value1 # this is only available in job1
steps:
- bash: echo $(global_variable)
- bash: echo $(job_variable1)
- bash: echo $JOB_VARIABLE1 # variables are available in the script environment too
- job: job2
pool:
vmImage: 'ubuntu-latest'
variables:
job_variable2: value2 # this is only available in job2
steps:
- bash: echo $(global_variable)
- bash: echo $(job_variable2)
- bash: echo $GLOBAL_VARIABLE
这两个作业的输出如下所示:
# job1
value
value1
value1
# job2
value
value2
value
指定变量
在前面的示例中, variables
关键字后跟键值对列表。
键是变量名称,值是变量值。
还有另一种语法,在想要使用 变量模板 或 变量组时很有用。 应在管道的根级别使用此语法。
在此备用语法中 variables
, 关键字采用变量说明符的列表。
变量说明符 name
用于常规变量、 group
变量组和 template
包含变量模板。
以下示例演示了这三者。
variables:
# a regular variable
- name: myvariable
value: myvalue
# a variable group
- group: myvariablegroup
# a reference to a variable template
- template: myvariabletemplate.yml
详细了解 使用模板重用变量。
通过环境访问变量
请注意,变量也通过环境变量提供给脚本。 使用这些环境变量的语法取决于脚本语言。
名称为大写,将 .
替换为 _
。 这会自动插入到进程环境中。 下面是一些示例:
- Batch 脚本:
%VARIABLE_NAME%
- PowerShell 脚本:
$env:VARIABLE_NAME
- Bash 脚本:
$VARIABLE_NAME
重要
包含文件路径的预定义变量会根据代理主机类型和 shell 类型转换为适当的样式 (Windows 样式 C:\foo\ 与 Unix 样式 /foo/) 。 如果在 Windows 上运行 bash 脚本任务,则应使用环境变量方法来访问这些变量,而不是使用管道变量方法,以确保具有正确的文件路径样式。
TFS 不支持 YAML。
设置机密变量
不要在 YAML 文件中设置机密变量。 操作系统通常会记录它们所运行进程的命令,你不希望日志包含作为输入传入的机密。 使用脚本的环境或映射 块中的 variables
变量,将机密传递到管道。
需要在管道的管道设置 UI 中设置机密变量。 这些变量的范围限定为在其中设置它们的管道。 还可以 在变量组中设置机密变量。
若要在 Web 界面中设置机密,请执行以下步骤:
- 转到“管道”页,选择适当的管道,然后选择“编辑”。
- 找到该管道的变量。
- 添加或更新该变量。
- 选择
图标,以加密方式存储变量。
- 保存管道。
机密变量使用 2048 位 RSA 密钥进行静态加密。 代理上提供机密供任务和脚本使用。 请注意谁有权更改管道。
重要
我们努力屏蔽机密,使其不显示在 Azure Pipelines 输出中,但仍需要采取预防措施。 切勿将机密作为输出进行回显。 某些操作系统记录命令行参数。 切勿在命令行上传递机密。 相反,我们建议将机密映射到环境变量中。
我们从不屏蔽机密的子字符串。 例如,如果“abc123”设置为机密,则“abc”不会从日志中屏蔽。 这是为了避免在某个级别过于精细地屏蔽机密,使日志不可读。 因此,机密不应包含结构化数据。 例如,如果“{ ”foo“: ”bar“ }” 设置为机密,则不会从日志中屏蔽“bar”。
与普通变量不同,它们不会自动解密为脚本的环境变量。 需要显式映射机密变量。
以下示例演示如何在 PowerShell 和 Bash 脚本中使用名为 的 mySecret
机密变量。
与普通管道变量不同,没有名为 的 MYSECRET
环境变量。
variables:
GLOBAL_MYSECRET: $(mySecret) # this will not work because the secret variable needs to be mapped as env
GLOBAL_MY_MAPPED_ENV_VAR: $(nonSecretVariable) # this works because it's not a secret.
steps:
- powershell: |
Write-Host "Using an input-macro works: $(mySecret)"
Write-Host "Using the env var directly does not work: $env:MYSECRET"
Write-Host "Using a global secret var mapped in the pipeline does not work either: $env:GLOBAL_MYSECRET"
Write-Host "Using a global non-secret var mapped in the pipeline works: $env:GLOBAL_MY_MAPPED_ENV_VAR"
Write-Host "Using the mapped env var for this task works and is recommended: $env:MY_MAPPED_ENV_VAR"
env:
MY_MAPPED_ENV_VAR: $(mySecret) # the recommended way to map to an env variable
- bash: |
echo "Using an input-macro works: $(mySecret)"
echo "Using the env var directly does not work: $MYSECRET"
echo "Using a global secret var mapped in the pipeline does not work either: $GLOBAL_MYSECRET"
echo "Using a global non-secret var mapped in the pipeline works: $GLOBAL_MY_MAPPED_ENV_VAR"
echo "Using the mapped env var for this task works and is recommended: $MY_MAPPED_ENV_VAR"
env:
MY_MAPPED_ENV_VAR: $(mySecret) # the recommended way to map to an env variable
上述脚本中这两个任务的输出如下所示:
Using an input-macro works: ***
Using the env var directly does not work:
Using a global secret var mapped in the pipeline does not work either:
Using a global non-secret var mapped in the pipeline works: foo
Using the mapped env var for this task works and is recommended: ***
还可以在脚本外部使用机密变量。 例如,可以使用 定义将机密变量映射到任务 variables
。 此示例演示如何在 Azure 文件复制任务中使用机密变量 $(vmsUser)
和 $(vmsAdminPass)
。
variables:
VMS_USER: $(vmsUser)
VMS_PASS: $(vmsAdminPass)
pool:
vmImage: 'ubuntu-latest'
steps:
- task: AzureFileCopy@4
inputs:
SourcePath: 'my/path'
azureSubscription: 'my-subscription'
Destination: 'AzureVMs'
storage: 'my-storage'
resourceGroup: 'my-rg'
vmsAdminUserName: $(VMS_USER)
vmsAdminPassword: $(VMS_PASS)
引用变量组中的机密变量
此示例演示如何引用 YAML 文件中的变量组,以及如何在 YAML 中添加变量。 变量组中使用了两个变量: user
和 token
。 变量 token
是机密变量,并映射到环境变量 $env:MY_MAPPED_TOKEN
,以便可以在 YAML 中引用它。
此 YAML 进行 REST 调用以检索发布列表,并输出结果。
variables:
- group: 'my-var-group' # variable group
- name: 'devopsAccount' # new variable defined in YAML
value: 'contoso'
- name: 'projectName' # new variable defined in YAML
value: 'contosoads'
steps:
- task: PowerShell@2
inputs:
targetType: 'inline'
script: |
# Encode the Personal Access Token (PAT)
# $env:USER is a normal variable in the variable group
# $env:MY_MAPPED_TOKEN is a mapped secret variable
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $env:USER,$env:MY_MAPPED_TOKEN)))
# Get a list of releases
$uri = "https://vsrm.dev.azure.com/$(devopsAccount)/$(projectName)/_apis/release/releases?api-version=5.1"
# Invoke the REST call
$result = Invoke-RestMethod -Uri $uri -Method Get -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}
# Output releases in JSON
Write-Host $result.value
env:
MY_MAPPED_TOKEN: $(token) # Maps the secret variable $(token) from my-var-group
重要
默认情况下,使用 GitHub 存储库时,与管道关联的机密变量不可用于分支的拉取请求生成。 有关详细信息,请参阅 分叉的贡献。
TFS 不支持 YAML。
跨管道共享变量
若要在项目中的多个管道之间共享变量,请使用 Web 界面。 在 “库”下,使用 变量组。
使用任务的输出变量
某些任务定义输出变量,可在下游步骤、作业和阶段中使用。 在 YAML 中,可以使用 依赖项跨作业和阶段访问变量。
某些任务定义输出变量,可以在同一阶段的下游步骤和作业中使用。 在 YAML 中,可以使用 依赖项跨作业访问变量。
某些任务定义输出变量,可以在同一作业的下游步骤中使用。
- 若要从同一作业中的不同任务引用变量,请使用
TASK.VARIABLE
。 - 若要从其他作业的任务引用变量,请使用
dependencies.JOB.outputs['TASK.VARIABLE']
。
注意
默认情况下,管道中的每个阶段都依赖于 YAML 文件中它前面的阶段。 如果需要引用不是紧接当前阶段之前的阶段,可以通过向阶段添加节 dependsOn
来替代此自动默认值。
注意
以下示例使用标准管道语法。 如果使用部署管道,变量和条件变量语法将有所不同。 有关要使用的特定语法的信息,请参阅 部署作业。
对于这些示例,假设我们有一个名为 MyTask
的任务,该任务设置一个名为 的 MyVar
输出变量。
详细了解 表达式 - 依赖项中的语法。
在同一作业中使用输出
steps:
- task: MyTask@1 # this step generates the output variable
name: ProduceVar # because we're going to depend on it, we need to name the step
- script: echo $(ProduceVar.MyVar) # this step uses the output variable
在不同的作业中使用输出
jobs:
- job: A
steps:
# assume that MyTask generates an output variable called "MyVar"
# (you would learn that from the task's documentation)
- task: MyTask@1
name: ProduceVar # because we're going to depend on it, we need to name the step
- job: B
dependsOn: A
variables:
# map the output variable from A into this job
varFromA: $[ dependencies.A.outputs['ProduceVar.MyVar'] ]
steps:
- script: echo $(varFromA) # this step uses the mapped-in variable
在不同的阶段使用输出
若要在作业级别使用不同阶段的输出,请使用 stageDependencies
语法:
- 在阶段级别,引用不同阶段中的变量的格式为
stageDependencies.STAGE.JOB.outputs['TASK.VARIABLE']
- 在作业级别,引用不同阶段中的变量的格式为
stageDependencies.STAGE.JOB.outputs['TASK.VARIABLE']
stages:
- stage: One
jobs:
- job: A
steps:
- task: MyTask@1 # this step generates the output variable
name: ProduceVar # because we're going to depend on it, we need to name the step
- stage: Two
jobs:
- job: B
variables:
# map the output variable from A into this job
varFromA: $[ stageDependencies.One.A.outputs['ProduceVar.MyVar'] ]
steps:
- script: echo $(varFromA) # this step uses the mapped-in variable
还可以使用文件输入在阶段之间传递变量。 为此,需要在作业级别的第二阶段定义变量,然后将变量作为 env:
输入传递。
## script-a.sh
echo "##vso[task.setvariable variable=sauce;isOutput=true]crushed tomatoes"
## script-b.sh
echo 'Hello file version'
echo $skipMe
echo $StageSauce
## azure-pipelines.yml
stages:
- stage: one
jobs:
- job: A
steps:
- task: Bash@3
inputs:
filePath: 'script-a.sh'
name: setvar
- bash: |
echo "##vso[task.setvariable variable=skipsubsequent;isOutput=true]true"
name: skipstep
- stage: two
jobs:
- job: B
variables:
- name: StageSauce
value: $[ stageDependencies.one.A.outputs['setvar.sauce'] ]
- name: skipMe
value: $[ stageDependencies.one.A.outputs['skipstep.skipsubsequent'] ]
steps:
- task: Bash@3
inputs:
filePath: 'script-b.sh'
name: fileversion
env:
StageSauce: $(StageSauce) # predefined in variables section
skipMe: $(skipMe) # predefined in variables section
- task: Bash@3
inputs:
targetType: 'inline'
script: |
echo 'Hello inline version'
echo $(skipMe)
echo $(StageSauce)
上述管道中阶段的输出如下所示:
Hello inline version
true
crushed tomatoes
列出变量
可以使用 az pipelines variable list 命令列出管道中的所有变量。 若要开始,请参阅 Azure DevOps CLI 入门。
az pipelines variable list [--org]
[--pipeline-id]
[--pipeline-name]
[--project]
参数
- org:Azure DevOps 组织 URL。 可以使用 配置默认组织
az devops configure -d organization=ORG_URL
。 如果未配置为默认或使用 选取git config
,则为必需。 示例:--org https://dev.azure.com/MyOrganizationName/
。 - pipeline-id:如果未提供 pipeline-name ,则是必需的。 管道的 ID。
- pipeline-name:如果未提供 pipeline-id ,则是必需的;如果提供 pipeline-id ,则忽略该名称。 管道的名称。
- 项目:项目的名称或 ID。 可以使用 配置默认项目
az devops configure -d project=NAME_OR_ID
。 如果未配置为默认值或使用 进行选取,git config
则为必需。
示例
以下命令列出管道中 ID 为 12 的所有变量,并显示表格式的结果。
az pipelines variable list --pipeline-id 12 --output table
Name Allow Override Is Secret Value
------------- ---------------- ----------- ------------
MyVariable False False platform
NextVariable False True platform
Configuration False False config.debug
在脚本中设置变量
管道中的脚本可以定义变量,以便该变量可由管道中的后续步骤之一使用。 此方法设置的所有变量都被视为字符串。 若要从脚本设置变量,请使用命令语法并打印到 stdout。
从脚本设置作业范围的变量
若要从脚本设置变量,请使用 task.setvariable
日志记录命令。 这将更新后续作业的环境变量。 后续作业将有权访问具有 宏语法 的新变量,并在任务中作为环境变量。
当 设置为 true 时 issecret
,变量的值将另存为机密并从日志中屏蔽。 有关机密变量的详细信息,请参阅 日志记录命令。
steps:
# Create a variable
- bash: |
echo "##vso[task.setvariable variable=sauce]crushed tomatoes" # remember to use double quotes
# Use the variable
# "$(sauce)" is replaced by the contents of the `sauce` variable by Azure Pipelines
# before handing the body of the script to the shell.
- bash: |
echo my pipeline variable is $(sauce)
后续步骤还会将管道变量添加到其环境中。 不能在定义变量的步骤中使用变量。
steps:
# Create a variable
# Note that this does not update the environment of the current script.
- bash: |
echo "##vso[task.setvariable variable=sauce]crushed tomatoes"
# An environment variable called `SAUCE` has been added to all downstream steps
- bash: |
echo "my environment variable is $SAUCE"
- pwsh: |
Write-Host "my environment variable is $env:SAUCE"
上述管道的输出。
my environment variable is crushed tomatoes
my environment variable is crushed tomatoes
设置多作业输出变量
如果要使某个变量可供将来的作业使用,则必须使用 isOutput=true
将其标记为输出变量。 然后,可以使用 语法并包括设置变量的步骤名称,将其映射到将来的作业 $[]
中。 多作业输出变量仅适用于同一阶段中的作业。
若要将变量传递到不同阶段的作业,请使用 阶段依赖项 语法。
注意
默认情况下,管道中的每个阶段都依赖于 YAML 文件中它前面的阶段。 因此,每个阶段都可以使用上一阶段的输出变量。 若要访问其他阶段,需要更改依赖项关系图,例如,如果阶段 3 需要阶段 1 中的变量,则需要在阶段 1 上声明显式依赖项。
创建多作业输出变量时,应将表达式分配给变量。 在此 YAML 中, $[ dependencies.A.outputs['setvarStep.myOutputVar'] ]
分配给变量 $(myVarFromJobA)
。
jobs:
# Set an output variable from job A
- job: A
pool:
vmImage: 'windows-latest'
steps:
- powershell: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the value"
name: setvarStep
- script: echo $(setvarStep.myOutputVar)
name: echovar
# Map the variable into job B
- job: B
dependsOn: A
pool:
vmImage: 'ubuntu-18.04'
variables:
myVarFromJobA: $[ dependencies.A.outputs['setvarStep.myOutputVar'] ] # map in the variable
# remember, expressions require single quotes
steps:
- script: echo $(myVarFromJobA)
name: echovar
上述管道的输出。
this is the value
this is the value
如果要将变量从一个阶段设置为另一个阶段,请使用 stageDependencies
。
stages:
- stage: A
jobs:
- job: A1
steps:
- bash: echo "##vso[task.setvariable variable=myStageOutputVar;isOutput=true]this is a stage output var"
name: printvar
- stage: B
dependsOn: A
variables:
myVarfromStageA: $[ stageDependencies.A.A1.outputs['printvar.myStageOutputVar'] ]
jobs:
- job: B1
steps:
- script: echo $(myVarfromStageA)
如果要从 矩阵 或 切片设置变量,则在从下游作业访问变量时引用该变量,必须包括:
- 作业的名称。
- 步骤。
jobs:
# Set an output variable from a job with a matrix
- job: A
pool:
vmImage: 'ubuntu-18.04'
strategy:
maxParallel: 2
matrix:
debugJob:
configuration: debug
platform: x64
releaseJob:
configuration: release
platform: x64
steps:
- bash: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the $(configuration) value"
name: setvarStep
- bash: echo $(setvarStep.myOutputVar)
name: echovar
# Map the variable from the debug job
- job: B
dependsOn: A
pool:
vmImage: 'ubuntu-18.04'
variables:
myVarFromJobADebug: $[ dependencies.A.outputs['debugJob.setvarStep.myOutputVar'] ]
steps:
- script: echo $(myVarFromJobADebug)
name: echovar
jobs:
# Set an output variable from a job with slicing
- job: A
pool:
vmImage: 'ubuntu-18.04'
parallel: 2 # Two slices
steps:
- bash: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the slice $(system.jobPositionInPhase) value"
name: setvarStep
- script: echo $(setvarStep.myOutputVar)
name: echovar
# Map the variable from the job for the first slice
- job: B
dependsOn: A
pool:
vmImage: 'ubuntu-18.04'
variables:
myVarFromJobsA1: $[ dependencies.A.outputs['job1.setvarStep.myOutputVar'] ]
steps:
- script: "echo $(myVarFromJobsA1)"
name: echovar
请务必将作业名称作为 部署 作业的输出变量的前缀。 在本例中,作业名称为 A
:
jobs:
# Set an output variable from a deployment
- deployment: A
pool:
vmImage: 'ubuntu-18.04'
environment: staging
strategy:
runOnce:
deploy:
steps:
- bash: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the deployment variable value"
name: setvarStep
- bash: echo $(setvarStep.myOutputVar)
name: echovar
# Map the variable from the job for the first slice
- job: B
dependsOn: A
pool:
vmImage: 'ubuntu-18.04'
variables:
myVarFromDeploymentJob: $[ dependencies.A.outputs['A.setvarStep.myOutputVar'] ]
steps:
- bash: "echo $(myVarFromDeploymentJob)"
name: echovar
TFS 不支持 YAML。
使用表达式设置变量
可以使用表达式设置变量。 我们已遇到这种情况的一种情况,即将变量设置为上一作业中另一个作业的输出。
- job: B
dependsOn: A
variables:
myVarFromJobsA1: $[ dependencies.A.outputs['job1.setvarStep.myOutputVar'] ] # remember to use single quotes
可以使用任何受支持的表达式来设置变量。 以下示例将变量设置为充当计数器,该计数器从 100 开始,每次运行递增 1,每天重置为 100。
jobs:
- job:
variables:
a: $[counter(format('{0:yyyyMMdd}', pipeline.startTime), 100)]
steps:
- bash: echo $(a)
有关计数器、依赖项和其他表达式的详细信息,请参阅 表达式。
TFS 不支持 YAML。
为步骤配置可设置的变量
可以在步骤中定义 settableVariables
,也可以指定不能设置任何变量。
在此示例中,脚本无法设置变量。
steps:
- script: echo This is a step
target:
settableVariables: none
在此示例中,脚本允许 变量 sauce
,但不允许变量 secretSauce
。 管道运行页上会显示警告。
steps:
- bash: |
echo "##vso[task.setvariable variable=Sauce;]crushed tomatoes"
echo "##vso[task.setvariable variable=secretSauce;]crushed tomatoes with garlic"
target:
settableVariables:
- sauce
name: SetVars
- bash:
echo "Sauce is $(sauce)"
echo "secretSauce is $(secretSauce)"
name: OutputVars
排队时允许
如果变量出现在 YAML 文件的 块中 variables
,则其值是固定的,无法在队列时重写。 最佳做法是在 YAML 文件中定义变量,但有时这样做没有意义。 例如,你可能想要定义一个机密变量,而不是在 YAML 中公开该变量。 或者,可能需要在管道运行期间手动设置变量值。
有两个选项可用于定义队列时间值。 可以在 UI 中定义变量,并选择“ 允许用户在运行此管道时重写此值 ”选项,也可以改用 运行时参数 。 如果变量不是机密,最佳做法是使用 运行时参数。
若要在队列时设置变量,请在管道中添加新变量并选择替代选项。
若要允许在队列时设置变量,请确保该变量不会同时出现在管道或作业的 块中 variables
。 如果在 YAML 的变量块和 UI 中定义变量,则 YAML 中的值将具有优先级。
TFS 不支持 YAML。
变量的扩展
在多个范围设置同名变量时,将应用以下优先级(最高优先级排在首位)。
- 在 YAML 文件中设置的作业级别变量
- 在 YAML 文件中设置的阶段级别变量
- 在 YAML 文件中设置的管道级别变量
- 在排队时设置的变量
- 在管道设置 UI 中设置的管道变量
在以下示例中,在 YAML 文件中的管道级别和作业级别设置相同的变量 a
。 它还在变量组 G
中设置,并在管道设置 UI 中将其设置为变量。
variables:
a: 'pipeline yaml'
stages:
- stage: one
displayName: one
variables:
- name: a
value: 'stage yaml'
jobs:
- job: A
variables:
- name: a
value: 'job yaml'
steps:
- bash: echo $(a) # This will be 'job yaml'
在同一范围内设置同名的变量时,最后设置的值优先。
stages:
- stage: one
displayName: Stage One
variables:
- name: a
value: alpha
- name: a
value: beta
jobs:
- job: I
displayName: Job I
variables:
- name: b
value: uno
- name: b
value: dos
steps:
- script: echo $(a) #outputs beta
- script: echo $(b) #outputs dos
注意
在 YAML 文件中设置变量时,请勿在 Web 编辑器中将其定义为队列时可设置的变量。 当前无法在队列时更改 YAML 文件中设置的变量。 如果需要在队列时可设置变量,请不要在 YAML 文件中设置它。
变量在运行启动时展开一次,并在每个步骤开始时再次展开。 例如:
jobs:
- job: A
variables:
a: 10
steps:
- bash: |
echo $(a) # This will be 10
echo '##vso[task.setvariable variable=a]20'
echo $(a) # This will also be 10, since the expansion of $(a) happens before the step
- bash: echo $(a) # This will be 20, since the variables are expanded just before the step
前面的示例中有两个步骤。 的 $(a)
扩展在作业开始时发生一次,在两个步骤的开头发生一次。
由于变量在作业开始时是扩展的,因此不能在策略中使用它们。 在以下示例中,不能使用 变量 a
扩展作业矩阵,因为变量仅在每个展开作业的开头可用。
jobs:
- job: A
variables:
a: 10
strategy:
matrix:
x:
some_variable: $(a) # This does not work
如果变量 a
是上一作业的输出变量,则可以在将来的作业中使用它。
- job: A
steps:
- powershell: echo "##vso[task.setvariable variable=a;isOutput=true]10"
name: a_step
# Map the variable into job B
- job: B
dependsOn: A
variables:
some_variable: $[ dependencies.A.outputs['a_step.a'] ]
递归扩展
在代理上,使用 $( )
语法引用的变量以递归方式展开。
例如:
variables:
myInner: someValue
myOuter: $(myInner)
steps:
- script: echo $(myOuter) # prints "someValue"
displayName: Variable is $(myOuter) # display name is "Variable is someValue"
TFS 不支持 YAML。