定义变量

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 或经典生成管道,请参阅 预定义的变量 ,了解系统变量的综合列表。 如果使用经典发布管道,请参阅 发布变量

运行管道时,系统变量使用其当前值进行设置。 自动设置某些变量。 作为管道作者或最终用户,可以在运行管道之前更改系统变量的值。

系统变量是只读的。

环境变量

环境变量特定于所使用的操作系统。 它们以特定于平台的方式注入管道。 格式对应于为特定脚本平台设置环境变量的格式。

在 UNIX 系统上, (macOS 和 Linux) ,环境变量具有格式 $NAME。 在 Windows 上,格式 %NAME% 适用于批处理和 $env:NAME PowerShell。

系统变量和用户定义的变量也会作为平台的环境变量注入。 当变量转换为环境变量时,变量名称变为大写,句点变为下划线。 例如,变量名称 any.variable 将成为变量名称 $ANY_VARIABLE

(示例中,环境变量存在 变量命名限制 :无法在变量名称) 开头使用 secret

变量命名限制

用户定义的和环境变量可以包含字母、数字 ._ 字符。 不要使用系统保留的变量前缀。 这些是: endpointinputsecretpathsecurefile。 以这些字符串之一开头的任何变量 (无论大写) 都不适用于任务和脚本。

了解变量语法

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 该属性。

注意

宏语法变量仅扩展为 stagesjobs并且 steps。 You cannot, for example, use macro syntax inside a resource or trigger.

在此示例中,宏语法与 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

了解有关 使用模板重复使用变量的详细信息。

通过环境访问变量

请注意,变量也通过环境变量提供给脚本。 使用这些环境变量的语法取决于脚本语言。

名称是大写的,替换为 ._。 这会自动插入到进程环境中。 下面是一些示例:

  • 批处理脚本: %VARIABLE_NAME%
  • PowerShell 脚本: $env:VARIABLE_NAME
  • Bash 脚本: $VARIABLE_NAME

重要

包含文件路径的预定义变量将转换为基于代理主机类型和 shell 类型的相应样式 (Windows 样式 C:\foo\ 与 Unix 样式 /foo/) 。 如果在 Windows 上运行 bash 脚本任务,则应使用环境变量方法访问这些变量,而不是管道变量方法,以确保具有正确的文件路径样式。

TFS 不支持 YAML。

设置机密变量

不要在 YAML 文件中设置机密变量。 操作系统通常会记录它们运行的进程的命令,你不希望日志包含作为输入传入的机密。 使用脚本的环境或映射块中的 variables 变量,将机密传递给管道。

需要在管道的管道设置 UI 中设置机密变量。 这些变量的范围限定为在其中设置它们的管道。 还可以 在变量组中设置机密变量

若要在 Web 界面中设置机密,请执行以下步骤:

  1. 转到“管道”页,选择适当的管道,然后选择“编辑”。
  2. 找到该管道的变量。
  3. 添加或更新该变量。
  4. 选择 机密 锁图标以加密方式存储变量。
  5. 保存管道。

机密变量使用 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 中添加变量。 变量组使用两个变量: usertoken。 该 token 变量为机密,并映射到环境变量,以便可以在 YAML 中引用该变量 $env:MY_MAPPED_TOKEN

此 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 语法:

  • 在阶段级别,引用不同阶段中的变量的格式为 dependencies.STAGE.outputs['JOB.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]

参数

  • 组织:Azure DevOps 组织 URL。 You can configure the default organization using az devops configure -d organization=ORG_URL. 如果未配置为默认或使用 git config选取,则为必需。 示例:--org https://dev.azure.com/MyOrganizationName/
  • pipeline-id:如果未提供 管道名称 ,则为必需。 管道的 ID。
  • pipeline-name:如果未提供 管道 ID ,则为必需,但如果提供 管道 ID ,则忽略。 管道的名称。
  • 项目:项目的名称或 ID。 You can configure the default project using 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日志记录命令。 这将更新后续作业的环境变量。 后续作业将有权访问具有 宏语法 的新变量,并在任务中作为环境变量。

如果 issecret 设置为 true,变量的值将保存为机密并从日志中屏蔽。 有关机密变量的详细信息,请参阅 日志记录命令

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

设置多作业输出变量

If you want to make a variable available to future jobs, you must mark it as an output variable by using 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。 管道运行页上会显示警告。

无法设置 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。

变量的扩展

在多个范围设置同名变量时,将应用以下优先级(最高优先级排在首位)。

  1. 在 YAML 文件中设置的作业级别变量
  2. 在 YAML 文件中设置的阶段级别变量
  3. 在 YAML 文件中设置的管道级别变量
  4. 在排队时设置的变量
  5. 在管道设置 UI 中设置的管道变量

在以下示例中,同一变量 a 在 YAML 文件中的管道级别和作业级别设置。 它还在变量组中 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。