Azure devops 如何将azure devops管道结果设置为成功,即使其中一个作业失败
我正在开发一个Azure CD YAML管道,以将CI管道的结果部署到虚拟机上。 现在,为了这篇文章的目的,稍微简化一些事情,CD管道非常简单,由一个阶段和3个作业组成:Azure devops 如何将azure devops管道结果设置为成功,即使其中一个作业失败,azure-devops,azure-pipelines,Azure Devops,Azure Pipelines,我正在开发一个Azure CD YAML管道,以将CI管道的结果部署到虚拟机上。 现在,为了这篇文章的目的,稍微简化一些事情,CD管道非常简单,由一个阶段和3个作业组成: 第一个作业运行脚本来停止某种复杂的应用程序。这有时会失败 仅当第一个作业失败时,第二个作业才会运行。这使管理员有机会进行手动干预(利用内置功能)并修复第一个作业中遇到的问题。如果管理员愿意继续运行部署管道,他将恢复管道的运行 第三步是部署新版本的应用程序 以下是YAML管道的总体结构: jobs: - deployme
- 第一个作业运行脚本来停止某种复杂的应用程序。这有时会失败
- 仅当第一个作业失败时,第二个作业才会运行。这使管理员有机会进行手动干预(利用内置功能)并修复第一个作业中遇到的问题。如果管理员愿意继续运行部署管道,他将恢复管道的运行
- 第三步是部署新版本的应用程序
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显示绿色检查
有人知道实现这一目标的方法吗?
我假设这是可能的,否则我不理解为什么我们有机会在管道中进行手动干预。构建结果是只读的,在构建完成后无法更新。不过,您可以查看下面的解决方法,以消除Devops门户中的失败标志(红十字) 1、对作业中的任务使用
continueOnError
。例如:
jobs:
- deployment: StopApplication
...
steps:
- task: taskName
...
continueOnError: true
- 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
当continueOnError属性设置为true时。任务失败时,管道的结果将设置为SucceededWithIssues
。你将有一个感叹号而不是红十字
对于作业ManualIntervation
,您还需要切换到条件
然后更改jobManualIntervation
的条件,以检查标志变量是否设置为true。见下文:
- job: ManualIntervation
dependsOn: StopApplication
condition: eq(dependencies.StopApplication.result, 'SucceededWithIssues')
2,另一种解决方法是将stopplication
作业与不同管道中的其他作业分开
您需要创建两个管道。第一个管道只有stopplication
作业。第二条管道包含其余的作业。以及使用从第一管道触发第二管道
在第一条管道中。以及失败任务后的powershell任务,用于检查作业状态并使用rest api触发第二个管道。请参见以下示例:
jobs:
- deployment: StopApplication
...
steps:
- task: taskName
...
continueOnError: true
- 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
为真。然后将执行手动干预作业
因此,即使第一个管道失败,第二个管道也会成功。生成结果是只读的,在生成完成后无法更新。不过,您可以查看下面的解决方法,以消除Devops门户中的失败标志(红十字)
1、对作业中的任务使用continueOnError
。例如:
jobs:
- deployment: StopApplication
...
steps:
- task: taskName
...
continueOnError: true
- 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
当continueOnError属性设置为true时。任务失败时,管道的结果将设置为SucceededWithIssues
。你将有一个感叹号而不是红十字
对于作业ManualIntervation
,您还需要切换到条件
然后更改jobManualIntervation
的条件,以检查标志变量是否设置为true。见下文:
- job: ManualIntervation
dependsOn: StopApplication
condition: eq(dependencies.StopApplication.result, 'SucceededWithIssues')
2,另一种解决方法是将stopplication
作业与不同管道中的其他作业分开
您需要创建两个管道。第一个管道只有stopplication
作业。第二条管道包含其余的作业。以及使用从第一管道触发第二管道
在第一条管道中。以及失败任务后的powershell任务,用于检查作业状态并使用rest api触发第二个管道。请参见以下示例:
jobs:
- deployment: StopApplication
...
steps:
- task: taskName
...
continueOnError: true
- 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
为真。然后将执行手动干预作业
这样,即使第一条管道失败,第二条管道也会成功。您好,感谢您的宝贵意见。有点奇怪的是,虽然我们可以在管道中进行手动干预,但我们无法设置管道运行状态。你认为这是一个有价值的新功能吗?我想我们需要重新考虑我们的管道执行方法,因为如果没有明确的结果(失败或成功),只会给操作人员留下解释和困惑的空间,因为他们想知道什么软件实际部署在哪里。另一方面(并且为了潜在读者的利益),在第一个解决方案中,一个改进可以是在手动干预作业的条件下直接使用StopApplication作业状态。这使得创建变量的经济性更高。条件