我使用Git部署我的Web应用程序。因此,在Teamcity中,我准备了我的应用程序(编译,缩小JS和HTML,删除未使用的文件等),然后执行Powershell构建步骤:
$ErrorActionPreference = "Stop"
git init
git remote add origin '%env.gitFolder%'
git fetch
git reset --mixed origin/master
git add .
git commit -m '%build.number%'
git push origin master
但是,如果引发异常,脚本将继续(即使我设置了
$ErrorActionPreference = "Stop"
),并且构建也会成功。我希望脚本在出现错误时停止,并且构建失败。
我尝试将
Format stderr output as: error
和Fail build if: an error message is logged by build runner
放在构建步骤中,因此构建失败,但是脚本继续运行,因此它创建了一个愚蠢的提交。我尝试在脚本中放入try-catch,但是它没有进入catch ...
有谁有想法停止脚本并使构建错误失败?
对不起,我的英语,我是法语... ^^
最佳答案
$ErrorActionPreference
变量不适用于调用外部实用程序([console]应用程序),例如git
。
只有两种方法可以确定外部实用程序的成功与失败:
$LASTEXITCODE
变量,PowerShell将其设置为**外部实用程序报告的退出代码**。按照约定,
0
的值表示成功,而任何非零值表示失败。 (请注意,某些实用程序(例如robocopy.exe
)也使用某些非零退出代码来传达非错误条件。)$?
,该变量反射(reflect)退出代码$True
的0
和任何非零退出代码的$False
。$?
为$false
且使用stderr重定向($LASTEXITCODE
或0
)并且发出的命令为stderr输出(本身不一定指示)时,2>
可以错误地反射(reflect)*>
。失败)-参见this GitHub issue。$LASTEXITCODE
而不查询$?
来推断失败与成功。 要执行失败操作,通常需要使用
Throw
关键字来生成脚本终止错误,这需要显式操作。但是,请注意,有一个pending RFC建议将对外部程序的调用正确集成到PowerShell的用于将来版本的错误处理机制中。
显然,在每次外部实用程序调用之后检查
$LASTEXITCODE
/$?
都很麻烦,因此这是一个包装函数,可简化此过程:注意:虽然此功能有效,但它不会尝试补偿broken-up-to-at-least-v7.0 passing of arguments with embedded double quotes to external programs。要获得此补偿,您可以使用Native module 中的
iee
函数,可通过Install-Module Native
从PowerShell库中安装。function Invoke-Utility {
<#
.SYNOPSIS
Invokes an external utility, ensuring successful execution.
.DESCRIPTION
Invokes an external utility (program) and, if the utility indicates failure by
way of a nonzero exit code, throws a script-terminating error.
* Pass the command the way you would execute the command directly.
* Do NOT use & as the first argument if the executable name is not a literal.
.EXAMPLE
Invoke-Utility git push
Executes `git push` and throws a script-terminating error if the exit code
is nonzero.
#>
$exe, $argsForExe = $Args
$ErrorActionPreference = 'Continue' # to prevent 2> redirections from triggering a terminating error.
try { & $exe $argsForExe } catch { Throw } # catch is triggered ONLY if $exe can't be found, never for errors reported by $exe itself
if ($LASTEXITCODE) { Throw "$exe indicated failure (exit code $LASTEXITCODE; full command: $Args)." }
}
现在,您只需要在所有Invoke-Utility
调用之前添加git
,并且如果其中任何一个报告非零退出代码,则脚本将中止。如果太冗长,请为函数定义一个别名
Set-Alias iu Invoke-Utility
,在这种情况下,您只需要在iu
之前添加:iu git init
iu git remote add origin '%env.gitFolder%'
iu git fetch
# ...
关于git - 具有Git命令错误处理的Powershell-在外部程序的非零退出代码时自动中止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60266883/