【问题标题】:Pass variables to yaml template (like parameters) in azure pipelines在 azure 管道中将变量传递给 yaml 模板(如参数)
【发布时间】:2020-08-20 10:04:10
【问题描述】:

为了尽量减少重复的构建脚本,我们在管道中使用了模板。这些模板有参数。但是,我现在遇到了一个问题,因为我需要将数据传递到管道启动时尚不可用的模板。 (数据是在流水线的某些步骤中生成的)。由于在管道启动时会扩展参数,因此无法通过参数将数据传递给模板。

我知道我可以在管道中引用不同任务、作业和阶段的输出变量,但我使用的模板不知道它在其中执行的周围管道。所以模板不知道如何引用模板之外的其他作业的输出变量,仅仅是因为模板不知道之前执行了哪些作业。

有什么方法可以在我的模板中映射变量吗?理想情况下,我想做这样的事情:

stages:
- stage: Stage1
  jobs:
  - some job that creates output variables
- stage: Stage2
  jobs:
  - template: 'myTemplate.yaml'
    variables:
      data1: $[ stageDependencies.Stage1.some_job.outputs['taskname.data1']]

并在模板中提供 data1 变量。

所以我尽量避免使用:$[ stageDependencies.Stage1.some_job.outputs['taskname.data1']]在模板中,因为Stage1 甚至可能不存在于使用模板的所有管道中。

如果模板只包含步骤而不是多个作业,我实际上可以这样做:

- stage: Stage2
  jobs:
  - job: Job1
    variables:
      data1: $[ stageDependencies.Stage1.some_job.outputs['taskName.data1']]

    steps:
    - template: templates/Azure/CreateTenant.yaml

很遗憾,我的模板包含多个作业

更新: 我已输入功能请求以更好地支持这种情况: https://developercommunity.visualstudio.com/idea/1207453/yaml-template-variablesparameters-that-are-expande.html

【问题讨论】:

    标签: yaml azure-pipelines


    【解决方案1】:

    如果模板只包含步骤而不是多个作业,我实际上可以做到这一点。不幸的是,我的模板包含多个作业

    要解决此问题,您可以在阶段级别而不是作业级别定义变量:

      - stage: Stage2
        variables:
          data1: $[ stageDependencies.Stage1.some_job.outputs['taskName.data1']]
    
        jobs:
          - template: templates/Azure/CreateTenant.yaml
    

    那么我们就可以避免在模板中使用:$[ stageDependencies.Stage1.some_job.outputs['taskname.data1']]。

    您可以查看文档Variable scopes 了解更多详细信息。

    【讨论】:

    • 谢谢,我今天早些时候也想通了。还没有尝试过,但没有看到为什么这不起作用的原因。可惜没有合适的方法使用“参数”的方式来做到这一点,所以我们实际上可以看到模板需要哪些变量,而不是搜索模板的内容
    【解决方案2】:

    除了Leo Liu-MSFT 的回答之外,我想分享我用来将 YAML 变量传递给模板的两种技术:

      - stage: Stage2
        variables:
          entireJobOutputInJson: $[convertToJson(stageDependencies.Stage1.some_job.outputs)]
    
        jobs:
          - template: templates/Azure/CreateTenant.yaml
            parameters:
              variableNameWithJobOutputInJson: 'entireJobOutputInJson'
    

    关键点:

    1. 我们可以在需要的时候使用convertToJson表达式函数来传递所有的输出变量。
    2. 我们有一个带有变量名的参数,而不是值。变量名只是模板扩展时刻已知的静态字符串值,因此我们可以将其传递给模板。这种技术允许使在模板中使用外部变量的事实可见。它可以避免在重命名变量等重构过程中出现问题。

    在模板中,变量可以简单地用$(variableName)语法的名称扩展:

    parameters:
      variableNameWithJobOutputInJson: ''
    
    jobs:
    - job: Job1
      steps:
        - pwsh: |
            $obj = ConvertFrom-Json '$(${{ parameters.variableNameWithJobOutputInJson }})'
            $props = $obj.psobject.properties.name
            foreach ($property in $props ) {
              $varName = ($property -split "\.")[-1] # taking only the last part of multipart identifier
              echo "##vso[task.setvariable variable=$varName]$($obj.$property)"
            }
          displayName: 'Import Job output'
    

    我在这里使用了 pwsh,因为它可以在基于 windows 和 linux 的代理中运行。

    【讨论】:

      猜你喜欢
      • 2022-06-29
      • 1970-01-01
      • 2022-06-29
      • 2021-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-29
      相关资源
      最近更新 更多