user3067684
user3067684

Reputation: 1258

Azure Devops pipeline yml looping over stages

How can i loop over an array or through an object to create stages?

Below is a yml file that works. You can see the build stage loops over the parameters environments for jobs. IS it possible to achieve the same thing for the publishing stages?

The publishing stages require manual approval, must run in order and only when the previous stage is successfully complete?

parameters:
  - name: 'environments'
    type: object
    default: 
      - environment: development
        variableGroup: strata2-admin-spa-vg
        dependsOn: 'build'
      - environment: test
        variableGroup: strata2-test-admin-spa-vg
        dependsOn: 'development'
      - environment: production
        variableGroup: strata2-development-variables
        dependsOn: 'development'
  - name: 'buildTemplate'
    type: string
    default: buildTemplate.yml
  - name: 'publishTemplate'
    type: string
    default: publishTemplate.yml

trigger:
  - main

pool:
  vmImage: ubuntu-latest

stages:
  
  - stage: build
    displayName: Build stage
    jobs: 


# Can I do this for stages?
      - ${{each build in parameters.environments}}:
        - template: ${{parameters.buildTemplate}}
          parameters:
            environment: ${{build.environment}}
            variableGroup: ${{build.variableGroup}}


# How to loop over parameters.environments to dynamically create stages
  - stage: Publish_Development
    displayName: Publish development environment
    dependsOn: build
    jobs:
      - template: ${{parameters.publishTemplate}}
        parameters:
          environment: Development_websites
          variableGroup: strata2-admin-spa-vg

  - stage: Publish_Test
    displayName: Publish test environment
    dependsOn: Publish_Dev
    jobs:
      - template: ${{parameters.publishTemplate}}
        parameters:
          environment: Test_websites
          variableGroup: strata2-test-admin-spa-vg

  - stage: Publish_Production
    displayName: Publish production environment
    dependsOn: Publish_Test
    jobs:
      - template: ${{parameters.publishTemplate}}
        parameters:
          environment: Production_websites
          variableGroup: strata2-development-variables

Upvotes: 10

Views: 9761

Answers (3)

Andrew Haigh
Andrew Haigh

Reputation: 79

While the accepted answer is correct - it's not as clear as it could be - it took me a bit of fiddling about before I got it to work correctly

Here's how I got the loop running

parameters:
  - name: stages
    type: object
    default:
      - stage: Sandbox
        dependsOn: Build
      - stage: Dev
        dependsOn: DeploySandbox    
      - stage: PreProd
        dependsOn: Build
      - stage: Prod
        dependsOn: DeployPreProd

stages:
  - stage: Build
    displayName: Build
    jobs:
    - job:
      displayName: Build_Job

  - ${{ each stage in parameters.stages }} :
      - stage: Deploy${{ stage.stage }}
        displayName: Deploy ${{ stage.stage }} Environment
        dependsOn: ${{ stage.dependsOn }}
        variables:
          - name: system. Debug
            value: true
        jobs:
        - job: 
          displayName: "${{ stage.stage }}"
          steps:
            - script: echo Hello, world!
              displayName: 'Deploying to ${{ stage.stage }}'

I'll be using this to dramatically reduce duplication in my pipelines from here on, and hopefully this will help someone get up to speed a little faster

Cheers

-=A=-

.

Upvotes: 7

DarrenS
DarrenS

Reputation: 70

Managed to get this working for myself. Stages automatically generated based on numerical batch numbers, that run in parallel. Hope it helps someone out there.

- name: batches
  displayName: BATCH
  type: object
  default:
  - 1
  - 2
  - 3

stages:
- ${{ each stage in parameters.batches }}:
  - stage: BATCH_${{ stage }} 
    dependsOn: []
    jobs:
      - job: PREP
        steps:
        - template: install.yml

      - job: RUN
        dependsOn: PREP
        timeoutInMinutes: 300
        steps:
        - template: run.yml
          parameters: 
            batch: ${{ stage }}

Would be nice if the batch numbers weren't displayed as an editable box when running the pipeline from Azure DevOps. I tried setting them as fixed values, but couldn't get that to work, so this is what I went with in the end.

Upvotes: 1

Dejulia489
Dejulia489

Reputation: 1295

You can create a stages object the same way you created the environments object.

stages: 
  Publish_Development:
   - stage: Publish_Development
   - displayName: Publish development environment
   - dependsOn: 
   - ... 
  Publish_Test
   - stage: Publish_Development
   - ...

Then you can loop over the stages object like you did with environments.

- ${{each stage in parameters.stages}}:
  - stage: ${{ stage.stage }} 
    displayName: ${{ stage.displayName}} 
    dependsOn: ${{ stage.dependsOn}} 
    ...

Upvotes: 3

Related Questions