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

如何阻止GitHub Actions步骤因Az CLI特定错误在PowerShell脚本中失败

问题

我在GitHub Actions工作流中运行一个pwsh脚本,用来删除订阅里指定的资源组(资源组名称来自上一步输出)。但Azure操作有时存在延迟,会出现尝试删除已被删除的资源组的情况,我需要避免这个GitHub Actions步骤因为ResourceGroupNotFound这个特定错误而失败(也就是不让Az CLI返回错误码1导致步骤失败)。

我尝试了以下代码(因为try/catch对Az CLI无效,只能通过!$?判断执行状态):

param(
    [Parameter()]
    [string]$rgName
)
$ErrorActionPreference = "Stop"
$retries = 5
$sleepInSec = 30
for ($i = 1; $i -le $retries; $i++) {
    az group delete --yes --name $rgName 2>fail.txt
    if (!$?) {
        $errorMsg = Get-Content "fail.txt"
        if ($errorMsg -like "*ERROR: (ResourceGroupNotFound)*") {
            Write-Host "RG already deleted or never present. Skipping..."
            $ErrorActionPreference = "Continue"
            break
        }
        elseif ($i -eq $retries) {
            Write-Error "Maximum retries reached ($retries). Need manual inspection. Error: $errorMsg"
            $ErrorActionPreference = "Stop"
            exit 1
        } else {
            Write-Host "Failed $i. run. Waiting for $sleepInSec seconds before retrying."
            Start-Sleep -Seconds $sleepInSec
            continue
        }
    }
    break
}

目前判断错误信息的逻辑是可行的,但设置$ErrorActionPreference = "Continue"无法阻止步骤失败,请问有什么方法可以避免Az CLI的这个特定错误导致步骤失败?


解决方案

核心问题是脚本最终的退出码仍受Az CLI失败状态或Write-Error行为影响,需要手动控制脚本的退出码,而非依赖$ErrorActionPreference。修改后的代码如下:

param(
    [Parameter()]
    [string]$rgName
)
$ErrorActionPreference = "Stop"
$retries = 5
$sleepInSec = 30
$scriptExitCode = 0

for ($i = 1; $i -le $retries; $i++) {
    # 直接捕获Az CLI的错误输出,无需写入文件
    $errorOutput = az group delete --yes --name $rgName 2>&1
    if (!$?) {
        # 将错误输出转为字符串便于匹配
        $errorMsg = $errorOutput -join "`n"
        if ($errorMsg -like "*ERROR: (ResourceGroupNotFound)*") {
            Write-Host "RG already deleted or never present. Skipping..."
            $scriptExitCode = 0
            break
        }
        elseif ($i -eq $retries) {
            Write-Error "Maximum retries reached ($retries). Need manual inspection. Error: $errorMsg"
            $scriptExitCode = 1
            break
        } else {
            Write-Host "Failed $i run. Waiting for $sleepInSec seconds before retrying."
            Start-Sleep -Seconds $sleepInSec
            continue
        }
    }
    # 执行成功,退出码设为0
    $scriptExitCode = 0
    break
}

# 手动控制脚本退出码,这是GitHub Actions判断步骤成功与否的关键
exit $scriptExitCode

关键调整说明:

  1. 直接捕获错误输出:用2>&1将Az CLI的错误输出重定向到标准输出,直接存入变量,省去文件读写的冗余操作。
  2. 手动管理退出码:定义$scriptExitCode变量,针对不同场景设置为0(成功/忽略特定错误)或1(真正失败),最后通过exit $scriptExitCode手动控制脚本的退出状态——GitHub Actions会以此判断步骤是否成功,0代表成功,非0代表失败。
  3. 移除不必要的参数切换:无需动态修改$ErrorActionPreference,通过手动设置退出码即可精准控制步骤结果,避免Write-Error在Stop模式下的终止行为干扰。

另外,也可以在GitHub Actions步骤中添加continue-on-error: true,但这种方式不够精准,脚本内部控制退出码的方案更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 13:20:34