admin管理员组

文章数量:1353265

Let's say, I have a stage which, at some point, has a task which writes an output variable:

steps:    
- task: PowerShell@2
  name: TargetDirectory
  displayName: 'Determine Target Directory'
  inputs:
    targetType: 'inline'
    script: |
      $targetDirectory = "web_$(Build.BuildId)_$(System.JobAttempt)"
      Write-Host "##vso[task.setvariable variable=deploymentTargetDirectory;isOutput=true]$targetDirectory"

And in a later stage, I want to pass this output variable to a job template. This doesn't work, the value is simply taken as is and not interpolated:

- stage: Build
    dependsOn: PreProcess
    jobs:
    - template: build-tpl.yml
      parameters:
        targetDir: $[ stageDependencies.PreProcess.DeploymentSetup.outputs['TargetDirectory.deploymentTargetDirectory'] ]
        

While this does work exactly the way it should:

 - stage: Build
    dependsOn: PreProcess
    variables:                  #It works if I set a stage variable here
      deploymentTargetDir: $[ stageDependencies.PreProcess.DeploymentSetup.outputs['TargetDirectory.deploymentTargetDirectory'] ]
    jobs:
    - template: build-tpl.yml
      parameters:
        targetDir: $(deploymentTargetDir)

To be clear, I am fairly sure I adress the variable correctly, as I didn't change anything in the working example. Only difference is, that I assign the value of my output variable to a stage variable before passing it to the parameter of the template.

Since I could't not find any refernce and only found that out by trial and error - is this the correct way, or is there a simpler, better way?

Let's say, I have a stage which, at some point, has a task which writes an output variable:

steps:    
- task: PowerShell@2
  name: TargetDirectory
  displayName: 'Determine Target Directory'
  inputs:
    targetType: 'inline'
    script: |
      $targetDirectory = "web_$(Build.BuildId)_$(System.JobAttempt)"
      Write-Host "##vso[task.setvariable variable=deploymentTargetDirectory;isOutput=true]$targetDirectory"

And in a later stage, I want to pass this output variable to a job template. This doesn't work, the value is simply taken as is and not interpolated:

- stage: Build
    dependsOn: PreProcess
    jobs:
    - template: build-tpl.yml
      parameters:
        targetDir: $[ stageDependencies.PreProcess.DeploymentSetup.outputs['TargetDirectory.deploymentTargetDirectory'] ]
        

While this does work exactly the way it should:

 - stage: Build
    dependsOn: PreProcess
    variables:                  #It works if I set a stage variable here
      deploymentTargetDir: $[ stageDependencies.PreProcess.DeploymentSetup.outputs['TargetDirectory.deploymentTargetDirectory'] ]
    jobs:
    - template: build-tpl.yml
      parameters:
        targetDir: $(deploymentTargetDir)

To be clear, I am fairly sure I adress the variable correctly, as I didn't change anything in the working example. Only difference is, that I assign the value of my output variable to a stage variable before passing it to the parameter of the template.

Since I could't not find any refernce and only found that out by trial and error - is this the correct way, or is there a simpler, better way?

Share Improve this question asked Apr 1 at 12:06 HafnernussHafnernuss 2,8492 gold badges32 silver badges46 bronze badges 1
  • 1 Agree with @bryanbcook below. Actually you can edit the pipeline, Download full yaml to check the expanded yaml, it shows the real pipeline definition. Runtime variable is used for condition or expression, so if you pass it as parameters, in template you need to define variable again. Or define in stage level as you did in your last yaml. – wade zhou - MSFT Commented Apr 2 at 3:11
Add a comment  | 

1 Answer 1

Reset to default 1

The key is understanding the pipeline run sequence:

  • templates and their parameters are expanded at compile-time. ${{<expr>}} syntax are for compile-time expressions. Before the pipeline is run, only pre-defined system variables are available. Variables written with macro-syntax $() or runtime-expressions $[] have no meaning and are treated as literals.

  • variables are evaluated at runtime, meaning the most current value is dereferenced. $[<expr>] are runtime expressions. Only a few locations in the pipeline schema support runtime expressions:

    • variable declarations
    • stage, job and step condition. Note that succeeded() and $[ succeeded() ] are functionally equivalent and the $[ ] syntax is optional for conditions.

For the example you've provided, it is possible to pass runtime expressions as parameters and then dereference them as variables in your job template. Following this practice allows the caller to pass a runtime-expression, macro-syntax or literal value.

# build-tpl.yml template
parameters:
- name: targetDir
  type: string

jobs:
- job: jobname
  variables:
    # dereference the runtime expression, macro-syntax or literal value
    targetDir: ${{ parameters.targetDir }}
  steps:
  - pwsh: write-host $(targetDir)
# calling pipeline
stages:
- stage: PreProcess
  jobs:
  - job: DeploymentSetup
    steps:
    # ... step to create output variable deploymentTargetDirectory

- stage: Build
  dependsOn: PreProcess
  jobs:
  - template: build-tpl.yml
    parameters:
      targetDir: $[ stageDependencies.PreProcess.DeploymentSetup.outputs['TargetDirectory.deploymentTargetDirectory'] ]
        

本文标签: Azure Yml Pipelines Variables as template parameterStack Overflow