Azure devops Azure DevOps多级管道在等待批准时卡住

Azure devops Azure DevOps多级管道在等待批准时卡住,azure-devops,yaml,Azure Devops,Yaml,我在Azure Git Repos中使用托管Azure DevOps和我们的代码。我们过去使用“经典”的基于UI的管道编辑器,但现在正在为构建/发布阶段使用YAML模板 在过去,我配置了CI/CD,这样当代码通过pull请求提交到主分支时,它将启动构建,然后启动开发部署。其他发布阶段将在代码移动到该阶段之前等待批准。新版本将取消所有尚未部署到各自环境中的早期版本 对于YAML部署阶段,我发现当主分支触发构建时,它会部署到开发环境中,但管道处于等待状态,因为其他阶段尚未得到批准。因此,运行没有标记

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

在过去,我配置了CI/CD,这样当代码通过pull请求提交到主分支时,它将启动构建,然后启动开发部署。其他发布阶段将在代码移动到该阶段之前等待批准。新版本将取消所有尚未部署到各自环境中的早期版本

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

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


还有其他人想做同样的事情吗?我是不是认为这一切都错了,应该换一种方式来做呢?

yaml管道目前不支持手动部署到阶段。请检查这个

您可以尝试为每个阶段添加和。例如下面的yaml管道。阶段构建只有在阶段启动成功完成后才会开始运行,然后阶段构建将等待批准,直到阶段构建获得批准并成功完成后才会触发阶段发布

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

触发器的属性可以实现类似的效果。如果当前pr仍在构建中,则不会开始新的运行

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

更新:


您可以在管道顶部添加powershell任务以调用。下面的脚本获取所有正在进行的生成,并取消它们(当前生成除外)

- 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
          }
以使管道具有取消当前正在运行的生成的权限。您需要转到管道,单击3dot并选择管理安全性

然后设置停止生成s权限以允许用户项目集合生成服务(projectName),


我对这个问题研究了一段时间,我认为有更好的解决办法


请参见我对类似问题的回答:

我目前确实在阶段之间存在依赖关系。开发阶段取决于构建阶段,测试阶段取决于开发阶段。批准是在测试阶段建立的,但不是在开发阶段。结果是,每次合并PR时,它都部署到开发中,但等待测试阶段的批准。由于PR经常发生,这导致大量管道运行等待批准。这些不会自动取消,最终会超时。此外,我发现代码覆盖率选项卡从未显示,因为运行从未标记为完成。您可以在触发器中尝试批处理属性,或使用pr触发器。我更新了上面的答案。我不确定这正是我想要的。对于PR触发器(不是Azure Repos的选项),它仅取消同一PR的以前运行。批处理选项(默认情况下为true)看起来只是减少了运行次数,但没有取消以前的所有运行。您可以将powershell任务添加到管道顶部。powershell任务在执行以下任务之前运行脚本以取消正在进行的生成。请检查上面的更新。这正越来越接近我想要的,但它似乎没有找到与where子句匹配的构建。部分原因是我缺乏语法方面的经验。我做了一些调试,发现$buildstop似乎是空的。我还必须在“$(Build.DefinitionName)”周围添加引号。你能在样品管道上进行吗?我不确定我错过了什么。我试图修改where子句,使其只包含定义名称,而不包含其他标准,但结果仍然是空的。
- 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
          }