在模板作业中跨阶段使用管道变量

时间:2021-07-30 16:14:05

标签: azure-devops azure-pipelines-yaml

问题描述

我在尝试在另一个阶段使用在一个阶段创建的变量时遇到了一些问题,并设法找到了各种新旧文章,描述了如何做到这一点。识别新语法的最新文章/帖子

$[stageDependencies.{stageName}.{jobName}.outputs['{stepName}.{variableName}']

像这样使用:

variables:
  myVariable: $[stagedependencies.CreateStageVarStage.CreateStageVarJob.outputs['SetValueStep.VariableFromFirstStage']]

这很好用,直到您需要使用作业模板。

我在网上找到的样本都没有涉及模板的情况。他们只是演示了同一个 yaml 文件中的多个阶段如何获取值。

语法取决于能够将表达式放入变量中。不幸的是,当您为作业使用模板时,无法声明变量并将其作为参数传递会导致它未被评估。

- stage: UseJobTemplateStage
  displayName: 'Use Job Template Stage'
  dependsOn: CreateStageVarStage
  jobs:
  - template: templates/job-showstagevars.yml
    parameters:
      ValueToOutput: $[ stagedependencies.CreateStageVarStage.CreateStageVarJob.outputs['SetValueStep.VariableFromFirstStage'] ]

在此代码段中,它按原样显示。该值不会被替换。

理论上,您可以将您的工作设置为在变量块中包含表达式,但这种硬编码破坏了模板的主要好处之一。

相关文章

Share variables across stages in Azure DevOps Pipelines
Azure DevOps Release Notes - sprint 168

1 个答案:

答案 0 :(得分:0)

解决方案

答案其实并不遥远。原始表达式只需要通过模板作业中的一个变量即可。基本上,将变量设置为参数的值并使用宏语法来评估变量。

parameters:
- name: ValueToOutput
  type: string

...

  variables:
  - name: LocalVarOfValueToOutputParam
    value: ${{ parameters.ValueToOutput }}

使用 $(LocalVarOfValueToOutputParam) 的宏语法将导致值正确进入模板作业。

示例

如果我们有一个用于构建定义的 yaml 文件:

stages:
- stage: CreateStageVarStage
  displayName: 'Create StageVar Stage'
  jobs:
  - job: CreateStageVarJob
    displayName: 'Create StageVar Job'
    timeoutInMinutes: 5
    pool:
      name:    'Azure Pipelines'
      vmImage: 'windows-2019'
    steps:
      - checkout: none 
      - pwsh: |
          [string]$message = 'This is the value from the first stage'
          Write-Host "Setting output variable 'VariableFromFirstStage' to '$message'"
          Write-Output "##vso[task.setvariable variable=VariableFromFirstStage;isOutput=$true]$message"
        name: SetValueStep

- stage: UseJobTemplateStage
  displayName: 'Use Job Template Stage'
  dependsOn: CreateStageVarStage
  jobs:
  - template: templates/job-showstagevars.yml
    parameters:
      ValueToOutput: $[ stagedependencies.CreateStageVarStage.CreateStageVarJob.outputs['SetValueStep.VariableFromFirstStage'] ]

使用作业模板 templates/job-showstagevars.yml

parameters:
- name: ValueToOutput
  type: string

jobs:
- job: ShowStageVarJob
  displayName: 'Show stage var'
  timeoutInMinutes: 5
  pool:
    name:    'Azure Pipelines'
    vmImage: 'windows-2019'

  variables:
  - name: LocalVarOfValueToOutputParam
    value: ${{ parameters.ValueToOutput }}

  steps:
  - checkout: none
  - pwsh: |
      Write-Host "ValueToOutput parameter=${{ parameters.ValueToOutput }}"
      Write-Host "LocalVarOfValueToOutputParam (pre-processor syntax)=${{ variables.LocalVarOfValueToOutputParam }}"
      Write-Host "LocalVarOfValueToOutputParam (macro syntax)=$(LocalVarOfValueToOutputParam)"
    displayName: 'Show StageVariable'

我们在第二阶段的输出中得到的是:

ValueToOutput parameter=$[ stagedependencies.CreateStageVarStage.CreateStageVarJob.outputs['SetValueStep.VariableFromFirstStage'] ]
LocalVarOfValueToOutputParam (pre-processor syntax)=$[ stagedependencies.CreateStageVarStage.CreateStageVarJob.outputs['SetValueStep.VariableFromFirstStage'] ]
LocalVarOfValueToOutputParam (macro syntax)=This is the value from the first stage