実行シェルはどのように/いつJenkinsでビルドを失敗としてマークしますか?


112

これに対する答えを探しているときに見つけた恐怖の物語...

OK、Jenkinsが実行するはずのすべてをほぼ実行する.shスクリプトがあります。

  • SVNからソースをチェックアウトします
  • プロジェクトをビルドする
  • プロジェクトをデプロイします
  • 自分で掃除する

したがって、Jenkinsでは、Execute Shellコマンドでスクリプトを実行してプロジェクトを「ビルド」するだけで済みます。スクリプトが実行されます(ソースがダウンロードされ、プロジェクトはビルド/デプロイです)が、ビルドに失敗のマークが付けられます。私はスクリプトを閉じてみました:

  • 出口0(まだ失敗としてマークします)
  • 出口1(予想どおり、失敗としてマークします)
  • 終了コマンドはまったくありません(失敗としてマークされます)

実行シェルはいつ、どのように、なぜビルドを失敗としてマークしますか?

回答:


131

まず最初に、下の灰色の領域の上にマウスを置きます。答えの一部ではありませんが、絶対に言わなければなりません:

「チェックアウト、ビルド、デプロイ」をすべて単独で実行するシェルスクリプトがある場合、なぜJenkinsを使用しているのですか?あなたはそれが何であるかを作るジェンキンスのすべての機能を先取りしています。スクリプトを直接呼び出すcronまたはSVN post-commitフックを使用することもできます。SVNチェックアウト自体を実行するJenkinsは重要です。これにより、変更があった場合にのみ(または、必要に応じて、タイマー、または手動で)ビルドをトリガーできます。ビルド間の変更を追跡します。これらの変更が表示されるため、どのビルドがどの変更セットであったかを確認できます。変更がビルドの成功または失敗を引き起こしたときにコミッターにメールを送信します(ここでも、好みに応じて構成されています)。修正により失敗したビルドが修正されると、コミッターにメールが送信されます。そしてますます。Jenkinsがアーティファクトをアーカイブすると、Jenkinsから直接ビルドごとにアーティファクトを利用できるようになります。これはSVNチェックアウトほど重要ではありませんが、これもJenkinsを構成する重要な要素です。デプロイと同じです。単一の環境がない限り、展開は通常複数の環境で行われます。Jenkinsは、プロモーションを使用して、特定のビルド(SVNの変更の特定のセットを含む)がデプロイされた環境を追跡できます。あなたはこのすべてを先取りしています。「ジェンキンスを使わなければならない」と言われているようですが、本当に使いたくはありません。上司を背負わせて「はい、ジェンキンスを使用しました」というチェックマークを付けるだけです。

短い答えは、JenkinのExecute Shellビルドステップの最後のコマンドの終了コードは、ビルドステップの成功/失敗を決定するものです。-成功、-失敗。これは、ジョブ実行全体ではなく、ビルドステップの成功/失敗を決定することに注意してください。ジョブ実行全体の成功/失敗は、複数のビルドステップ、およびビルド後のアクションとプラグインによってさらに影響を受ける可能性があります。0anything else

既に説明したとおりBuild step 'Execute shell' marked build as failure、1つのビルドステップにのみ焦点を当てます。実行シェルビルドステップにシェルスクリプトを呼び出す1行しかない場合、シェルスクリプトの終了コードがビルドステップの成功/失敗を決定します。シェルスクリプトの実行後にさらに行がある場合は、それらが失敗の原因となっている可能性があるため、慎重に確認してください。

最後に、こちらをお読みください。Googleテストの実行後にJenkinsビルドスクリプトが終了します。それはあなたの質問とは直接関係ありませんが、JenkinsがExecute Shellビルドステップを起動するシェルスクリプトとして、/bin/sh -xe

-eシェルスクリプトをすることを意味して終了、ちょうど1コマンドが失敗しても、失敗しても、あなたはそのコマンドのエラーチェックを行う場合には、(スクリプトが終了するので、それはあなたのエラーチェックに到達する前に)。これは通常、失敗したコマンドのエラーメッセージを出力する(またはそれをnullにリダイレクトして他の方法で処理する)シェルスクリプトの通常の実行とは逆であり、続行します。

これを回避するにset +eは、シェルスクリプトの先頭に追加します。

スクリプトは想定されたすべてのことを行うと言っているので、失敗したコマンドがスクリプトの最後のどこかにある可能性があります。たぶん最後のエコー?またはどこかのアーティファクトのコピー?完全なコンソール出力を表示せずに、私たちは推測しています。

ジョブ実行のコンソール出力と、できればシェルスクリプト自体も投稿してください。そうすれば、どの行が失敗しているのかを正確に知ることができます。


6
私がまだJenkinsを使用している理由は不明です...トップの誰かがこのスクリプトを既に持っていることを完全に理解していないようで、Jenkinsを使用すると主張しました。私はディルバートストリップにいるような気がします。-eヒントをありがとうございます。問題を解決しました
テスター

45
Jenkinsを使用する正当な理由はまだあります。監査証跡、ビルドステータスの可視性などです。すでにビルドスクリプトがある場合、それをJenkinsに移動することは、Jenkins機能を利用するためにリファクタリングする前の最初のステップとして適切です。
aehlke 2014年

3
この回答をクロスリンクするserverfault.com/a/143576/186454 set + eおよびset -eは、スクリプトのどこにでも指定できます。返された値が0でない場合、その間の任意のコードがビルドを失敗することはありません
アレックスSkrypnyk

2
シェルスクリプトvsジェンキンスセットで非常によく言われました
pushya

認証されたアクセスとジョブのUIを提供するためにjenkinsを使用します。cronはそれを切りません。ジェンキンスはクリプトを実行するだけではありません。
ffghfgh 2017年

90

あなたの質問に対するシンプルで短い答えは

「シェルの実行」ビルドステップに次の行を追加してください。

#!/bin/sh

ここで、「シェルの実行」ビルドジョブにこの行が必要な理由を説明しましょう。

デフォルトでは、ジェンキンスは取る/bin/sh -xeと、この手段は-xそれぞれ、すべてのcommand.And他のオプション印刷します-e原因はすぐにスクリプトの実行を停止するシェル、とき非ゼロ(任意のコマンドが失敗したとき)終了コードで任意のコマンドが終了します。

したがって、を追加#!/bin/shすると、オプションなしで実行できます。


4
賛成。-xeのデフォルトについては知りませんでした。grepコマンドが文字列を見つけられなかったとき、grepが0以外の戻り値を返したため、スクリプト全体が失敗しました:)
Somaiah Kumbera

よくできました!私の重要ではない手順で使用すると、クリーンアップ手順のようにfind . -name 'bower_components' -exec rm {} \;なり、場合によっては失敗しました。ありがとう!
ヨーク

これにより、すべてがクリアされました- 「他のオプション-eを使用すると、コマンドがゼロ以外の(コマンドが失敗した)終了コードで終了すると、シェルはスクリプトの実行をすぐに停止します。」
Paramvir Singh Karwal

3

私の意見で-eは、シェルのオプションをオフにすることは本当に悪い考えです。最終的に、ディスクスペース不足やネットワークエラーなどの一時的な状態が原因で、スクリプトのコマンドの1つが失敗します。なければ-eジェンキンス気づかないだろうと喜ん沿って継続します。Jenkinsがデプロイを行うように設定されている場合、不良コードがプッシュされ、サイトがダウンする可能性があります。

スクリプトにgrepやfindなどの失敗が予想される行がある場合は、|| trueその行の最後に追加します。これにより、ラインが常に成功を返すことが保証されます。

その終了コードを使用する必要がある場合は、ifステートメントにコマンドを巻き上げることができます。

grep foo bar; if [ $? == 0 ]; then ...    -->   if grep foo bar; then ...

または、||句に戻りコードを取り込むことができます。

grep foo bar || ret=$?

1
ブライアン、ありがとう。あなたは私の日を救った。また、-xと-eの両方をオンにすることをお勧めします。jenkinsログに表示されるようにします。
ビカルバスネット

2

簡潔でシンプル:

Jenkinsがビルドステップ(これもスクリプトです)がゼロ以外のコードで終了することを確認すると、ビルドは赤いボール(=失敗)でマークされます。

正確にそれが起こる理由は、ビルドスクリプトによって異なります。

私は別の観点から同様のことを書きましたが、とにかくそれを読むのに役立つかもしれません: なぜJenkinsは私のビルドが成功したと思いますか?


0

したがって、を追加#!/bin/shすると、オプションなしで実行できます。

また、LinuxスレーブでJenkinsマスターからbashスクリプトを実行していた問題を修正するのにも役立ちました。#!/bin/bash「Execute Shell」ブロックの実際のスクリプトの上に追加するだけで、問題が修正されました。それ以外の場合は、Windows gitが提供するバージョンのbashシェルを実行してエラーを出していました。


0

ジェンキンスver。1.635では、次のようなネイティブ環境変数を表示することはできません。

$BUILD_NUMBER or ${BUILD_NUMBER}

この場合、他の変数に設定する必要があります。

set BUILDNO = $BUILD_NUMBER
$BUILDNO
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.