如何阻止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
关键调整说明:
- 直接捕获错误输出:用
2>&1将Az CLI的错误输出重定向到标准输出,直接存入变量,省去文件读写的冗余操作。 - 手动管理退出码:定义
$scriptExitCode变量,针对不同场景设置为0(成功/忽略特定错误)或1(真正失败),最后通过exit $scriptExitCode手动控制脚本的退出状态——GitHub Actions会以此判断步骤是否成功,0代表成功,非0代表失败。 - 移除不必要的参数切换:无需动态修改
$ErrorActionPreference,通过手动设置退出码即可精准控制步骤结果,避免Write-Error在Stop模式下的终止行为干扰。
另外,也可以在GitHub Actions步骤中添加continue-on-error: true,但这种方式不够精准,脚本内部控制退出码的方案更可靠。
内容的提问来源于stack exchange,提问作者kirkec
相关产品推荐
相关产品推荐

