シェルの実行が失敗してもジェンキンスビルドは失敗しない


132

ビルドプロセスの一部として、実行シェルステップとしてgit commitを実行しています。ただし、ワークスペースに変更がない場合、Jenkinsはビルドに失敗しています。これは、コミットする変更がない場合にgitがエラーコードを返すためです。ビルドを中止するか、不安定な場合は単に不安定としてマークを付けます。何か案は?


コミットするものがあるかどうかを確認し、そのような場合にのみコミットしますか? stackoverflow.com/questions/5139290/...
アンダース・リンダール

回答:


210

コマンドが失敗したときにそれ以上の実行を停止するには:

command || exit 0

コマンドが失敗したときに実行を継続するには:

command || true


12
|| exit 0最初のケースではは必要ありません。falseをcommand返すと実行が停止します。つまり、2番目のオプションは非常に役立ちます。
Nir Alfasi

20
@alfasinあなたは問題を理解していません。OPはJenkinsビルドが失敗することを望んでいません。エルゴ我々はしなければならないexit 0、ゼロ以外の終了コードは、ビルドに失敗しますので。
Quolonelの質問

1
その場合、「コマンドが失敗したときにそれ以上の実行を停止するには:」から「コマンドが失敗したときにそれ以上の実行を停止し、Jenkinsジョブを成功としてマークするには:」という表現に変更します。
Nir Alfasi、2015

1
@alfasin Quolonel Questionsの素早い発言は専門家ではないことに同意しますが、彼の発言は正しかったです。「exit 0」は、ジョブが成功したことを示しません。現在のビルドステップが成功したとマークするだけです。ジョブは次のビルドステップのいずれかで失敗する可能性があります。
noamik

1
これはうまくいきました!/ bin / bash + eを使用してエラーで失敗しないようにすることができるため、これは「sshを使用してリモートホストでシェルを実行する」プラグイン機能に特に役立ちます。また、ビルドに失敗しないコマンドを選択できるというアイデアも気に入っています。
leeman24 2017

80

Jenkinsは/bin/sh -xeデフォルトでを使用してシェルビルドステップを実行しています。-x実行されたすべてのコマンドを出力することを意味します。-eスクリプト内のいずれかのコマンドが失敗した場合、失敗して終了することを意味します。

したがって、あなたのケースで何が起こったのかは、gitコマンドが1で終了することであると思います。デフォルトの-eパラメータのため、シェルは0以外の終了コードを取得し、残りのスクリプトを無視して、ステップを失敗としてマークします。ここにビルドステップスクリプトを投稿できれば、これを確認できます。

その場合は、#!/bin/shオプションなしでスクリプトが実行されるように配置してみてください。または、set +eこの動作をオーバーライドするために、ビルドステップの上で何か類似したことを行います。


編集:もう1つ注意すべき点は、シェルスクリプトの最後のコマンド0以外のコードを返す場合、このセットアップを使用しても、ビルドステップ全体が失敗とマークされることです。この場合、echoコマンドを最後に置くだけでそれを回避できます。

別の関連する質問


41

プッシュするものが何もない場合、gitは終了ステータスを返します。1。実行シェルビルドステップはそれぞれ失敗としてマークされます。ORステートメントを使用できます|| (二重管)。

git commit -m 'some messasge' || echo 'Commit failed. There is probably nothing to commit.'

つまり、最初に失敗した場合(終了ステータス> 0が返された場合)、2番目の引数を実行します。2番目のコマンドは常に0を返します。プッシュするものが何もない場合(終了ステータス1-> 2番目のコマンドを実行)、エコーは0を返し、ビルドステップが続行されます。

ビルドを不安定としてマークするには、ビルド後のステップであるJenkins Text Finderを使用できます。コンソール出力を通過し、パターン(あなたのエコー)を照合し、ビルドを不安定としてマークすることができます。


27

ジェンキンスに失敗しないように伝える別のスムーズな方法があります。ビルドステップでコミットを分離し、シェルが失敗しないように設定できます。

set +e
git commit -m "Bla."
set -e

2
set -e終了コードに関係なく、実行するコマンドの後に必ず追加してください。そうしないと、意図しないコマンドが実行される可能性があります。私は、私のようなものでしたので、自分でエラーを処理したい:= "{?} $"セット-e#ハンドル終了コードのロジック``セット+ eは-mコミット"BLA" EXIT_CODEを
jcasner

8

Jenkinsは、ステップの戻り値によってステップの成功/失敗を決定します。シェルの場合、それは最後の値の戻りでなければなりません。Windows CMDと(POSIX)Bashシェルの両方でexit 0、最後のコマンドとしてを使用して戻り値を手動で設定できるはずです。


これは、2行の「execute windows bat」では機能しないようです:git commit -m "message" exit 0
Ben

@Ben exit 0Windows Jenkinsインストールの複数のビルドで "execute windows batch command"と一緒に使用すると、期待どおりに動作します。何か他のことが起こっているに違いない。コンソールログの関連部分を投稿できますか?
jwernerny 2013年

最初のステップでgit commit -m "blah"を使用していますか?マシン上で手動でbatスクリプトを作成してみて、gitコマンドの後にエコーと終了0を入れました。コミットするものがなければ、他のコマンドはどちらも実行されません...
Ben

@xiaweiからの回答を参照してください。Jenkinsのデフォルトの動作で#!/bin/sh -xvは、エラーが発生した場合にスクリプトを停止するシェルを実行します。
Steven the Easy

8

私はここにある答えを使用してこれを機能させることができました:

エラーなしでgit commitする方法は?

git diff --quiet --exit-code --cached || git commit -m 'bla'

1
上記の内容は次のとおりです。「git diffコマンドを実行し、失敗した場合はgit commitコマンドを実行します。基本的に、コミットするgit diffものが見つかった場合にのみコミットを実行します。ただし、@ jwernernyの回答は正しかったexit 0ので、最後のステートメントとして追加できます。。ジェンキンスは成功として扱うようにする任意のスクリプトに私はあなたがLinuxのシェルのステップをやっていたならば、これは失敗する1つのシナリオを考えることができますが、バッチ内のこれは常に動作するはずです。
スラブ

@Ben Jenkinsは、ここ(中央)で/bin/sh -xe述べたように、デフォルトでシェルビルドステップを実行しています。したがって、ビルドステップの上にを配置または実行して、この動作をオーバーライドすることができます。これにより、exit内の1つのコマンド(0以外のコード)でも残りのステップが続行されます#!/bin/bashset +e
Xiawei Zhang

8

タイトルの(より一般的な)質問について-Jenkinsが失敗しないようにするには、終了コード1が表示されないようにします。pingの例:

bash -c "ping 1.2.3.9999 -c 1; exit 0"

そして今、あなたは例えばpingの出力を得ることができます:

output=`bash -c "ping 1.2.3.9999 -c 1; exit 0"`

もちろん代わりに ping ...を含む任意のコマンドを使用できますgit commit



6

テキスト検索プラグインを使用できます。これにより、選択した式の出力コンソールを確認し、ビルドをとしてマークできますUnstable


これは有望に見えましたが、何らかの理由でビルドに失敗し続けました。
Ben

4

複数のシェルコマンドの場合、以下を追加して失敗を無視します。

set +e commands true

ここに画像の説明を入力してください


一般に、-eの設定を解除することはお勧めしません。特定のコマンドの戻り値を無視したい場合は、 "|| true"または次のようにtrueを返すより意味のあるものを追加できます:stop-service.sh || エコーサービスは既にダウンした
ラウル・サリナス- Monteagudo

3

このコマンドをシェルブロックに入れると、次のようになります。

false
true

ビルドは失敗としてマークされます(少なくとも1つのゼロ以外の終了コード)ので、(set + e)を追加して無視できます。

set +e
false
true

失敗しません。ただし、これは(set + e)を設定していても失敗します。

set +e
false

最後のシェルコマンドは0で終了する必要があるためです。


2

以下は、変更がある場合にのみコミットすることにより、Mercurialで機能します。したがって、ビルドは、コミットが失敗した場合にのみ失敗します。

hg id | grep "+" || exit 0
hg commit -m "scheduled commit"

0

いくつかのヒントを含む別の答えは、誰かにとって役立つ可能性があります:

次のルールでコマンドを分離することを忘れないでください

コマンド1 && command2-command1が成功した場合にのみ、command2が実行されることを意味します

command1 ;command2-コマンド1の結果に関係なくコマンド2が実行されることを意味します

例えば:

String run_tests = sh(script: "set +e && cd ~/development/tests/ && gmake test ;set -e;echo 0 ", returnStdout: true).trim()
println run_tests 

失敗した場合(コマンドが失敗した場合)set -eおよびecho 0コマンドを使用して正常に実行されgmake testますが、次のコードは省略されます。

String run_tests = sh(script: "set +e && cd ~/development/tests/ && gmake test && set -e && echo 0 ", returnStdout: true).trim()
println run_tests 

少し間違っており、コマンドset -eecho 0イン&& gmake test && set -e && echo 0println run_testsステートメントでスキップされますgmake test。失敗するとjenkinsビルドが中止されるためです。回避策としてreturnStatus:true、に切り替えることができますが、コマンドからの出力を見逃してしまいます。


0

この答えは正しいですが、それは指定されていない|| exit 0か、|| true行くシェルコマンド内。以下に、より完全な例を示します。

sh "adb uninstall com.example.app || true"

上記は機能しますが、以下は失敗します:

sh "adb uninstall com.example.app" || true

多分それは他の人には明白ですが、これに気付く前に私は多くの時間を浪費しました。

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