プルリクエスト(Pull Request)、とても便利な仕組みですよね。
マージがボタン一つでできますし、ソースコードレビューも格段にやりやすくなったと感じています。
私の所属しているプロジェクトでは、Bitbucketのプルリクエストを使ってソースコードレビューを行っています。
プルリクエストは、全体テストを一回手元で通してから送るのがマナー です。
そうでないと、レビューアーが問題なしと判断してマージボタンを押した後に、
といった問題が発覚することがあります。結構よく起こります。
もちろん、Jenkins等のCIツールを使っているので、問題はすぐに発覚します。
しかし、問題を修正するまではソースをpullできない状態になるわけで、他の開発者に迷惑をかけてしまいます。
「テスト通してからプルリクエスト出すとか、あたりまえじゃん」と思われるかもしれません。
しかし、毎日スケジュールに追われながら開発をしていると、そんな当たり前のこともしなくなってしまうものです。どうしたものか。何か解決策は無いものでしょうか。
私たちのプロジェクトでも、初期の頃は全体テストを手元で通してからプルリクエストを送っていました。
しかし、プロジェクトが進むにつれて、以下の問題が発生しました。
私たちのプロジェクトで全体テスト実行がどのくらいかかるのか。Jenkinsでテストを実行したときのビルド時間は下図のような感じです。
マシンが遅い、他のJobも一緒に走っているため、開発環境で動かしたときよりも若干遅いなど要因が他にもありますが、それでも1時間56分はかかりすぎです。
ローカル開発環境で、全体テストを走らせている間は、ただでさえ遅い開発マシンがより一層おそくなります。
我々は常にスケジュールに追われています。その間開発が止まるとなると時間の無駄です。
そうなると、もはや全体テストを手元で実行するのは面倒になり、結果として、
となり、そのままテストの失敗した状態がしばらく続くという最悪の事態となります。
この問題を防ぐためには、プルリクエストを出した段階で、そのプルリクエストに対しテストを実行してくれるような仕組みがあればよいわけです。
ついでにコメントとしてテスト結果もかいておいてくれるとよいですね!
Githubを使っている方々。よかったですね。既にその仕組みはあります。
Jenkinsからプルリクエストをテストするなら、Github pull request builder plugin で実現できます。
GithubはAPI経由でプルリクエストの情報を取得できるので、
ということができます。
さて、Bitbucketにもその仕組みが欲しいですね。残念。BitbucketはAPI経由でプルリクエスト一覧を取得する仕組みがないのです( 2013/6/9時点 )。
Pull Request APIの要望はあがっているのですが、いつ実装されるのかが不明です。
実装されるまで待てない、いまさらGithubに移行なんてできない。
なければ作ればいいじゃないか!
ということで作ってGem bitbucket-api-extension として公開しました。
使い方の詳細などはここでは説明しませんが、上記gemを利用することで、プルリクエストの一覧取得、プルリクエストの詳細情報(revision, branchの情報等) が取得できます。
プルリクエスト一覧さえ取得できてしまえば、あとはJenkinsマシンでテストするだけです。わざわざ図にするほどのものではないですが、イメージとしては下図のような感じです。
我々のプロジェクトでは、 PRTester というプルリクエストテストのためのプログラムを作りました。
まったく汎用的ではありませんので、他のプロジェクトでは使えないと思います。
ソースをみていただければわかると思いますが、コマンドをべた書きしてます。これはひどい。
テスト結果は下記のように、プルリクエストのコメントとして書き込まれます。
単純な仕組みですので、PRTesterみたいな簡単なスクリプトをご自分のプロジェクト用に作ってみてはいかがでしょうか。
プルリクエストもテストできるようになって問題解決!と思いきや、そうもいかず。
テスト実行が遅いという問題は相変わらず残っています。
一日に何個もプルリクエストが出される状態で、テストに1、2時間かかっているのでは、いつまでたってもテストされないプルリクエストがでてきてしまいます。
そうなると、プルリクエストのテスト実行前にマージしてしまい、Jenkinsが怒りだすという事態も発生するようになってきました。最悪です。なんのためにPRTesterを作ったのか。
やはりテスト実行自体を早くする必要がありそうです。
ここからテスト実行を早くするための仕組みを検討しだすわけですが、それは次回紹介いたします。