如何简化 Azure 管道并避免重复

How to simplify Azure pipeline and avoid to much repeating

我有这个管道(删除了不相关的部分):

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)

基本上我在 bash_script1 中生成了一些我需要在所有阶段使用的值。 有没有办法避免在每个阶段重复变量?我不能在参数中直接使用语法 $[ ],因为它们不会在模板中展开。

您可以使用 runtime parameters 来简化上述 yaml 管道。请查看以下步骤:

1、在运行时参数部分定义阶段名称和模板:

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、使用${{...}}表达式循环阶段参数:参见下面的完整示例:

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)