あるある話題で、すでにいろんな所でまとめ終わってるものばかりですがとりあえずメモ
1. 「シェルの実行」内で分岐
[設定 (Configure)] → [ビルド (Build)] → [シェルの実行 (Execute Shell)] を弄る
例
#!/bin/sh ls /tmp/hoge # Not exists if [ $? -eq 0 ] ; then echo "SUCCESS" else echo "FAILURE" fi
ポイントは Shebang を指定すること。
Jenkins Job の「シェルの実行」に入力されたコードは /tmp/hudson**.sh
みたいなファイルに落とされてから実行されますが、この時 Shebang が無いと自動的に set -e
が挿入されてしまいます。
失敗した時に実行したいのに、set -e
によって if に到達できない問題があるため、Shebang を明示的に記載することでそれを回避できます。
2. Post Build Task を使う(文字列フィルタ編)
「この文字列が出力されてたら status code が 0 でもエラーって思いたいんだよ」という時、 前述の「シェルの実行」内で出力をファイルに落として grep してー・・とがんばってもいいのですが Post build task を使う方がてっとりばやいです。
Post build task のインストール後、[設定 (Configure)] → [ビルド後の処理 (Post-build Actions)] → [Post build task] を追加します。
詳しい使い方はここでは省きます。上記リンク先や Google it 。簡単に言うと、指定した文字列を「ジョブの実行」で出力された文字列で検索して、マッチしたら実行する、みたいなことができます。
これまでの方法で解決できないパターンがある
たとえば「シェルの実行」で bundle exec
を行うジョブがあったとします。
cd /path/to/project bundle install --path vendor/bundle bundle exec rspec
「このジョブが失敗したときだけある処理をしたい」みたいなことを思い浮かべた時、困ることが多かったです。
パターン1 で難しい理由
#!/bin/sh cd /path/to/project bundle install --path vendor/bundle bundle exec rspec if [ $? -eq 0 ] ; then echo "SUCCESS" else echo "FAILURE" fi
とやりたくなってしまいますが、これは if まで到達しません 。なぜなら
$ head -n 5 `which bundle` #!/usr/bin/env bash set -e [ -n "$RBENV_DEBUG" ] && set -x program="${0##*/}"
こんな風に bundle
内で set -e
が指定されているため
RSpec でエラーが出た時の処理を書きたいと思っても bundle 内の set -e
に阻まれて if に到達できない。
(もしかして外からこれを解除する方法あるのかな…)
パターン2で難しい理由
RSpec の結果出力を見て「failure が 0 じゃないからー」とかをチェックしてもいいんですが、これもスマートじゃない気がしました。(もちろん時と場合にはよるんですが。さっと見るだけならいいかな?)
Build other projects
で難しい理由
Add post-build action (ビルド後の処理)
→ [Build other projects (他のプロジェクトのビルド)]
だと
- 成功した時だけ
- 不安定の時にも
- エラーの時にも
という3つの条件しか選べず「エラーの時 だけ」というのが指定できません。
そこで次の方法です。
3. Post Build Task を使う(ジョブステータスをチェック編)
Post Build Task
を使うのは変わらないのですが、そこに書くシェルスクリプトをいじります
#!/bin/sh curl ${BUILD_URL}/api/json?tree=result | grep -q "SUCCESS" if [ $? -eq 0 ]; then echo "SUCCESS!" else echo "FAILURE..." fi
$BUILD_URL
には http://jenkins.server/job/プロジェクト名/ビルド番号
が入ります。こいつに /api/json
をつけくわえると、指定した番号のビルドに関する情報が json 形式で得られます (参考: Remote access API - Jenkins - Jenkins Wiki)
さらに ?tree=result
と指定すると
{"result":"SUCCESS"}
このようにビルドの状態だけを抜きとれるので、より一層 grep しやすくなりました。
まとめ
シェルが使えるのでどうにでもなる。
もっと楽い方法あるよーという方はご教授願います