即使其中一项作业失败,如何将 azure devops 管道结果设置为成功

Fra*_*nno 10 azure-devops azure-pipelines

我正在开发一个 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: ...
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,如果第一个部署作业失败,但管理员检查问题、修复问题、恢复管道的运行并且最后一个部署作业成功,Azure DevOps 将我的管道显示为“失败”(DevOps 中的红十字) Portal),我可以理解为其中一项工作失败了。尽管如此,从功能上来说,部署成功了,因此我想设置/强制管道运行的结果为成功,以便 Azure DevOps 显示绿色复选标记。

有谁知道如何实现这一目标?我认为这是可能的,否则我不会理解为什么我们有机会在管道中进行手动干预。

Lev*_*SFT 7

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

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

jobs:
 - deployment: StopApplication
   ...
    steps:
    - task: taskName
       ...
      continueOnError: true
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

您还需要更改为conditionfor 工作ManualIntervation

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

- job: ManualIntervation
  dependsOn: StopApplication
  condition: eq(dependencies.StopApplication.result, 'SucceededWithIssues')
Run Code Online (Sandbox Code Playgroud)

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

您需要创建两个管道。第一个管道只有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
Run Code Online (Sandbox Code Playgroud)

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

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

- job: ManualIntervation
  dependsOn: StopApplication
  condition: eq('${{parameters.ManualIntervation}}', 'true') 
Run Code Online (Sandbox Code Playgroud)

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

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