Azure DevOps YAML管道按需预部署审批问题与解决方案
Azure DevOps YAML管道灵活审批方案
问题背景
我们正调研将Azure DevOps经典构建与发布流程迁移至YAML管道,需部署至dev、test、acc、prod四个环境。日常需验证未合并至main分支的特性(即部署特性分支至dev/test),但main分支更新时会自动部署至dev/test,打断特性测试。经典管道中我们通过临时添加预部署审批解决此问题,但YAML管道无独立的预/后部署审批,只能为整个环境添加审批——这会阻塞10-20个持续部署至dev/test的管道,手动审批无关部署极为繁琐。
我们发现ManualValidation@0任务可能解决该问题,但存在挑战:需默认跳过,仅在环境变量或库变量触发时激活,且每个管道添加该步骤会导致配置臃肿,因此寻求更优方案。
解决方案(基于@Alvin Zhao - MSFT建议)
由于公司多个网站部署流程基本一致,我们搭建了存储共享步骤的Git仓库,通过模板化实现灵活的按需审批。
部署模板片段(deploy-website.yml)
# file deploy-website.yml parameters: # 省略部分参数 - name: preDeployApproversVariable # POI 1 type: string default: '' - name: postDeployApprovalVariable type: string default: '' jobs: - ${{ if ne(parameters.preDeployApproversVariable, '')}}: # POI 2 - template: wait-for-manual-approval.yml parameters: jobName: AwaitPreDeployApproval approvers: ${{parameters.preDeployApproversVariable}} instructions: 请批准或拒绝本次部署 dependsOn: [] # POI 3 - deployment: WebDeployment ${{ if ne(parameters.preDeployApproversVariable,'') }}: # POI 4 dependsOn: [AwaitPreDeployApproval] strategy: runOnce: # 此处为实际部署步骤 steps: - script: echo 执行部署操作 - ${{ if ne(parameters.postDeployApprovalVariable, '')}}: - template: wait-for-manual-approval.yml parameters: jobName: AwaitPostDeployApproval approvers: ${{parameters.postDeployApprovalVariable}} instructions: 请批准或拒绝后续操作 dependsOn: - WebDeployment
部署模板关键要点(POI)
- POI 1:参数
preDeployApproversVariable和postDeployApprovalVariable存储变量组中变量的名称,不得直接填写变量值。 - POI 2:若调用该模板的管道未指定预/后部署审批参数,
wait-for-manual-approval.yml模板不会出现在编译后的管道中。 - POI 3:
wait-for-manual-approval.yml模板要求必填dependsOn参数,预审批可设为空数组,后审批建议指定依赖的部署作业。 - POI 4:
WebDeployment作业会根据条件依赖预审批作业,确保审批通过后才执行部署。
手动审批模板(wait-for-manual-approval.yml)
# File: wait-for-manual-approval.yml parameters: - name: jobName # POI 5 type: string - name: approvers type: string - name: instructions type: string default: '请批准或拒绝' - name: dependsOn type: object default: [] jobs: - job: '${{parameters.jobName}}' ${{ if ne(length(parameters.dependsOn), 0)}}: # POI 6 dependsOn: ${{parameters.dependsOn}} pool: server timeoutInMinutes: 60 steps: - task: ManualValidation@0 condition: ne(variables['${{parameters.approvers}}'], '') # POI 7 inputs: notifyUsers: | $(${{parameters.approvers}}) # POI 8 instructions: ${{parameters.instructions}} onTimeout: reject
手动审批模板关键要点
- POI 5:作业名称为模板输入参数,支持在同一阶段多次引用该模板实现多环节审批。
- POI 6:通过条件依赖确保后审批作业仅在部署完成后启动。
- POI 7:
approvers参数在编译时展开,因此必须传入变量组中变量的名称。若变量组中该变量值为空,则不满足条件,ManualValidation@0任务会自动跳过。 - POI 8:使用宏语法
$()从变量组中获取审批人的实际值。
最终管道引用示例
# 省略其他配置 resources: repositories: - repository: CommonTemplates type: git name: Git_repo_name # 替换为实际共享模板仓库名称 stages: - stage: Development jobs: - template: deploy-website.yml@CommonTemplates parameters: preDeployApproversVariable: PreDeployApproverApp1 # 变量组中预审批人变量名称 postDeployApprovalVariable: PostDeployApproverApp1 # 变量组中后审批人变量名称
内容的提问来源于stack exchange,提问作者SimonAx
相关产品推荐
相关产品推荐

