Jenkins casual notification using Remote access API

はじめに

このエントリは Jenkins Advent Calendar jp 2011 の21日目分です。

はてなダイアリーで書くのが流行っているようですが、あえてのはてなブログからお送りします。

今日は、ビルド結果の通知とリモートアクセスAPIの組み合わせについて話します。

Jenkinsの通知処理

Jenkins は各種プラグインが揃っており、そのうちの幾つかはこのアドベントカレンダーでも紹介されています。通知系のプラグインも IRC Plugin や Growl Plugin, Skype Plugin など色々揃ってますね。これらを使えば、ジョブのビルド結果をいろんな手段で通知させることができます。

これら通知系のプラグインを使っていると、メッセージをカスタマイズしたくなると思います。私はなりました。Growl などはデフォルトでもいいのですが、IRC 通知の場合、ビルド結果で色やメッセージを適切に変えたくなります。

こういうときはどうすればいいのでしょうか。JavaJRuby で通知系のプラグイン、例えば IRC2 Plugin みたいなものを作るのでしょうか。それはコストがかかりすぎるので無いですね。

それでは別の手を考えましょう。IRC で通知するというお題で話を進めているわけですが、IRC を開発ツールとして活用されている方は、Ikachan のような便利ツールも導入されている場合が多いかと思います。この場合、Web API を使って通知できるので非常に捗ります。

curl -F channel=\#jenkins -F message="Jenkins ($JOB_NAME): $BUILD_URL" http://example.com/ikachan

こんな感じで Web APIcurl とかでカジュアルに叩いてやれば通知できちゃいますが、ここで問題が2つほどあります。

  1. Jenkins のビルド後の処理で、上記のような任意コマンドを実行するにはどうすればよいか
  2. 実行できたとして、その中でジョブが成功したか失敗したかのステータスをどうやって取得できるか

まず 1. ですが、これは Post build task を使えば実現できます。このプラグインを導入すると、ビルド後の処理に "Post build task" が選択できるようになり、"Script" 欄に直接シェルスクリプトが書けます。なお、このスクリプト中ではビルド時と同様の環境変数が使えるので、JOB_NAME や BUILD_URL などビルド結果の通知に役立ちそうな値が利用可能です。

さて、前述のスクリプトでは、ビルド結果が SUCCESS なのか FAILURE なのか ABORTED なのかわからないので、まだそこまで便利ではありません。というわけで、2. をどうにかして解決してステータスを取得したいわけです。

ここでリモートアクセスAPIの出番です。Jenkins のリモートアクセス API にはいくつか種類がありますが、ジョブ用のAPIだってもちろん存在します。このAPIを使ってデータを取得すると、実はステータスがわかります!

<mavenModuleSetBuild>
  <action>...</action>
  ...
  <result>SUCCESS</result>
  ...
</mavenModuleSetBuild>

${BUILD_URL}api/xml (/job/{jobName}/lastBuild/api/xml みたいなURL) にアクセスすると、上記のような結果を XML で取得できます。末尾を /json に変えれば、予想通り JSON で取得できたりもしますが、ここでは割愛します。

XML API の場合、の値がステータスそのものになっているので、これを取り出して通知結果に入れてやると、以下のような感じで2行で書けちゃいました!

RESULT=`curl ${BUILD_URL}api/xml | perl -le '$_=<>;print [/<result>(.+?)</]->[0]'`
curl -F channel=\#jenkins -F message="Jenkins ($JOB_NAME): $RESULT - $BUILD_URL" http://example.com/ikachan

簡単でいいですね。でもこれだと色が単一で面白くありません。やはり red-green 的な色の変化はつけたいところなので、SUCCESS なら緑、FAIURE なら赤、ABORTED なら黄色、みたいに結果に応じて IRC 用の色コマンドを埋め込んで通知しちゃいましょう。

RESULT=`curl ${BUILD_URL}api/xml | perl -le '$_=<>;/<result>(.+?)</;printf "\x02\x0301,%02d%s\x0f",{A=>8,S=>3,F=>4}->{substr $1,0,1},$1'`
curl -F channel=\#jenkins -F message="Jenkins ($JOB_NAME): $RESULT - $BUILD_URL" http://example.com/ikachan

1行目がだいぶ長くなりましたが、それでも2行は保ったまま、色まで付いて結果通知できるようになりました!

おわりに

というわけで長くなりましたが、Post build task とリモートアクセスAPIを組み合わせることで、任意の通知をカジュアルにしちゃおう、という一例を示しました。

Post build task プラグインは中々便利で、シェルスクリプトでビルド後処理として任意に書けちゃうわけですから、使い勝手が非常に良いですね。ちなみに、私はビルド処理自体もビルドサポート系のプラグイン(例えば MSBuild Plugin とか Rake Plugin とか)を使わずに、シェルスクリプトかバッチファイル(Windows 用ジョブの時)で書いています。理由は、プラグインだと細かいオプション指定が出来ないことなどがあるからですが、普段からこのような使い方をしている人には、違和感なく使えると思います。

また、リモートアクセスAPIも、ビルド後のフェーズで呼んでやると、ちゃんと今実行したばかりのジョブ結果も普通に取れちゃったりして、中々スグレモノです。データさえ取得できれば、あとはどう調理するか次第ですから、拡張の幅が広がりますね。

そんなわけで、最近個人的にオススメの Post build task + リモートアクセスAPI について簡単に紹介しましたが、プロジェクトなど状況にあわせて、カジュアルに拡張していきたいときの一助になれば幸いです。

明日は誕生日(?)の bleis さんです!お誕生日おめでとうございます!お楽しみに!