Powershell与Git命令错误处理

Mic*_*oux 8 git powershell teamcity

我使用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
Run Code Online (Sandbox Code Playgroud)

但是如果抛出异常,脚本会继续(即使我设置$ErrorActionPreference = "Stop")并且构建成功.

我希望脚本在出现错误时停止,并且构建失败.

我试图进行Format stderr output as: error构建步骤Fail build if: an error message is logged by build runner,因此构建失败,但脚本继续,因此它创建了一个愚蠢的提交.

我尝试在我的脚本中添加一个try-catch,但它没有进入catch ...

有没有人有想法停止脚本并失败构建错误?

抱歉我的英语,我是法国人...... ^^

gve*_*vee 7

我相信这里的问题是gitPS 抛出的错误是不可捕获的.

插图:

try {
    git push
    Write-Host "I run after the git push command"
}
catch {
    Write-Host "Something went wonky"
}
Run Code Online (Sandbox Code Playgroud)

请注意<code>Write-Host</code>来自<code>catch</code>块!</p>

<p>这是我们需要查看git命令的退出代码的地方.</p>

<p>PowerShell中最简单的方法(我知道)是检查它的值<code>$?</code>(更多信息在<code>$?</code>这里:<a href=Powershell中的`$?`是什么?)

try {
    git push
    if (-not $?) {
        throw "Error with git push!"
    }
    Write-Host "I run after the git push command"
}
catch {
    Write-Host "Something went wonky"
    throw
}
Run Code Online (Sandbox Code Playgroud)

检查我们的自定义错误(现在由<code>catch</code>块捕获)!</p></p>
        <ul class=


mkl*_*nt0 5

$ErrorActionPreference变量不适用于调用外部公用事业([控制台]应用),例如git

只有两种方法可以确定外部实用程序的成功与失败

  • 通过检查自动$LASTEXITCODE变量,PowerShell将其设置为外部实用程序报告退出代码。 按照惯例,值表示成功,而任何非零值表示失败。(请注意,某些实用程序(例如)也使用某些非零退出代码来传达非错误条件。)
    0robocopy.exe

  • 如果您对所报告的特定退出代码不感兴趣,则可以检查Boolean自动变量$?,该变量反映$True退出代码0$False任何非零退出代码。

    • 警告:从PowerShell Core 7.0.0-preview.3起,$?可以错误地反映$false何时使用$LASTEXITCODEis 0 使用stderr重定向(2>*>以及命令发出stderr输出(其本身不一定表示失败)-请参阅此GitHub问题

代理上发生故障,需要明确的动作,通常通过使用Throw关键字生成一个脚本终止错误。


显然,在每次外部实用程序调用之后检查$LASTEXITCODE/ $?都很麻烦,因此这里有一个包装器函数可以简化此过程:

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 = 'Stop' # in case $exe isn't found
  & $exe $argsForExe
  if ($LASTEXITCODE) { Throw "$exe indicated failure (exit code $LASTEXITCODE; full command: $Args)." }
}
Run Code Online (Sandbox Code Playgroud)

现在,您只需要添加Invoke-Utility 所有git调用,如果其中任何一个报告退出代码为非零,则脚本将中止。

如果太冗长,请为您的函数定义一个别名:Set-Alias iu Invoke-Utility,在这种情况下,您只需添加iu 

iu git init
iu git remote add origin '%env.gitFolder%'
iu git fetch
# ...
Run Code Online (Sandbox Code Playgroud)