定义变量

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

变量命名限制

用户定义的和环境变量可以包含字母、数字、 ._ 字符。 请勿使用系统保留的变量前缀。 这些是: 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 属性。

注意

宏语法变量仅针对 stagesjobssteps展开。 例如,不能在 或 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 中引用它们。

以下示例演示如何设置和 两个变量, configurationplatform并在后续步骤中使用它们。 若要在 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 界面中设置机密,请执行以下步骤:

  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 是机密变量,并映射到环境变量 $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。 管道运行页上会显示警告。

警告:无法设置 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 中设置的管道变量

在以下示例中,在 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。