You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure DevOps中触发CD流水线前能否合并同提交的多个CI构建?

该需求完全可以实现,可通过以下配置完成:

核心配置步骤

1. 开启CD流水线资源触发的批处理能力

修改CD-Pipeline.yml中的资源触发配置,新增batch: true参数,该参数会自动合并同一分支的多个触发请求,避免多CI同时完成时重复触发CD:

resources:
  pipelines:
  - pipeline: databasepipeline
    source: CI-Database
    trigger: 
      branches:
        include: 
        - main
      batch: true # 新增配置
  - pipeline: dotnetpipeline
    source: CI-Dotnet
    trigger: 
      branches:
        include: 
        - main
      batch: true # 新增配置

2. 给CI流水线增加提交标识标签

在两条CI流水线的步骤末尾新增打标签步骤,将当前代码提交的SHA作为标签附加到CI构建上,方便后续CD校验:

# CI-Database.yml和CI-Dotnet.yml都添加以下步骤
- pwsh: |
    Write-Host "##vso[build.addbuildtag]Commit_$(Build.SourceVersion)"
  displayName: 绑定提交SHA标签

3. CD流水线新增前置CI完成校验阶段

在CD的部署阶段前增加校验逻辑,确认同一提交SHA对应的两条CI都已构建成功后再执行部署,避免单CI完成就触发部署的问题:

# 加到CD-Pipeline.yml的stages最前方
- stage: CheckCICompleted
  displayName: 校验同提交CI构建状态
  jobs:
  - job: CheckStatus
    timeoutInMinutes: 10 # 可根据CI平均执行时长调整
    steps:
    - pwsh: |
        $commitSha = "$(Build.SourceVersion)"
        $orgUri = "$(System.CollectionUri)"
        $project = "$(System.TeamProject)"
        $header = @{Authorization = "Bearer $(System.AccessToken)"}

        # 校验Database CI是否完成
        $dbPipeId = (Invoke-RestMethod -Uri "$orgUri/$project/_apis/pipelines?name=CI-Database&api-version=7.1-preview.1" -Headers $header).value.id
        $dbBuilds = (Invoke-RestMethod -Uri "$orgUri/$project/_apis/build/builds?definitions=$dbPipeId&branchName=refs/heads/main&resultFilter=succeeded&tagFilters=Commit_$commitSha&api-version=7.1-preview.6" -Headers $header).value

        # 校验Dotnet CI是否完成
        $dotnetPipeId = (Invoke-RestMethod -Uri "$orgUri/$project/_apis/pipelines?name=CI-Dotnet&api-version=7.1-preview.1" -Headers $header).value.id
        $dotnetBuilds = (Invoke-RestMethod -Uri "$orgUri/$project/_apis/build/builds?definitions=$dotnetPipeId&branchName=refs/heads/main&resultFilter=succeeded&tagFilters=Commit_$commitSha&api-version=7.1-preview.6" -Headers $header).value

        # 未完成则等待重试
        $retry = 0
        while($dbBuilds.Count -eq 0 -or $dotnetBuilds.Count -eq 0) {
          if($retry -gt 10) {
            Write-Error "CI构建等待超时,存在未完成的关联CI"
            exit 1
          }
          Start-Sleep -Seconds 30
          $dbBuilds = (Invoke-RestMethod -Uri "$orgUri/$project/_apis/build/builds?definitions=$dbPipeId&branchName=refs/heads/main&resultFilter=succeeded&tagFilters=Commit_$commitSha&api-version=7.1-preview.6" -Headers $header).value
          $dotnetBuilds = (Invoke-RestMethod -Uri "$orgUri/$project/_apis/build/builds?definitions=$dotnetPipeId&branchName=refs/heads/main&resultFilter=succeeded&tagFilters=Commit_$commitSha&api-version=7.1-preview.6" -Headers $header).value
          $retry++
        }

        # 输出可用的CI构建ID,后续部署可直接拉取对应构件
        Write-Host "##vso[task.setvariable variable=dbBuildId;isOutput=true]$($dbBuilds[0].id)"
        Write-Host "##vso[task.setvariable variable=dotnetBuildId;isOutput=true]$($dotnetBuilds[0].id)"
      name: GetValidCIBuilds
      displayName: 校验CI完成状态

4. 新增幂等校验避免重复部署

在部署步骤开头增加已部署校验,已经完成部署的提交直接跳过,彻底杜绝重复部署问题:

# 加到DeployDEV阶段的steps最前方
- pwsh: |
    $commitSha = "$(Build.SourceVersion)"
    $header = @{Authorization = "Bearer $(System.AccessToken)"}
    $deployedBuilds = (Invoke-RestMethod -Uri "$(System.CollectionUri)/$(System.TeamProject)/_apis/build/builds?definitions=$(System.DefinitionId)&branchName=refs/heads/main&resultFilter=succeeded&tagFilters=Deployed_$commitSha&api-version=7.1-preview.6" -Headers $header).value
    if($deployedBuilds.Count -gt 0) {
      Write-Host "当前提交已完成部署,直接跳过"
      exit 0
    }
    # 部署成功后打标签标记
    Write-Host "##vso[build.addbuildtag]Deployed_$commitSha"
  displayName: 重复部署校验

简化替代方案

如果项目规模不大,也可以直接将两条CI合并为一条流水线,用并行Job分别执行Database和Dotnet的构建,全部Job执行完成后直接触发CD,无需额外校验逻辑,实现成本更低。


内容的提问来源于stack exchange,提问作者David C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 15:54:02