定义变量

注意

在 Microsoft Team Foundation Server (TFS) 2018 和更低版本中,生成和发布管道被称为“定义”,运行被称为“生成”,服务连接被称为“服务终结点”,阶段被称为“环境”,而作业被称为“阶段” 。

变量为你提供了一种简便方法,可以将关键数据位导入管道的各个部分。 变量最常见的用途是定义一个可在管道中使用的值。 所有变量都存储为字符串,并且是可变的。 变量的值可以从 "运行" 更改为 "运行",也可以从 "作业" 更改为管道的作业。

在具有相同名称的多个位置定义相同的变量时,最本地范围内的变量会入选。 因此,在作业级别定义的变量可以在阶段级别重写变量集。 在阶段级别定义的变量将覆盖管道根级别的变量集。 管道根级别中的变量集将覆盖管道设置 UI 中的变量集。

您可以使用带有 表达式 的变量来有条件地分配值并进一步自定义管道。

变量不同于 运行时参数,这些参数在模板分析期间已类型化并可用。

用户定义的变量

在定义变量时,可以使用 (宏、模板表达式或运行时) 的不同 语法,以及使用哪种语法来确定变量将呈现在管道中的何处。

在 YAML 管道中,可以在根、阶段和作业级别设置变量。 你还可以在 UI 中的 YAML 管道之外指定变量。 在 UI 中设置变量时,可以加密该变量并将其设置为机密。

用户定义的变量可以 设置为只读变量的命名限制 (例如:不能 在变量名称的开头使用) 。

可以 使用变量组 使变量在多个管道中可用。

您可以使用 模板 来定义一个文件中多个管道中使用的变量。

系统变量

除了用户定义的变量外,Azure Pipelines 包含具有预定义值的系统变量。 如果使用的是 YAML 或经典生成管道,请参阅 预定义的变量 ,了解系统变量的完整列表。 如果使用的是经典版本管道,请参阅 发布变量

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

系统变量是只读的。

环境变量

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

在 (macOS 和 Linux) UNIX 系统上,环境变量的格式为 $NAME 。 在 Windows 上,格式 %NAME% 适用于 batch 和 $env:NAME PowerShell。

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

变量命名限制

用户定义的变量可以包含字母、数字、 ._ 字符。 请勿使用系统保留的变量前缀。 其中包括: endpointinputsecretsecurefile 。 任何以这些字符串之一开头的变量 (不管大小写) 将不可用于你的任务和脚本。

了解变量语法

Azure Pipelines 支持三种不同的方法来引用变量:宏、模板表达式和运行时表达式。 每个语法可以用于不同的目的,并且有一些限制。

在管道中,模板表达式变量 (${{ variables.var }} 在运行时启动之前,在编译时处理) 。 宏语法变量 (在 $(var) 任务运行之前) 在运行时进行处理。 运行时表达式 ($[variables.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)foo 在 Bash 任务中引用变量,则将 $() 输入中的所有表达式替换为任务可能会中断 Bash 脚本。

宏变量仅在用于值(而不是关键字)时展开。 值显示在管道定义的右侧。 下面是有效的: key: $(value) 。 以下内容无效: $(key): value 。 宏变量用于显示作业名称内联。 您必须改用 displayName 属性。

注意

宏语法变量仅适用于 stagesjobssteps 。 例如,您不能在或中使用宏语法 resourcetrigger

在此示例中,宏语法与 Bash、PowerShell 和脚本任务一起使用。 使用宏语法调用变量的语法对于这三个语法都是相同的。

variables:
 - name: projectName
   value: contoso

steps: 
- bash: echo $(projectName)
- powershell: echo $(projectName)
- script: echo $(projectName)

模板表达式语法

您可以使用模板表达式语法来展开 模板参数 和变量 () 。 模板变量在编译时处理,并在运行时启动之前被替换。 模板表达式设计用于将部分 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] 运行库 值 (右侧) 空字符串

我应该使用什么语法?

如果要为任务提供输入,请使用宏语法。

如果使用条件和表达式 ,请选择运行时表达式。 这种情况的例外是,如果管道会导致空变量打印出问题。例如,如果条件逻辑依赖于具有特定值或无值的变量。 在这种情况下,应该使用运行时表达式。

如果要在模板中定义变量,请使用模板表达式。

在管道中设置变量

在最常见的情况下,设置变量,在 YAML 文件中使用它们。 这样,你可跟踪版本控制系统中变量的更改。 还可以在管道设置 UI 中定义变量, ("经典"选项卡) YAML 中引用它们。

以下示例演示如何设置两个变量 和 configurationplatform ,并稍后在步骤中使用它们。 若要在 YAML 语句中使用该变量,请将其包装在 中 $() 。 变量不能用于定义 repository YAML 语句中的 。

# 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. 选择 Secret 锁定图标,以加密方式存储变量。
  5. 保存管道。

机密变量使用2048位 RSA 密钥进行静态加密。 要使用的任务和脚本的代理中提供了机密。 请注意谁有权改变你的管道。

重要

我们努力屏蔽机密,使其在 Azure Pipelines 输出中出现,但你仍需要采取预防措施。 切勿回显机密作为输出。 一些操作系统日志命令行参数。 永远不要在命令行上传递机密。 相反,我们建议你将机密映射到环境变量。

我们从不屏蔽机密的子字符串。 例如,如果将 "abc123" 设置为机密,则不会从日志中屏蔽 "abc"。 这是为了避免过于精细地屏蔽机密,使日志不可读。 出于此原因,机密不应包含结构化数据。 例如,如果 "{" foo ":" bar "}" 设置为机密,则不会从日志中屏蔽 "bar"。

与普通变量不同,它们不会自动解密到脚本的环境变量中。 需要显式映射机密变量。

下面的示例演示如何使用 mySecret PowerShell 和 Bash 脚本中调用的机密变量。 与普通管道变量不同,没有名为的环境变量 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 。 此示例演示如何 $(vmsUser)$(vmsAdminPass) 在 Azure 文件复制任务中使用机密变量和。

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 中添加变量。 变量组中使用了两个变量: usertokentoken变量是机密变量,并映射到环境变量, $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 中,可以使用 依赖项跨作业访问变量。

某些任务定义输出变量,可在同一作业内的下游步骤中使用。

注意

默认情况下,管道中的每个阶段都依赖于在 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 语法。

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
  - 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 漏斗 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/
  • 管道 id:如果未提供 管道名称 ,则为必需。 管道的 ID。
  • 管道名称:如果未提供 管道 id ,则是必需的,但如果提供了 管道 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.setvariabletask.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

设置多作业输出变量

如果要使变量可用于将来的作业,则必须使用 将其标记为输出变量 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 。 管道运行页上将显示一条警告。

Warning that you cannot set 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 中定义一个变量,并选择 允许用户在运行此管道时重写此值 的选项,也可以改为使用 运行时参数 。 如果你的变量不是机密,最佳做法是使用 运行时参数

若要在队列时间设置变量,请在管道中添加一个新变量,然后选择 "覆盖" 选项。

Set a variable at queue time.

若要允许在队列时间设置变量,请确保该变量不会出现在 variables 管道或作业的块中。 如果在 YAML 的 variables 块和 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。