はじめに
Jenkins のビルドスクリプトでシェルスクリプトを実行する行があり、
そのシェルスクリプト内で実行しているコマンドがエラーとなっても、
Jenkins 自体にエラーが検出されない時の対処方法について紹介します。
お忙しい方のために結論だけ先に書いてしまいます:
下記の set
コマンドを Jenkins のビルドスクリプトとシェルスクリプトの冒頭に追加すれば ok です。
set -eu
以下、この対処方法についての詳細を書いておきます。
対処方法 set -eu
の追加について
ビルドスクリプトの冒頭に追加
Jenkins の Job のコンソールログを読んで、
/bin/bash /tmp/jenkins?????.sh
のオプションに -e
がなければ
Jenkins のビルドスクリプト (Job の execute shell の Commands) の成功/失敗は
最後のコマンドの終了ステータスによって決まってしまいます。
例えば、ビルドスクリプトが
#!/bin/bash
./hogehoge/src/run.sh
echor $?
echo $?
だった時 -e
オプションがないとジョブの結果は "成功" となります。
ビルドスクリプトの途中に明らかにエラーとなるコマンドがあったとしても、
最後のコマンドは成功するので最終的な終了ステータスは 0 となり、
ジョブの結果は "成功" となってしまうようです。
これだと、ビルドスクリプトのエラーが正しく検出されないので、
set -eu
コマンドをビルドスクリプトの冒頭に記載します。
#!/bin/bash
set -eu # 追加
./hogehoge/src/run.sh
echor $? # ここで失敗する
echo $?
そうすれば、ビルドスクリプトの途中でエラーとなった時 (終了ステータスが 0 以外の時)、
ジョブの結果が正しく "失敗" となります。
なので、とりあえずシェルスクリプトの冒頭には set -eu
コマンドを書いておくと良いかと思います。
See https://qiita.com/youcune/items/fcfb4ad3d7c1edf9dc96
ビルドスクリプト内のシェルスクリプトに追加
続いて、ビルドスクリプト内のシェルスクリプトの冒頭にも set -eu
コマンドを追加してください。
これをしないと、ビルドスクリプト内のシェルスクリプトの終了ステータスが、
シェルスクリプトの最後のコマンドの終了ステータスで決定してしまいます。
要は、次のようなシェルスクリプトで
git clone http://github.com/git/user/hogehoge.git
python hogehoge/src/run.py # 成功 or 失敗
echo $? # 成功
で python スクリプトがエラーになったとしても、その次の echo $?
コマンドが成功するので、
最終的な終了ステータスが 0 となるので、ジョブの結果は "成功" となります。
これだと python スクリプトの結果を無視しているので、ジョブの成功/失敗を正しく検出できないです。
なので、set -eu
コマンドをシェルスクリプトの冒頭に追加します。
set -eu # 追加
git clone hogehoge
python hogehoge/src/run.py # 失敗するとシェルスクリプトも失敗する
echo $? # 実行されない
これで python スクリプトが失敗したときにジョブが失敗となります。
(もちろんジョブのビルドスクリプトの冒頭に set -eu
を記載していることが前提ですが)
これで、ビルドスクリプト内のシェルスクリプトが途中で失敗した場合でも、
正しくジョブが失敗と検出されるようになります。
まとめ
最後にまとめますと、とにかく、Jenkins でシェルスクリプト (コマンド実行) する時は、
set -eu
コマンドを冒頭に記載してください。
そうすれば、スクリプトのどこか途中でエラーとなったとき、
Jenkins のジョブの結果が正しく "失敗" と表示されるようになります。
この set -eu
コマンドをシェルスクリプトの冒頭に記載することは、
Jenkins 関連の話で閉じる内容ではないと思います。
シェルスクリプトを書くときに #!/bin/bash
を書くのと同じように、
set -eu
も合わせて書いておいた方が良いかと思います。
これにてこの記事はおしまいです。
お疲れ様でした。