azure-devopsazure-pipelinesazure-pipelines-yaml

Why is a parameter not seen when using extend?


We have two very similar DevOps (on a locally hosted server) projects, they differ in lists of files to handle, but the procedures are almost identical.

To avoid code duplication, we use shared components, like variables-common.yml, doBuild.yml, and product specific ones, like build-FOO.yml and build-BAR.yml.

All this works perfectly well for the initial FOO-pipeline.yml, which extends with a common Base-pipeline.yml. Adding BAR-pipeline.yml creates a problem I just cannot understand.

The pipelines FOO and BAR are identical, except for "FOO" and "BAR", so I'm showing only FOO:

# FOO-pipleline.yml

parameters:

  - name: cleanAgents
    displayName: Wipe agents before build
    type: boolean
    default: false
    values:
    - false
    - true

  - name: buildSoftware
    displayName: Build software
    type: boolean
    default: true
    values:
    - false
    - true

  - name: runAnalysis
    displayName: Run static code analysis
    type: boolean
    default: true
    values:
    - false
    - true

variables:

  - template: Variables/variables-FOO.yml
  - template: Variables/variables-Common.yml

name: FOO-$(productVersion)-$(Date:yyMMdd)$(Rev:rr)

resources:
  repositories:
    - repository:  FOO
      type: git    
      name: FOO
      ref: main
      trigger:
        branches:
          include:
          - main
      paths: # Paths where a code change triggers a run
        include:
        - Libraries
    - repository: FOO-TestComplete
      type: git
      name: FOO-TestComplete
      ref: main
      trigger: none        
trigger:
  - none # CI: main


extends:
  template: Base-pipeline.yml
  parameters:
    productName: FOO
    cleanAgents: ${{ parameters.cleanAgents }}
    buildSoftware: ${{ parameters.buildSoftware }}
    runAnalysis: ${{ parameters.runAnalysis }}

Here's a shorted version of Base-pipeline.yml:

# Base-pipleline.yml
parameters:   
- name: productName
  type: string  
- name: cleanAgents
  type: boolean
  default: false    
- name: buildSoftware    
  type: boolean

stages:

  - stage: stage_Build_without_analysis
    #      ============================
    displayName: 'Build ${{ parameters.productName }}, no analysis'
    pool:
      demands: BuildServer
    condition: or(${{ eq(parameters.buildSoftware, true) }},${{ eq(parameters.runUnitTests, true) }}, ${{ eq(parameters.runAnalysis, true) }})
    jobs:
    - template: /Build/Build.yml

The problem with BAR-pipeline (identical to FOO, just with BAR) is that I get an error

A value for the 'cleanAgents' parameter must be provided.

cleanAgents is there, it works for FOO and is seen for FOO. Not so for BAR.

A strange observation that might help in finding the problem:

If I use /Base-pipeline.yml (added slash) for the extend template, the validator tells me it does not exist, and lists all existing YAML-files. This list contains Base-pipeline.yml twice. I don't understand why, but it might be related.


Solution

  • A value for the 'cleanAgents' parameter must be provided.

    This error means the parameter cleanAgents is not being set in one of templates (or subtemplates) used in the pipeline.