0

I have this pipeline (non relevant parts removed):

stages:
  - stage: 'PreSteps'
    displayName: 'Preparation Steps'
    jobs:
    - job: 'Check_changes'
      steps:
        - task: Bash@3
          name: 'bash_script1'
          inputs:
            targetType: 'inline'
            script: |
              # do some stuff
              
              echo "##vso[task.setvariable variable=SomeVariable_1;isOutput=True]SomeValue_1"
              echo "##vso[task.setvariable variable=SomeVariable_2;isOutput=True]SomeValue_2"
              echo "##vso[task.setvariable variable=SomeVariable_3;isOutput=True]SomeValue_3"
              echo "##vso[task.setvariable variable=SomeVariable_4;isOutput=True]SomeValue_4"
              echo "##vso[task.setvariable variable=Changes;isOutput=True]4"

  - stage: 'S_Build'
    dependsOn: 'PreSteps'
    condition: gt(dependencies.PreSteps.outputs['Check_changes.bash_script1.Changes'], 0)
    displayName: 'Build and Publish Changed Projects'
    variables:
      Project_1: $[ stageDependencies.PreSteps.Check_changes.outputs['bash_script1.SomeVariable_1'] ]
      Project_2: $[ stageDependencies.PreSteps.Check_changes.outputs['bash_script1.SomeVariable_2'] ]
      Project_3: $[ stageDependencies.PreSteps.Check_changes.outputs['bash_script1.SomeVariable_3'] ]
      Project_4: $[ stageDependencies.PreSteps.Check_changes.outputs['bash_script1.SomeVariable_4'] ]
    jobs:
    - template: build.yml
      parameters:
        Projects:
        - $(Project_1)
        - $(Project_2)
        - $(Project_3)
        - $(Project_4)

  - stage: 'D_Release'
    dependsOn:
      - 'S_Build'
      - 'PreSteps'
    condition: eq(stageDependencies.S_Build.result, 'Succeeded')
    displayName: 'Release Changed Projects to DEV'
    variables:
      Project_1: $[ stageDependencies.PreSteps.Check_changes.outputs['bash_script1.SomeVariable_1'] ]
      Project_2: $[ stageDependencies.PreSteps.Check_changes.outputs['bash_script1.SomeVariable_2'] ]
      Project_3: $[ stageDependencies.PreSteps.Check_changes.outputs['bash_script1.SomeVariable_3'] ]
      Project_4: $[ stageDependencies.PreSteps.Check_changes.outputs['bash_script1.SomeVariable_4'] ]
    jobs:
    - template: release.yml
      parameters:
        Projects:
        - $(Project_1)
        - $(Project_2)
        - $(Project_3)
        - $(Project_4)

  - stage: 'P_Release'
    dependsOn:
      - 'D_Release'
      - 'PreSteps'
    condition: eq(stageDependencies.D_Release.result, 'Succeeded')
    displayName: 'Release Changed Projects to PROD'
    variables:
      Project_1: $[ stageDependencies.PreSteps.Check_changes.outputs['bash_script1.SomeVariable_1'] ]
      Project_2: $[ stageDependencies.PreSteps.Check_changes.outputs['bash_script1.SomeVariable_2'] ]
      Project_3: $[ stageDependencies.PreSteps.Check_changes.outputs['bash_script1.SomeVariable_3'] ]
      Project_4: $[ stageDependencies.PreSteps.Check_changes.outputs['bash_script1.SomeVariable_4'] ]
    jobs:
    - template: release.yml
      parameters:
        Projects:
        - $(Project_1)
        - $(Project_2)
        - $(Project_3)
        - $(Project_4)

Basically I'm generating some values in bash_script1 which I need to use across all the stages. Is there a way to avoid repeating the variables in each stage? I can't use the syntax $[ ] directly in the parameters as they don't get expanded in the template.

goosseno
  • 145
  • 2
  • 12

1 Answers1

1

You can use runtime parameters to simplify above yaml pipeline. Please check out below steps:

1, Define the stage name and template in the runtime parameters section:

parameters:
- name: Stages
  type: object
  default:
  - StageName: S_Build
    Template: build.yml 
    Depends: PreSteps
  - StageName: D_Release
    Template: release.yml
    Depends: S_Build
  - StageName: P_Release
    Template: release.yml
    Depends: D_Release

2, Using ${{...}} expression to loop through the Stages parameters: See below full example:

parameters:
- name: Stages
  type: object
  default:
  - StageName: S_Build
    Template: build.yml 
    Depends: PreSteps
  - StageName: D_Release
    Template: release.yml
    Depends: S_Build
  - StageName: P_Release
    Template: release.yml
    Depends: D_Release

trigger: none
#
stages:
- stage: PreSteps
  jobs: 
  - job: Check_changes
    steps:
    - task: Bash@3
      name: 'bash_script1'
      inputs:
        targetType: 'inline'
        script: |
          # do some stuff
          
          echo "##vso[task.setvariable variable=SomeVariable_1;isOutput=True]SomeValue_1"
          echo "##vso[task.setvariable variable=SomeVariable_2;isOutput=True]SomeValue_2"
          echo "##vso[task.setvariable variable=SomeVariable_3;isOutput=True]SomeValue_3"
          echo "##vso[task.setvariable variable=SomeVariable_4;isOutput=True]SomeValue_4"
          echo "##vso[task.setvariable variable=Changes;isOutput=True]4"

- ${{each stage in parameters.Stages}}:    
  - stage: ${{stage.StageName}}
    variables:
      Project_1: $[ stageDependencies.PreSteps.Check_changes.outputs['bash_script1.SomeVariable_1'] ]
      Project_2: $[ stageDependencies.PreSteps.Check_changes.outputs['bash_script1.SomeVariable_2'] ]
      Project_3: $[ stageDependencies.PreSteps.Check_changes.outputs['bash_script1.SomeVariable_3'] ]
      Project_4: $[ stageDependencies.PreSteps.Check_changes.outputs['bash_script1.SomeVariable_4'] ]
    dependsOn: 
    - ${{stage.Depends}}
    ${{ if eq(stage.StageName, 'S_Build') }}: 
      condition: gt(dependencies.PreSteps.outputs['Check_changes.bash_script1.Changes'], 0)
    ${{ if ne(stage.StageName, 'S_Build') }}:
      condition: succeeded('${{stage.Depends}}')
    jobs:
    - template: ${{stage.Template}}
      parameters:
        Projects:
        - $(Project_1)
        - $(Project_2)
        - $(Project_3)
        - $(Project_4)
Levi Lu-MSFT
  • 27,483
  • 2
  • 31
  • 43