首页 > 解决方案 > Azure DevOps 多阶段管道卡在等待批准

问题描述

我在 Azure Git Repos 中使用托管的 Azure DevOps 和我们的代码。我们曾经使用“经典”的基于 UI 的管道编辑器,但正在为我们的构建/发布阶段迁移到 YAML 模板。

过去,我配置了 CI/CD,以便当代码通过拉取请求提交到主分支时,它会触发构建,然后触发开发部署。在代码移至该阶段之前,其他发布阶段将等待批准。新版本将取消尚未部署到各自环境的任何先前版本。

对于 YAML 部署阶段,我发现当主分支触发构建时,它会部署到开发环境,但由于其他阶段尚未获得批准,因此管道处于等待状态。结果,运行没有被标记为“完成”,最终其他阶段将超时并被标记为失败。此外,管道的先前运行不会被取消,因此多个运行堆叠在等待状态。

理想情况下,我希望看到新构建将取消管道的所有先前运行。一旦部署到开发,我希望看到运行标记为“完成”,并且能够在事后手动部署到其他阶段。

还有其他人想做同样的事情吗?我只是在想这一切都是错的,应该以不同的方式来做吗?

标签: azure-devopsyaml

解决方案


yaml 管道目前不支持手动部署到阶段。请检查这个未解决的问题

您可以尝试为每个阶段添加dependsOn条件。对于以下示例 yaml 管道。Stage Build只有在 Stage Start成功完成后才会开始运行,然后 Stage Build 将等待批准,Stage Release 直到 Stage Build 获得批准并成功完成后才会触发。

您可以定义 pr 触发器并设置autocancel=true(默认为 true)以在将新更改推送到同一 pr 时取消以前的运行。

批处理属性trigger可以达到类似的效果。如果当前 pr 仍在构建中,它将不会开始新的运行。

trigger:
  batch: boolean # batch changes if true (the default); start a new build for every push if false
  branches:
    include:

_

pr:
  autoCancel: true
  branches:
    include:
    - master

stages:
- stage: Start
  jobs:
    - job: A
      pool:
        vmImage: windows-latest
      steps:
      - powershell: |
          echo "i am job a"

- stage: Build
  dependsOn: Start
  condition: succeeded()
  jobs:
  - deployment: Dev
    displayName: deploy Web App
    pool:
      vmImage: 'Ubuntu-16.04'
  # creates an environment if it doesn't exist
    environment: 'Dev'
    strategy:
    # default deployment strategy, more coming...
      runOnce:
        deploy:
          steps:
          - script: echo "i am dev environment"


- stage: Release
  dependsOn: Build
  condition: succeeded()
  jobs:
  - deployment: Environ
    displayName: deploy Web App
    pool:
      vmImage: 'Ubuntu-16.04'
  # creates an environment if it doesn't exist
    environment: 'Environment'
    strategy:
    # default deployment strategy, more coming...
      runOnce:
        deploy:
          steps:
          - script: echo "i am Environment environment"

更新:通过 powershell 脚本取消正在进行的构建

您可以在管道顶部添加一个 powershell 任务来调用build api。下面的脚本获取所有正在进行的构建并取消它们,但当前构建除外。

- task: PowerShell@2

      inputs:
        targetType: inline
        script: |

          $header = @{ Authorization = "Bearer $(system.accesstoken)" }
          $buildsUrl = "$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_apis/build/builds?api-version=5.1"
          echo $buildsUrl
          $builds = Invoke-RestMethod -Uri $buildsUrl -Method Get -Header $header

          $buildsToStop = $builds.value.Where({ ($_.status -eq 'inProgress') -and ($_.definition.name -eq "$(Build.DefinitionName)") -and ($_.id -ne $(Build.BuildId))})

          ForEach($build in $buildsToStop)
          {
            echo $build.id
            $build.status = "cancelling"
            $body = $build | ConvertTo-Json -Depth 10
            $urlToCancel = "$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_apis/build/builds/$($build.id)?api-version=5.1"
            echo $urlToCancel
            Invoke-RestMethod -Uri $urlToCancel -Method Patch -ContentType application/json -Body $body -Header $header
          }

为了让您的管道有权取消当前正在运行的构建。您需要转到您的管道,单击 3dots 并选择 Manage security

在此处输入图像描述

然后将Stop build的权限设置为 Allow for user Project Collection Build Service(projectName),

在此处输入图像描述


推荐阅读