【问题标题】:Is it possible to cancel a Azure DevOps pipeline Job programmatically?是否可以以编程方式取消 Azure DevOps 管道作业?
【发布时间】:2020-05-27 13:16:24
【问题描述】:

因为可以停止 Azure DevOps 管道中的单个步骤:

echo "##vso[task.complete result=Succeeded;]DONE"

见:https://github.com/microsoft/azure-pipelines-tasks/blob/master/docs/authoring/commands.md#task-logging-commands

是否也可以检查条件并根据该条件停止整个管道运行或作业?

附言。我知道,您可以为作业设置条件,但在我的情况下,整个管道是一个作业,由于其他原因,将其拆分为多个作业是没有意义的。

【问题讨论】:

  • 同意 Krzysztof Madej。这是一些附加信息。 1、如果使用Rest Api取消构建,管道状态会被标记为“已取消”。 2. 由于不想添加代码,所以可以为每个任务添加条件。在这种情况下,管道将运行并被标记为“成功”,但所有任务都将被跳过。你可以参考这个ticket
  • 嗨@Matthias,检查this rule,如果Krzysztof Madej 的回答可以解决您的问题。您可以考虑接受它作为答案。这只是一个提醒:)
  • @KevinLu-MSFT。我以前知道这种解决方案。这确实以某种方式解决了问题,但我认为还没有优雅的方法来解决这个问题。

标签: azure azure-devops azure-pipelines azure-pipelines-yaml


【解决方案1】:

您可以通过 REST API 取消构建:

PATCH https://dev.azure.com/atbagga/atbagga/_apis/build/Builds/120
Request content: {'status': 'Cancelling'}

这里有一个例子:

steps:
- task: PowerShell@2
  name: ConditionalStep
  inputs:
    targetType: 'inline'
    script: |
      Write-Host "I'm here"
      Write-Host ('$(SomeVariable)' -eq 'Stop')
      if ('$(SomeVariable)' -eq 'Stop') {
        $uri = "https://dev.azure.com/thecodemanual/DevOps Manual/_apis/build/builds/$(Build.BuildId)?api-version=5.1"

        $json = @{status="Cancelling"} | ConvertTo-Json -Compress

        $build = Invoke-RestMethod -Uri $uri -Method Patch -Headers @{Authorization = "Bearer $(System.AccessToken)"} -ContentType "application/json" -Body $json

        Write-Host $build
      }
      Write-Host "And now here!"
    pwsh: true
- pwsh: Start-Sleep -Seconds 60    
- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: |
      $uri = "https://dev.azure.com/thecodemanual/DevOps Manual/_apis/build/builds/$(Build.BuildId)/timeline?api-version=5.1"

      Write-Host $uri

      # Invoke the REST call
      $build = Invoke-RestMethod -Uri $uri -Method Get -Headers @{Authorization = "Bearer $(System.AccessToken)"} -ContentType "application/json"

      $taskResult = $build.records | Where-Object {$_.name -eq "ConditionalStep" } | Select-Object result

      Write-Host $taskResult.result

    pwsh: true

为此,您将获得该输出:

如果你得到这样的错误:

 | {"$id":"1","innerException":null,"message":"Access denied.
 | DevOps Manual Build Service (thecodemanual) needs Stop builds
 | permissions for vstfs:///Build/Build/1611 in team project
 | DevOps Manual to perform the
 | action.","typeName":"Microsoft.TeamFoundation.Build.WebApi.AccessDeniedException, Microsoft.TeamFoundation.Build2.WebApi","typeKey":"AccessDeniedException","errorCode":0,"eventId":3000}

请确保您的构建帐户有权停止构建:

您将在此部分下找到此内容:

请注意

您不能将构建设置为已完成。如果你这样做了。整个管道仍将执行。因此,如果这不是您想要的,您需要使用先前在管道中设置的输出变量为每个步骤添加条件,并以此方式忽略这些步骤。

steps:
- task: PowerShell@2
  name: ConditionalStep
  inputs:
    targetType: 'inline'
    script: |
      Write-Host "I'm here"
      Write-Host ('$(SomeVariable)' -eq 'Stop')
      if ('$(SomeVariable)' -eq 'Stop') {
        Write-Host '##vso[task.setvariable variable=shouldStop;isOutput=true]Yes'
      }
      Write-Host "And now here!"
    pwsh: true
- pwsh: Start-Sleep -Seconds 60
  condition: ne(variables['ConditionalStep.shouldStop'], 'Yes')
- task: PowerShell@2
  condition: ne(variables['ConditionalStep.shouldStop'], 'Yes')
  inputs:
    targetType: 'inline'
    script: |
      $uri = "https://dev.azure.com/thecodemanual/DevOps Manual/_apis/build/builds/$(Build.BuildId)/timeline?api-version=5.1"

      Write-Host $uri

      # Invoke the REST call
      $build = Invoke-RestMethod -Uri $uri -Method Get -Headers @{Authorization = "Bearer $(System.AccessToken)"} -ContentType "application/json"

      $taskResult = $build.records | Where-Object {$_.name -eq "ConditionalStep" } | Select-Object result

      Write-Host $taskResult.result

    pwsh: true

【讨论】:

  • 感谢您的回复!嗯,我不认为这是一个令人满意的解决方案:如果不满足条件,则管道不应标记为失败,并且我不想在每个后续步骤中都有额外的代码。
  • 欢迎。你能检查一下这是否让你满意吗?
  • @Matthias 如果我的回复对您有帮助,您可以考虑点赞吗?
猜你喜欢
  • 2021-05-15
  • 1970-01-01
  • 2021-05-23
  • 2020-03-28
  • 1970-01-01
  • 1970-01-01
  • 2011-08-31
  • 2021-09-07
相关资源
最近更新 更多