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
変数はnotの呼び出しに適用されます外部ユーティリティ([コンソール]アプリケーション)git
など。
determine外部ユーティリティの成功と失敗の2つの方法:
自動$LASTEXITCODE
変数を調べることにより、PowerShellは終了コード外部から報告ユーティリティ。
慣例により、値0
はsuccessを示しますが、任意のnonzero値はfailureを示します。 (robocopy.exe
などの一部のユーティリティは、特定のゼロ以外の終了コードを使用して、エラー以外の状態も伝達することに注意してください。)
報告されたSpecific終了コードに興味がない場合は、Boolean自動変数$?
。これは、終了コード$True
の場合は0
を反映し、ゼロ以外の終了コードの場合は$False
を反映します。
$?
が$false
and /の場合、$LASTEXITCODE
は0
を誤って反映する可能性がありますstderrリダイレクト(2>
または*>
)が使用されますandコマンドがstderr出力を出力しました(それ自体は必ずしも失敗を示すわけではありません)- これを参照してくださいGitHubの問題 。Acting失敗した場合は明示的アクションが必要です。通常は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 = '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)." }
}
ここで、すべてのgit
呼び出しの前にInvoke-Utility
を追加する必要があり、それらのいずれかがゼロ以外の終了コードを報告した場合、スクリプトは中止されます。
それが冗長すぎる場合は、関数のエイリアスをSet-Alias iu Invoke-Utility
と定義します。この場合、iu
を先頭に追加するだけで済みます。
iu git init
iu git remote add Origin '%env.gitFolder%'
iu git fetch
# ...
ここでの問題は、git
によってスローされたエラーがPSによってトラップできないことだと思います。
図:
try {
git Push
Write-Host "I run after the git Push command"
}
catch {
Write-Host "Something went wonky"
}
catch
ブロックからWrite-Host
が欠落していることに注意してください。
ここで、gitコマンドの終了コードを確認する必要があります。
PowerShellで(私が知っている)最も簡単な方法は、$?
の値を確認することです($?
の詳細については、こちらをご覧ください: 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
}
カスタムエラーを確認してください(現在はcatch
ブロックでキャッチされています)。