9

Is it possible to nest yaml templates inside another yaml template ?

I've multiple NuGet projects in different Git repository, and I'm trying to template the process of publishing NuGets on nuget.org.

So I created a git repository named "devops-templates", did a first yaml template, be sure that it works, then divide it 4 yaml templates (build solution, generate packages, run unit tests, publish), and reference them into the global yaml template.

The problem is that when I tried to use this global template into my pipelines, I obtained errors

/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

I searched inside Microsoft documentation : https://learn.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops but didn't find any information about it.

Here some parts of my code:

azure-pipelines.yml (main repository):

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-templates repository):

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-template repository):

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
        (...)

Edit : I added some parts of my code.

Ben Smith
  • 19,589
  • 6
  • 65
  • 93
Vianney Doleans
  • 163
  • 1
  • 1
  • 10

2 Answers2

6

It seems like there is an indentation mistake in your BuildSolution.yml. parameters and jobs should have the same indentation. refer to below:

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}}
Levi Lu-MSFT
  • 27,483
  • 2
  • 31
  • 43
  • Thanks ! It works. I was thinking about cancel last commits and continue with my precedent template file but your answer unlock my situation. Sorry with a so big mistake, I'm still newbie in azure-devops. – Vianney Doleans Nov 05 '19 at 11:43
3

You can reference four kinds of templates within Azure Pipelines: Stage, Job, Step and Variable.

An example (with slightly modified comments by me) taken from the "Template References" documentation is as follows:

# 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

And the test.yml file is as follows:

# 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 }}
Ben Smith
  • 19,589
  • 6
  • 65
  • 93
  • I did something similar at first, but now I'm trying to split my first template into small job templates, without have to change my pipeline, because it would increase the number of lines in each pipelines I have to realize. And by splitting the first template I realized, I could reuse jobs in the future. I edited my post for adding some code. – Vianney Doleans Nov 05 '19 at 10:39
  • @VianneyDoleans Ah Ok. I wrote this answer before you added extra detail to your question. Looks like Levi Lu-MSFT has answered your problem. – Ben Smith Nov 05 '19 at 10:57
  • 1
    Yes, his answer solved my problem. Sorry for not adding code in my first post, I will do it next time if I need to re-post. – Vianney Doleans Nov 05 '19 at 11:50