user1279914
user1279914

Reputation: 185

Turning an azure-pipeline.yml into a template

I am trying to turn a YAML Azure pipeline file into a template, but running into some issues.

A high level overview of what I am trying to accomplish is

  1. Allow multiple projects that are deployed individually in a single repository. No changes in that project's directory means that project should not be deployed.
  2. The branch that was changed should correspond to the deployment environment. For example, the branch dev might trigger the dev pipeline, master would trigger a prod deployment.
  3. Approvals for production deployments.

I have been able to accomplish this with this pipeline:

variables:
  projectPath: PathTo/ProjectFolder

trigger:
  branches:
    include:
      - master
      - release*
  paths:
    include:
      - $(projectPath)

pool:
  vmImage: 'windows-latest'

stages:
- stage: Build
  jobs:
  - job: BuildJob
    steps:
    # build stuff        
    - publish: $(Build.ArtifactStagingDirectory)\Output
      artifact: drop

- stage: DeployToTest
  condition: and(succeeded('Build'), startsWith(variables['Build.SourceBranchName'], 'release'))
  jobs:
  - job: DeployToTestJob
    steps:
    - download: current
      artifact: drop
    # etc

- stage: DeployToProd
  condition: and(succeeded('Build'), eq(variables['Build.SourceBranchName'], 'master'))
  jobs:
  - deployment: DeployToProdJob
    pool: 
     vmImage: 'windows-latest'
    environment: prod
    strategy:
      runOnce:
        deploy:
          steps:
          - download: current
            artifact: drop
          # etc...

And this works. One complaint is that I need to create a pipeline for each project in the repo. I feel like I can get around that but not sure how without a lot of scripting. But everything else is good.

I want to turn this into a template, where the only thing I have to specify is the path to the project. I tried that, and ended up with:

# template.yaml

parameters:
- name: 'projectPath'
  default: '.'
  type: string

trigger:
  branches:
    include:
      - master
      - release*
  paths:
    include:
      - ${{ projectPath }}

pool:
  vmImage: 'windows-latest'

stages:
- stage: Build
  jobs:
  - job: BuildJob
    steps:
    # build stuff        
    - publish: $(Build.ArtifactStagingDirectory)\Output
      artifact: drop

- stage: DeployToTest
  condition: and(succeeded('Build'), startsWith(variables['Build.SourceBranchName'], 'release'))
  jobs:
  - job: DeployToTestJob
    steps:
    - download: current
      artifact: drop
    # deploy stuff

- stage: DeployToProd
  condition: and(succeeded('Build'), eq(variables['Build.SourceBranchName'], 'master'))
  jobs:
  - deployment: DeployToProdJob
    pool: 
     vmImage: 'windows-latest'
    environment: prod
    strategy:
      runOnce:
        deploy:
          steps:
          - download: current
            artifact: drop
          # deploy stuff

and

# pipeline.yaml

resources:
  repositories:
    - repository: templates
      type: git
      name: sample/repo
      #ref: refs/tags/v1.0 # optional ref to pin to

extends:
  template: template.yml@templates  # Template reference
  parameters:
    projectPath: 'Some\Path'

But this gave me a couple errors:

/approval-pipeline.yml@templates (Line: 13, Col: 9): A template expression is not allowed in this context /approval-pipeline.yml@templates (Line: 15, Col: 1): Unexpected value 'pool'

Is there a way I can still utilize my projectPath parameter here? And is there a reason why I can use pool here? I didn't find the limitations of templates listed anywhere on the docs on MSDN.

Also, is this the best way to do this? Or would I be able to specify the path to each project somehow, and check if they had changes individually, and only run the pipeline in cases where that were true?

Upvotes: 0

Views: 1208

Answers (1)

Jane Ma-MSFT
Jane Ma-MSFT

Reputation: 5242

Is there a way I can still utilize my projectPath parameter here?

If you use templates to author YAML files, then you can only specify triggers in the main YAML file for the pipeline. You cannot specify triggers in the template files.

And is there a reason why I cannot use pool here?

In template, 'pool' should be added into 'job'.

So what you need to do is:

  1. Move your 'trigger' to pipeline.yml
  2. Delete 'pool' and add it between 'job' and 'steps'.

The modified code:

# template.yaml

stages:
- stage: Build
  jobs:
  - job: BuildJob
    pool:
      vmImage: 'windows-latest'
    steps:
    # build stuff        
    - publish: $(Build.ArtifactStagingDirectory)\Output
      artifact: drop

- stage: DeployToTest
  condition: and(succeeded('Build'), startsWith(variables['Build.SourceBranchName'], 'release'))
  jobs:
  - job: DeployToTestJob
    pool:
      vmImage: 'windows-latest'
    steps:
    - download: current
      artifact: drop
    # deploy stuff

- stage: DeployToProd
  condition: and(succeeded('Build'), eq(variables['Build.SourceBranchName'], 'master'))
  jobs:
  - deployment: DeployToProdJob
    pool: 
      vmImage: 'windows-latest'
    environment: prod
    strategy:
      runOnce:
        deploy:
          steps:
          - download: current
            artifact: drop
          # deploy stuff

and

# pipeline.yaml

variables:
  projectPath: PathTo/ProjectFolder

trigger:
  branches:
    include:
      - master
      - release*
  paths:
    include:
      - $(projectPath)

resources:
  repositories:
    - repository: templates
      type: git
      name: sample/repo
      #ref: refs/tags/v1.0 # optional ref to pin to

extends:
  template: template.yml@templates  # Template reference
  parameters:
    projectPath: 'Some\Path'

Upvotes: 1

Related Questions