如何在Azure DevOps YAML任务中动态填充DependsOn?
动态添加部署前后审批环节的YAML流水线通用方案问题
我正在实现YAML流水线的通用化模板,支持按需插入部署前后的手动审批环节。目前已完成基础逻辑:通过变量组控制首尾的审批任务,中间放置实际部署任务。现在要进一步通用化,让模板接收jobList类型的参数,实现动态插入前后置审批。
以下是当前的模板代码:
deploy.yml
# 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: # 遍历传入的部署任务列表 - ${{ 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:当前方案无效
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小时超时 steps: - task: ManualValidation@0 condition: ne(variables['${{parameters.approvers}}'], '') inputs: notifyUsers: | $(${{parameters.approvers}}) instructions: ${{parameters.instructions}} onTimeout: reject
关键关注点
- POI 1:当
preDeployApprovers参数非空时,所有部署任务会自动依赖前置审批任务AwaitPreDeployApproval,此逻辑已正常工作。 - POI 2:后置审批任务需要等待所有部署任务完成,但当前使用
${{join(',',parameters.deployJobs)}}设置dependsOn的方案无效,展开后的模板中后置审批任务没有dependsOn语句。硬编码任务名称可以正常运行,但需要自动提取deployJobs参数中所有任务名称的方法。
解决方案
要解决POI 2的问题,需要从deployJobs的每个任务对象中提取任务名称,再将这些名称组成数组作为dependsOn的值。
修改deploy.yml中的后置审批部分
将原来的dependsOn: ${{join(',',parameters.deployJobs)}}替换为以下表达式,通过map和keys函数提取每个任务的名称:
dependsOn: ${{ map(parameters.deployJobs, (job) => keys(job)[0]) }}
修改后的后置审批代码片段:
- ${{ if ne(parameters.postDeployApprovers, '')}}: - template: wait-for-manual-approval.yml parameters: jobName: AwaitPostDeployApproval approvers: ${{parameters.postDeployApprovers}} instructions: Approve or reject. dependsOn: ${{ map(parameters.deployJobs, (job) => keys(job)[0]) }}
可选优化:保留部署任务原有依赖(针对POI 1)
如果传入的部署任务本身已有dependsOn配置,当前POI 1的写法会覆盖原有依赖。可以修改为合并原有依赖和前置审批任务:
- ${{ each job in parameters.deployJobs }}: - ${{ each pair in job }}: ${{ if ne(pair.key, 'steps') }}: ${{ pair.key }}: ${{ pair.value }} ${{ if ne(parameters.preDeployApprovers, '')}}: dependsOn: ${{ if job.dependsOn }}: ${{ each dep in job.dependsOn }}: - ${{ dep }} - AwaitPreDeployApproval steps: - ${{ job.steps }}
这样既保留了部署任务原有的依赖关系,又添加了对前置审批任务的依赖。
内容的提问来源于stack exchange,提问作者SimonAx
相关产品推荐
相关产品推荐

