azureyamlazure-pipelinespipelineextends

can't use extends and stages together azure pipelines


I am trying to use a template in azure devops, because it is a template to make the build of a proyect with gradle and weblogic, but before doing that i need to create the build in the front and move it to the back, the problem with that is when i add the stages it throws an error Unexpected property extends And it is not because of the version because without the steps it works normally

There is a correct option to do that, without changing the template?, i already tried many things but doesnt work, this is my code

trigger:
  - none

parameters:
  - name: deliveryTrain
    type: object
    default:
      continuousIntegration:
        build:
          - with: gradle
            configure:
              javaVersion: '1.8'
              gradleExtraOptionsLabo: 'clean build'
              workingDirectory: 'Gerencia_Tecnologia/salud-mensajeria_dinamica-back'
        artifact:
          with: 'artifactory'
          configure:
            artifactName: 'dinamica.md.ear'
      continuousDelivery:
        deployment:
          - environment: 'labo'
            platform:
              with: 'weblogic'
              configure:
                serviceConnection: 'lab-Salud-wl-12.2.1.4'
      continuousTesting:
        - environment: 'labo'
          cases:
            - type: performance
              with: 'jmeter'
              configure:
                repo:
                  name: 'Gerencia_Tecnologia/salud-mensajeria_dinamica-back-ml'
                  branch: 'feature/hu_comun_1707'
                performanceTestFiles: 'jmeter/test/test.jmx'
                performanceTestPercentilTest: '99'
                performanceTestResultFiles: 'jmeter/test/result.jtl'

stages:
  - stage: MensajeriaDinamicaFrontBuild
    displayName: 'MensajeriaDinamica-Front-build'
    jobs:
      - job: BuildFrontEnd
        displayName: 'Build Front Artifact'
        pool:
          name: 'linux-generic'
        steps:
          - checkout: front
          - task: NodeTool@0
            inputs:
              versionSpec: '12.16.1'
            displayName: 'Install Node.js'
          - script: npm install -g @angular/cli@9.0.0
            displayName: 'Install Angular CLI'
          - script: |
              npm install &&
              ng build --aot --output-hashing=all --prod
            displayName: 'Built Front Artifact'
          - task: PublishPipelineArtifact@1
            displayName: 'Publish Front Artifact to dist carpet'
            inputs:
              targetPath: '$(System.DefaultWorkingDirectory)/dist'
              artifact: 'front-artifact'
          - task: CopyFiles@2
            displayName: 'Copy files to ArtifactStagingDirectory'
            inputs:
              SourceFolder: '$(System.DefaultWorkingDirectory)/dist'
              Contents: '**'  
              TargetFolder: '$(Build.ArtifactStagingDirectory)'
          - task: PublishBuildArtifacts@1
            displayName: 'Publish front Artifact to ArtifactStagingDirectory'
            inputs:
              pathToPublish: '$(Build.ArtifactStagingDirectory)'
              artifactName: 'MensajeriaDinamicaFrontArtifact'  

      - job: CopyArtifactsToBack
        condition: succeeded('BuildFrontEnd')
        dependsOn: BuildFrontEnd
        displayName: 'Move Front Artifact to Back-End Repository'
        pool:
          name: 'linux-generic'
        steps:
            - checkout: back
            - script: |
                rm -r $(Build.SourcesDirectory)/WAR_MensajeriaDinamica/WebContent/resultadosapp/* &&
                echo "Listing the deleted folders file:"
                ls -R $(Build.SourcesDirectory)/WAR_MensajeriaDinamica/WebContent/resultadosapp
              displayName: 'cleaned back webcontent'
            - task: DownloadPipelineArtifact@2
              inputs:
                artifactName: 'MensajeriaDinamicaFrontArtifact' 
                targetPath: '$(System.DefaultWorkingDirectory)/WAR_MensajeriaDinamica/WebContent/resultadosapp/'
            - script: |
                echo "Listing the downloaded artifact:"
                ls -R $(Build.SourcesDirectory)/WAR_MensajeriaDinamica/WebContent/resultadosapp
            - template: templates/gradle-weblogic.yaml@templates
                
      - job: UsingTemplate
        displayName: 'Usar plantilla de gradle weblogic'
        steps:
          - checkout: templates
          - script: |
              ls -R $(Build.SourcesDirectory)/templates
            displayName: 'List Files in Cloned Repositories'


resources:
  repositories:
    - repository: back
      type: git
      name: Gerencia_Tecnologia/salud-mensajeria_dinamica-back-ml
      ref: feature/hu_comun_1707
    - repository: front
      type: git
      name: Gerencia_Tecnologia/salud-mensajeria_dinamica-fr
      ref: feature/hu-comun-tablas
    - repository: templates
      type: git
      name: Gerencia_Tecnologia/ti-templates_pipelines-conf
      ref: master

extends:
  template: 'templates/gradle-weblogic.yaml@templates'
  parameters:
    deliveryTrain: ${{ parameters.deliveryTrain }}

And this is the template used

variables:
- template: ../transversal/vars/vars-global.yaml

parameters:
- name: deliveryTrain
  type: object
- name: changeOrderHistoriasId
  type: string
  default: ''
- name: changeOrderApprover
  type: string
  default: ''
- name: changeOrderItemApproverBusiness
  type: string
  default: ''
- name: changeOrderRequester
  type: string
  default: ''

stages:
  - template: ../transversal/stages/continuous-integration.yaml
    parameters:
      continuousIntegration: ${{ parameters.deliveryTrain.continuousIntegration }}
  
  - ${{ if ne(variables['Build.Reason'],'PullRequest') }}:
    - ${{ if parameters.deliveryTrain.continuousDelivery }}:
      - template: ../transversal/stages/approvals.yaml
        parameters:
          deployment: ${{ parameters.deliveryTrain.continuousDelivery.deployment }}
              
      - template: ../transversal/stages/continuous-delivery.yaml
        parameters:
          continuousDelivery: ${{ parameters.deliveryTrain.continuousDelivery }}
          artifact: ${{ parameters.deliveryTrain.continuousIntegration.artifact }}
          changeOrderHistoriasId: ${{ parameters.changeOrderHistoriasId }}
          changeOrderApprover: ${{ parameters.changeOrderApprover }}
          changeOrderItemApproverBusiness: ${{ parameters.changeOrderItemApproverBusiness }}
          changeOrderRequester: ${{ parameters.changeOrderRequester }}
    
    - template: ../transversal/stages/continuous-testing.yaml
      ${{ each environment in parameters.deliveryTrain.continuousTesting }}:
        ${{ if or( and(contains(variables['Build.SourceBranch'], 'refs/pull/' ), eq( environment.environment, 'none') ), and( eq(variables['Build.SourceBranch'], 'refs/heads/develop' ), eq( environment.environment, 'dllo') ), and( contains(variables['Build.SourceBranch'], 'refs/heads/release' ), eq( environment.environment, 'labo') ), and( eq(variables['Build.SourceBranch'], 'refs/heads/master' ), eq( environment.environment, 'pdn') ), and( contains(variables['Build.SourceBranch'], 'refs/heads/feature/' ), eq( environment.environment, 'dllo') )) }}:
          parameters:
            continuousTesting: ${{ environment.cases }}
  
    - ${{ if or(parameters.deliveryTrain.continuousDelivery, parameters.deliveryTrain.continuousTesting ) }}:
      - template: ../transversal/stages/post-delivery.yaml
        parameters:
          deliveryTrain: ${{ parameters.deliveryTrain }}

Solution

  • Based on your YAML sample, I can reproduce the same issue.

    enter image description here

    I am afraid that the extends and the stages fields are not able to be defined at the same time in YAML Pipeline.

    To meet your requirement, you can change to use - template field to use the YAML template and define the stages at the same time.

    Update1:

    Based on your YAML sample, you can use the following YAML Pipeline YAML code:

    Main YAML:

    trigger:
      - none
    
    variables:
    - template: ../transversal/vars/vars-global.yaml  
    
    resources:
      repositories:
        - repository: back
          type: git
          name: Gerencia_Tecnologia/salud-mensajeria_dinamica-back-ml
          ref: feature/hu_comun_1707
        - repository: front
          type: git
          name: Gerencia_Tecnologia/salud-mensajeria_dinamica-fr
          ref: feature/hu-comun-tablas
        - repository: templates
          type: git
          name: Gerencia_Tecnologia/ti-templates_pipelines-conf
          ref: master
    
    parameters:
      - name: deliveryTrain
        type: object
        default:
          continuousIntegration:
            build:
              - with: gradle
                configure:
                  javaVersion: '1.8'
                  gradleExtraOptionsLabo: 'clean build'
                  workingDirectory: 'Gerencia_Tecnologia/salud-mensajeria_dinamica-back'
            artifact:
              with: 'artifactory'
              configure:
                artifactName: 'dinamica.md.ear'
          continuousDelivery:
            deployment:
              - environment: 'labo'
                platform:
                  with: 'weblogic'
                  configure:
                    serviceConnection: 'lab-Salud-wl-12.2.1.4'
          continuousTesting:
            - environment: 'labo'
              cases:
                - type: performance
                  with: 'jmeter'
                  configure:
                    repo:
                      name: 'Gerencia_Tecnologia/salud-mensajeria_dinamica-back-ml'
                      branch: 'feature/hu_comun_1707'
                    performanceTestFiles: 'jmeter/test/test.jmx'
                    performanceTestPercentilTest: '99'
                    performanceTestResultFiles: 'jmeter/test/result.jtl'
    
    stages:
      - stage: MensajeriaDinamicaFrontBuild
        displayName: 'MensajeriaDinamica-Front-build'
        jobs:
          - job: BuildFrontEnd
            displayName: 'Build Front Artifact'
            pool:
              name: 'linux-generic'
            steps:
              - checkout: front
              - task: NodeTool@0
                inputs:
                  versionSpec: '12.16.1'
                displayName: 'Install Node.js'
              - script: npm install -g @angular/cli@9.0.0
                displayName: 'Install Angular CLI'
              - script: |
                  npm install &&
                  ng build --aot --output-hashing=all --prod
                displayName: 'Built Front Artifact'
              - task: PublishPipelineArtifact@1
                displayName: 'Publish Front Artifact to dist carpet'
                inputs:
                  targetPath: '$(System.DefaultWorkingDirectory)/dist'
                  artifact: 'front-artifact'
              - task: CopyFiles@2
                displayName: 'Copy files to ArtifactStagingDirectory'
                inputs:
                  SourceFolder: '$(System.DefaultWorkingDirectory)/dist'
                  Contents: '**'  
                  TargetFolder: '$(Build.ArtifactStagingDirectory)'
              - task: PublishBuildArtifacts@1
                displayName: 'Publish front Artifact to ArtifactStagingDirectory'
                inputs:
                  pathToPublish: '$(Build.ArtifactStagingDirectory)'
                  artifactName: 'MensajeriaDinamicaFrontArtifact'  
    
          - job: CopyArtifactsToBack
            condition: succeeded('BuildFrontEnd')
            dependsOn: BuildFrontEnd
            displayName: 'Move Front Artifact to Back-End Repository'
            pool:
              name: 'linux-generic'
            steps:
                - checkout: back
                - script: |
                    rm -r $(Build.SourcesDirectory)/WAR_MensajeriaDinamica/WebContent/resultadosapp/* &&
                    echo "Listing the deleted folders file:"
                    ls -R $(Build.SourcesDirectory)/WAR_MensajeriaDinamica/WebContent/resultadosapp
                  displayName: 'cleaned back webcontent'
                - task: DownloadPipelineArtifact@2
                  inputs:
                    artifactName: 'MensajeriaDinamicaFrontArtifact' 
                    targetPath: '$(System.DefaultWorkingDirectory)/WAR_MensajeriaDinamica/WebContent/resultadosapp/'
                - script: |
                    echo "Listing the downloaded artifact:"
                    ls -R $(Build.SourcesDirectory)/WAR_MensajeriaDinamica/WebContent/resultadosapp
                - template: templates/gradle-weblogic.yaml@templates
                    
          - job: UsingTemplate
            displayName: 'Usar plantilla de gradle weblogic'
            steps:
              - checkout: templates
              - script: |
                  ls -R $(Build.SourcesDirectory)/templates
                displayName: 'List Files in Cloned Repositories'
    
    
    
    
      - template: 'templates/gradle-weblogic.yaml@templates'
        parameters:
          deliveryTrain: ${{ parameters.deliveryTrain }}
    

    Template YAML:

    parameters:
    - name: deliveryTrain
      type: object
    - name: changeOrderHistoriasId
      type: string
      default: ''
    - name: changeOrderApprover
      type: string
      default: ''
    - name: changeOrderItemApproverBusiness
      type: string
      default: ''
    - name: changeOrderRequester
      type: string
      default: ''
    
    stages:
      - template: ../transversal/stages/continuous-integration.yaml
        parameters:
          continuousIntegration: ${{ parameters.deliveryTrain.continuousIntegration }}
      
      - ${{ if ne(variables['Build.Reason'],'PullRequest') }}:
        - ${{ if parameters.deliveryTrain.continuousDelivery }}:
          - template: ../transversal/stages/approvals.yaml
            parameters:
              deployment: ${{ parameters.deliveryTrain.continuousDelivery.deployment }}
                  
          - template: ../transversal/stages/continuous-delivery.yaml
            parameters:
              continuousDelivery: ${{ parameters.deliveryTrain.continuousDelivery }}
              artifact: ${{ parameters.deliveryTrain.continuousIntegration.artifact }}
              changeOrderHistoriasId: ${{ parameters.changeOrderHistoriasId }}
              changeOrderApprover: ${{ parameters.changeOrderApprover }}
              changeOrderItemApproverBusiness: ${{ parameters.changeOrderItemApproverBusiness }}
              changeOrderRequester: ${{ parameters.changeOrderRequester }}
        
        - template: ../transversal/stages/continuous-testing.yaml
          ${{ each environment in parameters.deliveryTrain.continuousTesting }}:
            ${{ if or( and(contains(variables['Build.SourceBranch'], 'refs/pull/' ), eq( environment.environment, 'none') ), and( eq(variables['Build.SourceBranch'], 'refs/heads/develop' ), eq( environment.environment, 'dllo') ), and( contains(variables['Build.SourceBranch'], 'refs/heads/release' ), eq( environment.environment, 'labo') ), and( eq(variables['Build.SourceBranch'], 'refs/heads/master' ), eq( environment.environment, 'pdn') ), and( contains(variables['Build.SourceBranch'], 'refs/heads/feature/' ), eq( environment.environment, 'dllo') )) }}:
              parameters:
                continuousTesting: ${{ environment.cases }}
      
        - ${{ if or(parameters.deliveryTrain.continuousDelivery, parameters.deliveryTrain.continuousTesting ) }}:
          - template: ../transversal/stages/post-delivery.yaml
            parameters:
              deliveryTrain: ${{ parameters.deliveryTrain }}
    

    For more detailed info, you can refer to the doc: Template usage reference