jenkinsで全てのブランチをテストし続ける

jenkinsでCIをしている時に,レポジトリへのpushがあるたびに,pushされたブランチをテストしたいことがあります.一つのブランチだけをテストするのではなくて,全てのブランチを逐次テストしておくってことです.さぁどうしよう.

おおまかな流れは以下

  1. レポジトリへのpushをjenkinsに通知
  2. gitプラグインでmasterブランチに移動
  3. そのpushの情報をjsonで受け取る
  4. jsonからブランチ名を取り出してチェックアウト & pull
  5. テスト

push通知 -> masterブランチ取得まで

githubレポジトリ設定からWebhooksを設定

f:id:Hi_king:20140403161514p:plain

Webhookを受け取る準備(jenkinsのプロジェクト設定)

  • ビルドのパラメータ化 -> 文字列 -> payload
    • このpayloadというパラメタがgithub webhookで勝手に付与されるもの(jsonで)
  • ビルドトリガ->リモートからビルド -> 先ほどつけたtoken

gitレポジトリをビルドする準備

  • gitプラグインをjenkinsに入れておく
  • jenkinsの公開鍵(/var/lib/jenkins/.ssh/id_rsa.pub)をgihubに登録しておく
  • ソースコード管理 -> Git -> Repository URL -> 対象レポジトリ
  • ソースコード管理 -> Git -> Branches to build -> master
    • この時点でブランチ名を取得する方法が思いつかなかったのでとりあえずmasterにしておいてあとでcheckout

ここまでで、レポジトリになにかpushがあるたびにjenkinsがmasterブランチを取得してくる、ことができるようになりました.

payloadからパラメタ展開 -> テスト

あとはjenkinsのプロジェクト設定の"ビルド -> シェルスクリプト"にベタベタと書いていきます.

このシェルの中では$payloadという変数でgithubから渡されたjsonにアクセスできるので,こっからjqコマンドレポジトリ名を取り出すだけ. レポジトリ名は"ref"というキーで入ってたので echo $payload|jq -r '.ref'で取得 (-rは生の文字列で出力という意味). 結局jenkinsに書いておくシェルスクリプトは以下になります.

git fetch origin
git reset --hard origin/`echo $payload|/usr/local/bin/jq -r '.ref'|sed "s/refs\/heads\///"`

# このあとにやりたいテストをかく

※checkout,pullじゃなくてreset --hardに修正しました

おわりに

  • 全ブランチの継続テストができました
  • これでテストし忘れる開発者がいなくなる
  • シェルでやる以外にいい方法ありそうだけどな…
  • このテスト結果を開発者ircに流して運用しています