git - 具有Git命令错误处理的Powershell-在外部程序的非零退出代码时自动中止

标签 git powershell error-handling teamcity exit-code

我使用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: errorFail build if: an error message is logged by build runner放在构建步骤中,因此构建失败,但是脚本继续运行,因此它创建了一个愚蠢的提交。

我尝试在脚本中放入try-catch,但是它没有进入catch ...

有谁有想法停止脚本并使构建错误失败?

对不起,我的英语,我是法语... ^^

最佳答案

$ErrorActionPreference变量不适用于调用外部实用程序([console]应用程序),例如git
只有两种方法可以确定外部实用程序的成功与失败:

  • 通过检查自动$LASTEXITCODE变量,PowerShell将其设置为**外部实用程序报告的退出代码**。
    按照约定, 0的值表示成功,而任何非零值表示失败。 (请注意,某些实用程序(例如robocopy.exe)也使用某些非零退出代码来传达非错误条件。)
  • 如果您对所报告的特定退出代码不感兴趣,则可以检查 bool(boolean) 自动变量$? ,该变量反射(reflect)退出代码$True0和任何非零退出代码的$False
  • 警告:至少在PowerShell [Core] 7.0上,当$?$false且使用stderr重定向($LASTEXITCODE0)并且发出的命令为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/

    相关文章:

    json - 当键在 Powershell 中包含点(句点)时从 JSON 解析值

    git - 在 visual studio 团队资源管理器中的 pull 请求中找不到任何项目

    git - 为不同的构建 react native 项目自定义包名称

    git - 从 BitBucket 下载 Git 存储库

    ruby-on-rails - 使用 Dockerfile 克隆私有(private) git gem 存储库的最佳方法

    powershell - 在 PowerShell 中从 C# 访问固定大小的数组元素

    windows - Connect-AzAccount 更改浏览器

    php - 错误处理: set_error_handler() expects the argument (errorHandler) to be a valid callback

    python - 处理Python中的记录器错误

    python - 如何访问包装在sqlalchemy错误中的psycopg2错误