【问题标题】:Azure DevOps Multi-Stage Pipelines Stuck Waiting for ApprovalsAzure DevOps 多阶段管道卡在等待批准
【发布时间】:2020-05-15 13:42:48
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: azure-devops yaml


    【解决方案1】:

    目前,yaml 管道不支持手动部署到阶段。请检查此open issue

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

    您可以定义pr trigger 并设置autocancel=true(默认为true)以取消之前的运行,如果新的更改被推送到同一个pr。

    triggerbatch 属性可以达到类似的效果。如果当前 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"
    

    更新:Cancel in progress builds via powershell scripts

    您可以在管道顶部添加一个 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

    然后将停止构建的权限设置为允许用户Project Collection Build Service(projectName),

    【讨论】:

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

    我一直在寻找这个问题,我认为有更好的解决方案。

    在此处查看我对类似问题的回答:https://stackoverflow.com/a/61400536/275559

    【讨论】:

      猜你喜欢
      • 2020-10-31
      • 1970-01-01
      • 2021-03-25
      • 2021-03-18
      • 2020-12-03
      • 2020-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多