Azure Devops:是不是可以将 yaml 模板嵌套在另一个 yaml 模板中?

Posted

技术标签:

【中文标题】Azure Devops:是不是可以将 yaml 模板嵌套在另一个 yaml 模板中?【英文标题】:Azure Devops: Is it possible to nest yaml templates inside another yaml template?Azure Devops:是否可以将 yaml 模板嵌套在另一个 yaml 模板中? 【发布时间】:2020-03-01 02:21:27 【问题描述】:

是否可以将 yaml 模板嵌套在另一个 yaml 模板中?

我在不同的 Git 存储库中有多个 NuGet 项目,我正在尝试在 nuget.org 上对发布 NuGet 的过程进行模板化。

所以我创建了一个名为“devops-templates”的 git 存储库,做了第一个 yaml 模板,确保它可以工作,然后将它分成 4 个 yaml 模板(构建解决方案、生成包、运行单元测试、发布),并参考将它们添加到全局 yaml 模板中。

问题是当我尝试在我的管道中使用这个全局模板时,我得到了错误

/Net/Utilities/BuildSolution.yml@templates (Line: 33, Col: 18): A template expression is not allowed in this context,/Net/Utilities/BuildSolution.yml@templates (Line: 36, Col: 21): A template expression is not allowed in this context,/Net/Utilities/BuildSolution.yml@templates (Line: 48, Col: 24): A template expression is not allowed in this context,/Net/Utilities/BuildSolution.yml@templates (Line: 53, Col: 28): A template expression is not allowed in this context,/Net/Utilities/BuildSolution.yml@templates (Line: 54, Col: 26): A template expression is not allowed in this context,/Net/Utilities/BuildSolution.yml@templates (Line: 59, Col: 21): A template expression is not allowed in this context,/Net/Utilities/BuildSolution.yml@templates (Line: 60, Col: 22): A template expression is not allowed in this context,/Net/Utilities/BuildSolution.yml@templates (Line: 61, Col: 32): A template expression is not allowed in this context,/Net/Utilities/BuildSolution.yml@templates (Line: 63, Col: 21): A template expression is not allowed in this context,/Net/Utilities/BuildSolution.yml@templates (Line: 64, Col: 26): A template expression is not allowed in this context

我在 Microsoft 文档中搜索:https://docs.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops,但没有找到任何相关信息。

这是我的代码的一些部分:

azure-pipelines.yml(主存储库):

resources:
  repositories:
    - repository: templates
      type: github
      name: (...)/devops-templates
      ref: refs/tags/v1.1.0
      endpoint: (...)

stages:
- template: Net/Pipeline/NuGetsPipeline.yml@templates
  parameters:
    solution: $(solution)
    nuGetsArtifactName: $(nuGetsArtifactName)
    buildArtifactName : $(buildArtifactName)
    (...)

NuGetsPipeline.yml(devops 模板存储库):

parameters:
 nuGetsArtifactName: 'NuGets'
 buildArtifactName : 'Build'
 nuGetSource: https://api.nuget.org/v3/index.json
 solution: ''
 (...)

stages:

- stage: Build
  jobs:
  - template: $variables['System.DefaultWorkingDirectory']/Net/Utilities/BuildSolution.yml
    parameters:
      buildArtifactName : $ parameters.buildArtifactName 
      (...)

  - template: $variables['System.DefaultWorkingDirectory']/Net/Utilities/GenerateNuGets.yml
    parameters:
      nuGetsArtifactName: $ parameters.nuGetsArtifactName 
      buildArtifactName : $ parameters.buildArtifactName 
      (...)

- stage: 'UnitTests'
  jobs:
  - template: $variables['System.DefaultWorkingDirectory']/Net/Utilities/RunUnitTests.yml
    parameters:
      buildArtifactName : $ parameters.buildArtifactName 
      (...)

- stage: 'Publish'
  jobs:
  - template: $variables['System.DefaultWorkingDirectory']/Net/Utilities/PublishNuGets.yml
    parameters:
      nuGetsArtifactName: $ parameters.nuGetsArtifactName 
      (...)

BuildSolution.yml(devops 模板存储库):

parameters:
  buildArtifactName: 'Build'
  solution: ''
  (...)

  jobs:
  - job: 'BuildSolution'
    pool:
        vmImage: $ parameters.vmImage 
    continueOnError: false
    variables:
      artifactName: $ parameters.buildArtifactName 
    steps:
      - task: NuGetCommand@2
        displayName: 'Restore NuGet packages'
        inputs:
          restoreSolution: $ parameters.solutionDir /$ parameters.solution 
          configuration: $ parameters.buildConfiguration

      - task: VSBuild@1
        (...)

编辑:我添加了部分代码。

【问题讨论】:

是的,您能展示您的模板以及如何称呼它们吗? 如错误所示,您的模板中可能存在错误。能否请您发布您的模板? 是的,当然。我编辑了我的帖子。 问题已解决。所以是的,可以将 yaml 模板嵌套在其他 yaml 模板中,我的错误是缩进。感谢您的回复! 【参考方案1】:

在制作复杂的 yaml 模板时,有时最好从内置宏扩展转移到专用的宏语言。

例如,ERB 在模板中为您提供了 Ruby 的所有功能。

SMX 在一个对 yaml 友好的包中为您提供 Python 的所有功能。

这样你就不受范围的限制,你可以使用函数、类、循环等。

您可以使用预提交挂钩和 l​​inter 来确保 yaml 已从模板派生。

有关最简单的预提交框架,请参阅 http://pre-commit.com。

【讨论】:

如何将其应用于 Azure yaml Pipelines? @Carlin'tVeld 我会使用 SMX 或 ERB 在 git 钩子中生成 yaml,并添加一个 linter 步骤以确保使用了钩子。 (也编辑过答案) 我猜你仍然受到 Azure Pipelines 运行时的限制。您只能使用这些类型的语言来生成您的 yaml 管道文件。看到 Azure Pipelines 运行您的自定义代码来定义工作的一些集成扩展会很酷。【参考方案2】:

您的 BuildSolution.yml 中似乎存在缩进错误。 参数和作业应该有相同的缩进。参考以下:

parameters:
  buildArtifactName: "build"
  solution: ""

jobs:
- job: 'BuildSolution'
  pool:
    vmImage: $parameters.vmImage
    continueOnError: false
  variables:
    artifactName: $ parameters.buildArtifactName
  steps:
    - task: NuGetCommand@2
      displayName: 'Restore NuGet packages'
      inputs:
        restoreSolution: $ parameters.solutionDir /$ parameters.solution 
        configuration: $parameters.buildConfiguration

【讨论】:

谢谢!有用。我正在考虑取消最后一次提交并继续使用我的先例模板文件,但您的回答解开了我的困境。抱歉,犯了这么大的错误,我还是 azure-devops 的新手。【参考方案3】:

您可以在 Azure Pipelines 中引用四种模板:Stage、Job、Step 和 Variable。

取自“Template References”文档的示例(我对 cme​​ts 稍作修改)如下:

# File: azure-pipelines.yml which references another YAML file (test.yml)

stages:
- template: stages/test.yml  # Template reference
  parameters:
    name: Mini
    testFile: tests/miniSuite.js

- template: stages/test.yml  # Template reference
  parameters:
    name: Full
    testFile: tests/fullSuite.js

而test.yml文件如下:

# File: test.yml file to be referenced by the azure-pipelines.yml file

parameters:
  name: ''
  testFile: ''

stages:
- stage: Test_$ parameters.name 
  jobs:
  - job: $ parameters.name _Windows
    pool:
      vmImage: vs2017-win2016
    steps:
    - script: npm install
    - script: npm test -- --file=$ parameters.testFile 
  - job: $ parameters.name _Mac
    pool:
      vmImage: macos-10.13
    steps:
    - script: npm install
    - script: npm test -- --file=$ parameters.testFile 

【讨论】:

一开始我做了类似的事情,但现在我试图将我的第一个模板拆分为小作业模板,而不必更改我的管道,因为它会增加我在每个管道中的行数必须意识到。通过拆分我意识到的第一个模板,我可以在未来重用工作。我编辑了我的帖子以添加一些代码。 @VianneyDoleans 啊好的。在您为问题添加额外细节之前,我写了这个答案。看起来 Levi Lu-MSFT 已经回答了您的问题。 是的,他的回答解决了我的问题。很抱歉我第一次发帖没有加代码,下次如果需要重新发帖。 @VianneyDoleans 没问题。很高兴您的问题现已解决:)

以上是关于Azure Devops:是不是可以将 yaml 模板嵌套在另一个 yaml 模板中?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 azure devops 中解析 yaml 文件

Azure DevOps YAML并行运行未排队

将数组作为输入传递给 Azure DevOps YAML 任务

Yaml Azure Devops TerraformInstaller 不明确

如何:在 Azure DevOps YAML 中有条件地插入模板?

Azure Devops - 将 YAML 脚本中的变量设置为日期时间