首页 > 解决方案 > 即使其中一项工作失败,如何将 azure devops 管道结果设置为成功

问题描述

我正在开发一个 Azure CD YAML 管道,以将 CI 管道的结果部署到虚拟机上。现在,为了这篇文章的目的,稍微简化一下,CD 管道非常简单,由一个包含 3 个作业的阶段组成:

这是 YAML 管道的整体结构:

jobs:
  - deployment: StopApplication
    environment:
      name: 'EnvA'  # This environment is a set of virtual machines running self-hosted Azure Agents.
      resourceType: VirtualMachine
    strategy:
          rolling:
            maxParallel: 1
            deploy:
              steps:
              - task: ...
  - job: ManualIntervation
        displayName: Manual intervention to fix issue while stopping application
        pool: server
        dependsOn: StopApplication
        condition: failed()  # This job will run only if job StopApplication has failed.
        timeoutInMinutes: 60 
        steps:
        - task: ManualValidation@0
          timeoutInMinutes: 50
          inputs:
            notifyUsers:
              someone@somewhere.com
            instructions: 'Do something'
            onTimeout: 'reject'
  - deployment: DeployApp
        dependsOn:
        - StopApplication
        - ManualIntervation
        condition: xor(succeeded('StopApplication'), succeeded('ManualIntervation'))
        workspace:
          clean: all
        environment:
          name: 'EnvA'  # This environment is a set of virtual machines running self-hosted Azure Agents.
          resourceType: VirtualMachine
        strategy:
          rolling:
            maxParallel: 1
            deploy:
              steps:
              - task: ...

我遇到的问题是,如果第一个部署作业失败,但管理员检查了问题,修复它,恢复管道的运行并且最后一个部署作业成功,Azure DevOps 将我的管道显示为失败(DevOps 中的红叉门户),我可以理解为其中一项工作失败了。尽管如此,在功能上,部署成功了,所以我想设置/强制管道运行的结果为成功,以便 Azure DevOps 显示绿色检查。

有谁知道实现这一目标的方法?我会假设这是可能的,否则我不明白为什么我们有机会在管道中进行手动干预。

标签: azure-devopsazure-pipelines

解决方案


构建结果是只读的,构建完成后无法更新。但是,您可以查看以下解决方法以消除 Devops 门户中的失败标志(红十字)。

1、continueOnError用于工作中的StopApplication任务。对于以下示例:

jobs:
 - deployment: StopApplication
   ...
    steps:
    - task: taskName
       ...
      continueOnError: true

当 continueOnError 属性设置为 true 时。管道的结果将设置为SucceededWithIssues任务失败时。您将有一个感叹号而不是红十字

在此处输入图像描述

您还需要更改为conditionfor 作业ManualIntervation

然后更改作业的条件ManualIntervation以检查标志变量是否设置为真。见下文:

- job: ManualIntervation
  dependsOn: StopApplication
  condition: eq(dependencies.StopApplication.result, 'SucceededWithIssues')

2,另一种解决方法是将StopApplication作业与不同管道中的其他作业分开。

您需要创建两个管道。第一个管道只有StopApplication工作。第二个管道包含其余的作业。并使用rest api从第一个管道触发第二个管道。

在第一个管道中。失败任务后的powershell任务检查作业状态并使用rest api触发第二个管道。请参见下面的示例:

 - powershell: |
      
      $body = @{
                templateParameters=@{
                    ManualIntervation= "false"
                }
              }

      if("$(Agent.JobStatus)" -eq "Failed"){
          $body.templateParameters.ManualIntervation='true'
      }
      $url = "$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_apis/pipelines/{second-pipelineId}/runs?api-version=6.1-preview.1"
      $result5 = Invoke-RestMethod -Uri $url -Headers @{Authorization = "Bearer $(system.accesstoken)"} -Method post -Body (convertto-json $body) -ContentType "application/json" 

    condition: always() #always run this task

然后在第二个管道中定义一个运行时参数 ManualIntervation并设置作业条件,ManualIntervation如下所示:

parameters:
- name: ManualIntervation
  type: string
  default: false
  
...

- job: ManualIntervation
  dependsOn: StopApplication
  condition: eq('${{parameters.ManualIntervation}}', 'true') 

执行第一个管道时。powershell 任务将触发第二个管道,模板参数请求正文将覆盖ManualIntervation第二个管道中的参数。如果ManualIntervation是真的。然后将执行 ManualIntervation 作业。

这样即使第一个管道失败,第二个管道也会成功。


推荐阅读