在 Azure DevOps Yaml 作业中动态填充 DependsOn

问题描述 投票:0回答:1

YAML 管道不支持可动态添加的部署前和部署后批准。我找到了一种部分实现此目标的方法,请参阅我之前的SO问题的最终更新。总之;我创建了一个包含 3 个作业的 YAML 模板;第一个和最后一个作业是根据变量组中的变量使用

ManualValidation@0
的条件作业,第二个作业是 Web 应用程序的实际部署。

下一步是通过引入 YAML 模板来使这种方法更加通用,该模板采用

jobList 
作为参数,并有条件地插入预部署和部署后作业。这个模板看起来像

# File: deploy.yml
parameters:
- name: preDeployApprovers
  type: string
  default: ''
- name: postDeployApprovers
  type: string
  default: ''
- name: deployJobs
  type: jobList
  default: []

jobs:
  - ${{ if ne(parameters.preDeployApprovers, '')}}:
    - template: wait-for-manual-approval.yml
      parameters:
        jobName: AwaitPreDeployApproval
        approvers: ${{parameters.preDeployApprovers}}
        instructions: Approve or reject.
        dependsOn:
    
    # Inspired by 
    # https://stackoverflow.com/questions/63256692/is-it-possible-to-pass-a-template-with-a-list-of-jobs-to-a-joblist-type-param
  - ${{ each job in parameters.deployJobs }}:  
    - ${{ each pair in job }}:
        ${{ if ne(pair.key, 'steps') }}:
          ${{ pair.key }}: ${{ pair.value }}
      ${{ if ne(parameters.preDeployApprovers, '')}}:
        dependsOn: [AwaitPreDeployApproval] # POI 1
      steps:
      - ${{ job.steps }} 
      
  - ${{ if ne(parameters.postDeployApprovers, '')}}:
    - template: wait-for-manual-approval.yml
      parameters:
        jobName: AwaitPostDeployApproval
        approvers: ${{parameters.postDeployApprovers}}
        instructions: Approve or reject.
        dependsOn: ${{join(',',parameters.deployJobs)}} # POI 2. Current solution does NOT work

引用 wait-for-manual-approval.yml:

#File: wait-for-manual-approval.yml
parameters:
  - name: jobName
    type: string
  - name: approvers
    type: string
    default: ''
  - name: instructions
    type: string
    default: 'Approve or reject'
  - name: dependsOn
    type: object
    default: []
  
jobs:
  - job: ${{parameters.jobName}}
    ${{ if parameters.dependsOn }}:
      dependsOn: ${{ parameters.dependsOn }}
    displayName: Wait for manual approval after deployment
    pool: server
    timeoutInMinutes: 240 #4 hours. 
   
    steps:
    - task: ManualValidation@0        
      condition: ne(variables['${{parameters.approvers}}'], '')
      inputs:
        notifyUsers: |
          $(${{parameters.approvers}})
        instructions: ${{parameters.instructions}}
        onTimeout: reject

兴趣点 (POI) 是

  • POI 1:部署前批准将根据参数
    preDeployApprovers
    添加到扩展模板中。如果此参数具有非默认值,则实际部署作业必须等待预部署批准('AwaitPreDeployApproval')完成,因此存在条件
    dependsOn
    。这种方法基于不同的SO问题的答案。
  • POI 2:部署后批准必须等待所有其他作业。

dependsOn
作为参数提供给 wait-for-manual-approval.yml 的方式深受这篇文章的启发。

兴趣点2是我头疼的根源,它不起作用。在我下载的扩展模板中,没有针对部署后作业的

dependsOn
语句。我已经尝试过对其中一个作业的名称进行硬编码并且可行,但是为了使这样的模板有用,我需要一种方法来提取
deployJobs
参数中的作业名称。有什么建议吗?

azure-devops azure-pipelines azure-pipelines-yaml
1个回答
2
投票

正如 @Alvin Zhu - MSFT 所提到的,如果您的作业有多个依赖项,则

dependsOn
属性应该是一个数组
[]
而不是字符串。

在这种情况下不能使用

join 函数,因为:

  • 它返回单个字符串,而不是数组
  • 作业等复杂对象会转换为空字符串

所以代替:

dependsOn: ${{join(',',parameters.deployJobs)}}

尝试使用过滤数组

dependsOn: ${{ parameters.deployJobs.*.job }}

说明:

  • parameters.deployJobs.*.job
    告诉系统将
    parameters.deployJobs
    作为过滤数组进行操作,然后选择
    job
    属性

完整的工作示例

trigger: none

parameters:
  - name: deployJobs
    type: jobList
    default:
      - job: A
        displayName: Job A
        steps:
          - script: echo "Hello from Job A"
      - job: B
        displayName: Job B
        steps:
          - script: echo "Hello from Job B"
      - job: C
        displayName: Job C
        steps:
          - script: echo "Hello from Job C"

jobs:
  - ${{ parameters.deployJobs }}

  - job: D
    displayName: Job D
    dependsOn: ${{ parameters.deployJobs.*.job }}
    steps:
      - script: echo "Hello from Job D"
© www.soinside.com 2019 - 2024. All rights reserved.