You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Azure DevOps YAML流水线中实现失败阶段自动重试及资源清理?

Azure DevOps YAML流水线失败阶段自动重试方案

问题1:如何可靠获取YAML流水线中已完成或失败阶段的状态?

方案1:阶段内直接捕获状态(推荐)

在每个需要监控的阶段末尾添加任务,将阶段运行状态写入流水线输出变量,后续阶段直接读取这些变量,无需调用API:

stages:
- stage: Build
  jobs:
  - job: Build_Job
    steps:
    # 阶段内的核心任务...
    - task: PowerShell@2
      name: Capture_Build_Status
      inputs:
        targetType: 'inline'
        script: |
          # 将当前阶段的运行状态写入输出变量
          Write-Host "##vso[task.setvariable variable=Stage_Status;isOutput=true]$AGENT_JOBSTATUS"

后续监控阶段可通过dependencies.Build.outputs['Build_Job.Capture_Build_Status.Stage_Status']直接获取状态,结果为succeeded/failed/canceled,状态完全可靠。

方案2:API调用+状态等待逻辑

如果必须使用API查询,需添加循环等待逻辑,直到阶段状态明确:

$org = "your-org"
$proj = "your-proj"
$buildId = $env:BUILD_BUILDID
$stageName = "Build"
$token = $env:SYSTEM_ACCESSTOKEN

# 循环查询直到状态明确
do {
    $timeline = Invoke-RestMethod -Uri "https://dev.azure.com/$org/$proj/_apis/build/builds/$buildId/timeline?api-version=7.1-preview.2" `
        -Headers @{Authorization = "Bearer $token"}
    $stage = $timeline.records | Where-Object { $_.name -eq $stageName -and $_.type -eq "Stage" }
    $status = $stage.result

    if ($status -notin @("succeeded", "failed", "canceled")) {
        Write-Host "Stage $stageName 状态为 $status,等待30秒后重试查询..."
        Start-Sleep -Seconds 30
    }
} while ($status -notin @("succeeded", "failed", "canceled"))

# 将最终状态写入流水线变量
Write-Host "##vso[task.setvariable variable=Stage_Build_Status]$status"

注意:需在任务中启用Allow scripts to access the OAuth token选项,并确保流水线服务账号拥有**Build (Read)**权限。

问题2:如何动态仅重跑失败阶段同时确保资源清理?

1. 为重试阶段添加前置清理逻辑

在每个可重试阶段的开头,添加条件触发的清理任务,仅当阶段是重试时执行资源清理:

stages:
- stage: Retry_Build
  dependsOn: Monitor_Retry
  condition: eq(dependencies.Monitor_Retry.outputs['Check_Status.Build_Status'], 'failed')
  jobs:
  - job: Retry_Build_Job
    steps:
    # 仅当之前Build阶段失败时,执行资源清理
    - task: AzureCLI@2
      condition: eq(dependencies.Monitor_Retry.outputs['Check_Status.Build_Status'], 'failed')
      inputs:
        azureSubscription: 'your-subscription'
        scriptType: 'bash'
        scriptLocation: 'inlineScript'
        inlineScript: |
          # 清理K8s集群及Azure Arc关联资源
          az group delete --name $(ClusterRG) --yes --no-wait
          az arc k8s delete --name $(ArcClusterName) --resource-group $(ClusterRG) --yes
    # 重新执行Build阶段的核心任务
    - task: Kubernetes@1
      inputs:
        # 部署K8s集群等任务...

2. 动态触发重试阶段

通过监控阶段的输出变量,结合condition属性动态触发对应失败阶段的重试:

# 监控阶段:汇总所有阶段状态
- stage: Monitor_Retry
  dependsOn: [Build, Deploy, Test]
  jobs:
  - job: Check_All_Status
    outputs:
      Build_Status: ${{ dependencies.Build.outputs['Build_Job.Capture_Build_Status.Stage_Status'] }}
      Deploy_Status: ${{ dependencies.Deploy.outputs['Deploy_Job.Capture_Deploy_Status.Stage_Status'] }}
      Test_Status: ${{ dependencies.Test.outputs['Test_Job.Capture_Test_Status.Stage_Status'] }}
    steps:
    - script: echo "Build状态: $(Build_Status), Deploy状态: $(Deploy_Status), Test状态: $(Test_Status)"

# 动态重试失败阶段
- stage: Retry_Build
  dependsOn: Monitor_Retry
  condition: eq(dependencies.Monitor_Retry.outputs['Check_All_Status.Build_Status'], 'failed')
  jobs:
  - job: Retry_Build_Job
    steps:
    # 清理+重跑任务...

- stage: Retry_Deploy
  dependsOn: Monitor_Retry
  condition: eq(dependencies.Monitor_Retry.outputs['Check_All_Status.Deploy_Status'], 'failed')
  jobs:
  - job: Retry_Deploy_Job
    steps:
    # 清理+重跑任务...

3. 全局兜底清理

为每个阶段添加always()条件的清理任务,确保无论任务成功或失败,临时资源都能被清理:

- task: Kubernetes@1
  condition: always()
  inputs:
    command: 'delete'
    arguments: 'pod sonobuoy-test --ignore-not-found=true'
    kubernetesServiceConnection: 'your-k8s-connection'

内容的提问来源于stack exchange,提问作者user30090146

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 16:25:56