Webサービス開発現場から / 近頃の開発のやり方 ・・・ Github と Pull Request とコードレビュー

先日プレスリリースが出たのですが、KAIZEN platform という会社で技術顧問などをやっています。それから、一昨日自分も出たWebアプリケーション開発に関する勉強会 (資料) を開いたじげんという会社でも少し前から同じように顧問のような形で携わっています。

自分が関わっている会社のPRも含めて、すこし、2013年現在のWebサービス開発の現場感、やり方みたいなものを書いてみたいと思う。ただ、自分の利益があるところの話だけではフェアではないので、Webエンジニアならよく知っているであろう Qiita を運営しているインクリメンツの様子も合わせて紹介する。

KAIZEN platform

KAIZEN platform が提供しているサービスは planBCD という A/B テストの SaaS で、Webサイトのコンバージョンだとかを画面の構成要素を変えて効果測定したいとか、そういう時に使うもの。

システム構成は大きく

  • A/Bテストの設定をしたり結果を受け取ったりするための Webアプリケーション
  • JavaScript のビーコンからログを受け取って格納して計算したりするログシステム

の二つに分けられる。

Webアプリケーションは Rails + JavaScript で、ログ周りも基本 Ruby で書かれている。インフラはすべて AWS に置いていて、社内には開発用のサーバーも含め、物理サーバーは一台もない。ビーコンはクライアントの Webサイトに貼り付けられて、その1HTTPリクエスト毎に planBCD のシステムにもアクセスが来るので、バックエンドはそれなりにスケーラブルに構成される必要がある。

Github と Pull Request ベース開発、テスト自動化

この辺をどうやって開発しているか、というのをざっくり一言でいえば「Github を使って Pull Request ベースでスクラム」みたいな感じだ。Rails のコードも JS のコードもすべて Github のプライベートレポジトリに置いている。

Pull Request ベースの開発は、最近クックパッドid:secondlife の発表なんかでもあった。これとほぼ同じやり方である。


ソースコードへの変更は基本的に、Pull Request を通して行う。リモートブランチに直接コミットしたり、ということはしない。そして、本体にマージする前にかならずその Pull Request のコードレビューを行う。コードレビューってどうやったら続くんですか? みたいな話がよくあるけれども Pull Request はレビューが間に挟まることが前提になっているので、Pull Request ベースで開発すると自然とレビューするような流れになる。

コードの変更に対してはすべてテストを書いていて継続的インテグレーション (CI) している。CI には Jenkins ではなく、CI as a Service な Circle CI を使っている。これは、プライシングその他の理由でビジネス用にも使い易い Travis CI みたいなものだと思えばいい。git push の度に Circle CI が Rails 用のコンテナを立ち上げてインテグレーションテストを実行し、何かあったら通知が飛んでくる。

このテストを書いて CI して、Pull Request でコードレビューして・・・というやり方は、前回の YAPC::Asia の感想エントリでも書いたとおり、Web開発のベストプラクティスとして現場に根付きつつあるやり方だ。ただ、トレンドだからこういうやり方をしているというよりは立ち上がったばかりのスタートアップで、スピード感は必要なのに人はいないと、そういう中でどうするべきかというときに必然的に辿り着いたのがこのやり方だった・・・というのが実感として面白い。

テストを自動化しておけば何かのリリースの度に人手でテストをする手間を省けるし、コードレビューをすることでバグを未然に防いだり設計がおかしなものがそのままマージされるリスクを減らせる。サーバーを自前で運用するのにも人的リソースが要るし・・・というので AWS や Circle CI のようなクラウドサービスを積極的に使う。たぶん、昨今のスタートアップでエンジニアリングを真面目にやろうとしている企業は、どこも同じような結論に達しているのではないかと思う。

この開発フローで、エンジニア数名で開発していっている。

エンジニアのコミュニケーション

KAIZEN platform が少しユニークなのは、リモート環境で関わっている人が結構多いというところだ。社員のエンジニアはもちろん、一緒に開発している協力会社 (ハートレイルズさん) もいるのだが、そのあたりも基本リモートでやっている。このとき彼らも Github と Pull Request とコードレビューのサイクルの中にいて、協力会社というよりほぼ同じチームという感覚で開発できているのがちょっと面白い。

そしてリモートワークとはいえ、スクラム的な、ある程度短い期間を切ってのイテレーションをちゃんと回そう・・・ということでJIRAGreenhopper を使ってカンバン形式でタスクとストーリーの見える化を行っている。この辺はいろんなツールがあって激戦区だけど、社員の坂田さんこと @sakatam が JIRA を使い慣れていたということで、彼がスクラムマスター的な役割も担いつつでの導入となった。

写真はエンジニアのスタンドアップミーティング・・・って座ってるのでスタンドアップじゃないけど、それに相当するミーティング。こんな感じで Google Hangout で顔を写して会話して、画面共有で JIRA のカンバンを見ながらスプリントを進める。モニタには Apple TV が繋がっていて、画面に何かを映したいときは AirPlay で飛ばす。

普段のエンジニア同士のコミュニケーションは HipChat を使ってチャットで行い、チャットで流れて困るようなドキュメントは今のところ Github Issue にまとめたりしている。

なんとなく、スタートアップ的なスピード感が伝わってるだろうか。

これからの課題は、基本的な開発プロセスは回っているのをどうより効率化していくか、一方で速いスピードに対して中長期ロードマップをどのように組み立てていくか、DevOps 的な部分や手元の開発環境の整備みたいな後手に回りがちなところ、あたりである。その辺を一緒にやってくのが自分の仕事だったりする。

Qiita (インクリメンツ)

次は Qiita や Qiita Team を作っているインクリメンツ社。インクリメンツ、というよりも Qiita という名前の方が馴染みが深いのではないかと思う。サービス内容については、まあこの blog を見てくれる人たちには説明不要だと思う。

インクリメンツもやはり、まだ人数数名のスタートアップというところ。Qiita はもともと CEO の yaotti (・・・ 彼は元々ぼくがはてなにいた頃にインターンに来て知り合ったので、呼び捨てである) が一人で立ち上げたサービスだったが、徐々に大きくなって社員数名を雇用するまでになった。立派だなと思う。

こちらオフィスの様子。ここは元々、今は mixi で COO をやっている id:kawasaki の kamado 社のオフィスだった場所。

Qiita も、Rails で書かれていてサーバーはすべて AWS にある。またランディングページそのほかの Qiita 本体ではないところのサイトを動かすのに Heroku も利用していると言っていた。オフィスの中にはやはりサーバー類はない。

Github、Circle CI、Pivotal Tracker …

Qiita の開発も、Github を使った Pull Request ベースの開発によって行われている。緊急の修正とかそういうのでない限り、基本は Pull Request を飛ばして、誰かがレビューしてその上でマージするそうだ。コードレビューの担当は誰というのは特に決まっておらず、誰かが自発的にレビューを行うというのでいまのところは回っている。ただ、場合によっては各々自分のタスクに集中して未レビューのパッチが溜まってしまうことが時々あるそうで、その辺は今後の課題ということだった。

Pull Request ベースで開発している、ということもありテストはしっかり書いている。特に Rails アプリケーションのモデル周り。決済など、バグ混入が怖い部分はコントローラも含めより念入りにテストしている。最近は capybara-webkit を使っての E2E テストも書くようになった。

テストの CI はインクリメンツもやはり Circle CI を使っている。Jenkins を動かすとそのために運用するサーバーが最低一台は増えてしまうので、やはり小さなスタートアップでは極力それを避けたいというのもあるだろう。同じような理由で、* as a Service 系のサービスをいろいろと積極的に使っていて、Rails アプリケーションの監視と数値化には NewRelic を、例外発生時のバグレポートには Sentry、ユーザーサポートには zendesk を・・・という具合だ。

タスク管理はストーリーベースの Pivotal Tracker。最近の Web 開発によくある「ゆるいスクラム」的なものをこれを使って回している。ミーティングはスクラム的な文脈の短い朝会を毎朝 10:00 からやって、週一回の定例にあとは金曜夜に振り返り的なゆるいミーティングだけで済ませているそうだ。自社サービスを開発運用し続けていく SaaS サービスの開発現場では、こんな風にスプリントミーティング的なきっちりとした感じではなくゆるく繋がるミーティングを続ける、というのもよくある風景だと思う。

Qiita Team

社員同士のコミュニケーションは HipChat によるチャット、それから自分たちで作っているサービス Qiita Team。チャットだけでは流れがちなストック寄りのコミュニケーションは、仲間内だけで使える Qiita 的なこの Qiita Team に書き込む。日報とかも。いわゆる、自分たちのサービスを自分たちで使ってという Eating our own dog food というやつですばらしいと思う。

ちなみに、自分ははてな在籍中は Qiita Team がカバーするのとよく似たツールのはてなグループ を使ってこの辺の情報共有や連絡そのほかを行っていたけど、これはエンジニアの仕事ととても相性がよい。作業記録とか、アイデアとか、この処理はこう書いた的なことを何でもいいからどんどん書き込んでいくと周囲のエンジニアからスターがついたり、コメントがあったりでフィードバックが返ってきたり、後から検索できたり云々。まもなく発売の Web+DB PRESS Vol.77 にはクックパッドの開発現場での情報共有についての特集記事があるらしいが、クックパッドでも同じようなツールを内製して・・・というか、はてなから転職したエンジニアがはてなグループがないのを苦にしてオリジナルのそれを開発したと言っていたし、その辺の話も載っていると思う。

そして同カテゴリのサービスになる Qiita Team に関しては Increments は和製 GitHub の夢を見るか? この辺りのエントリも詳しい。

話がそれた、インクリメンツの話。

Boxen

最近エンジニアが増えてきたこともあって、各エンジニアの手元の開発環境をどう整えるかというのが課題になってきたそうだが、最近 Boxen を導入して解決したそうだ。Boxen は Github の中の人が作った、ローカルマシン用のプロビジョニングツールみたいなもので、これを使うと各開発者の OSX のソフトウェアセットアップを (内部では Puppet が動いて) 自動化且つ共通化できるので、各種ミドルウェアのバージョンを統一できる。

KAIZEN もそうだしインクリメンツもそうだけど、人も少ない、お金もまだ無駄遣いはできない、あれもないこれもないというスタートアップでは日々の仕事で無駄なことが発生するとその分会社全体のパフォーマンスが目に見えて落ちるので、やらなくていいことはやらないように色んな工夫をする・・・というかせざるを得ない状況にある。そういう状況が、こんな感じのやり方、開発プロセスに行き着く理由のひとつだと思う。

じげん

最後に紹介するのはじげん の例。

先の二つは立ち上がって間もない、その名のとおりスタートアップなベンチャー企業だったが、こちらのじげんは設立は 2006 年で社員も結構いるしで、ベンチャー的な雰囲気は残しつつもスタートアップのフェーズは追えて拡大期に移行しつつある。事業は求人系や賃貸系の複数の情報サービスを、Webサービスとして提供するのが主なところ。

KAIZEN やインクリメンツは最近起業したばかりでまだ人数も少ないということで、いろんなプロセス、ツールが新しい。一方のこちらは、すべてのアプリケーションを Rails で書いているとはいえ、一番古いサービスの Ruby のバージョンは 1.8 で、Rails に至っては 1.2 とかそんな具合だ。本当はこれらを Ruby/Rails のバージョンアップに合わせてバーンアップさせていくべきだったのだろうが、テストも書いていなければ、その作業に割り当てるエンジニアもいなかった・・・ということで気づけば「レガシーな Rails アプリケーション」を抱えることになってしまった。

これまでの文脈から一転して、じゃあなんでこの会社の例を紹介しようというのか。そういう状況から色々プロセスに手を入れていって、良いやり方に移行していっているという例だからである。今は Rails 4 を使って、ユニットテスト/E2Eテストを書いて Jenkins で CI し、Github 上でコードレビューを行ってデプロイ。それからサーバーのプロビジョニングは Chef で・・・など DevOps も含めて、開発フローが確立されつつある。ほんの半年ちょっと前まではこのどれも行われていなかった。

多分、スタートアップが新しいやり方、新しいツール、建前より本音を優先するスタイルみたいなことを実践できるのはスタートアップだからであり、そうでない立場にいる人からは別世界の話のように聞こえると思うが、一方のこのじげんに関しては、そうではない、比較的よくありそうな課題群から出発しているという例に見えるだろう。

エンジニアは今は十数名。だいたい一つのサービスにつき 2〜3人くらいのエンジニアがアサインされて、開発を行っている。開発プロセスの改善に手をつけるまでは、各サービスのエンジニアがそれぞれ独立して自分のサービスを開発していて横串でそれらのやり方を標準化したりといったことはあまり行われていなかった。また、自分のサービスのインフラは基本そのサービスのエンジニアが片手間で運用していて、専門の運用部隊はいない。だから、どのサービスでどういうサーバー設定が行われているか全体を把握している人はいない・・・みたいなそんな状況だった。「あ〜、あるある」なんて声が聞こえてきそうだ。

そういえば先日 DevOps Day Tokyo でクックパッドの mirakui さんが発表されていて (発表の内容は http://www.publickey1.jp/blog/13/devopsdevops_day_tokyo_2013_2.html この記事なんかにある。必読)、その途中のスライドにこんな画面があった。

じげんが置かれている状況というのは、だいたいこの、mirakui さんが入った前後のクックパッドの当時の状況によく似ているのではないかなと思う。つまり、ここから開発標準や体制を整えていき、今後の事業の拡大や開発の複雑性増大に対して備えていきたい・・・そういうフェーズ。

Github の導入から

そんなわけで、横串での開発プロセスやインフラ運用方法を新しくしていきましょうと手を付け始めたのが半年とちょっと前。

最初は課題整理をして、現状把握をし、それをどんなやり方にしていきたいかというディスカッションをした。そのゴールイメージを作るのはそんなに難しくない。昨今では同じような事業をやっている他者の開発体制の情報が、このクックパッドのスライドのように公開されているから、なんとなく、こういうのが今どきのやり方だろうねという共通理解が最初からみんなの中にあった。

で、まずはどこから手をつけましょうかということで Github を導入した。少し前に開催したはじめるDevOps という勉強会でじげんのエンジニアリーダーの浅沼さんが当時の様子を話していたけれども、期末か何かの全社ミーティングで新しい開発プロセスのロードマップと、それに伴ってまずは Github を使い始めます・・・という話をしたら嬉しくなった現場のメンバーから握手を求められたとかそんな話をしていたのが印象的だった。

テストとコードレビューの習慣化

次はやはりテストを書く習慣を作りましょう、という話になっていく。当然、最初はどういうところをどのぐらいテストすればいいのか分からないという状態が続く。ただ、コツコツとやっていきつつ「カバレッジ 100%は目指さない」とか「モデル周りを重点的に書いて」とか「とりあえず最初は書きやすいところ、すぐに書けそうなところから」みたいなベストプラクティスを吸収していくうちに、なんとなくコミット毎にテストを添付するみたいなことができるようになってきた。

そして、コードレビュー。

インクリメンツもそうだし、id:secondlifeクックパッドのプレゼンでもそう言っていたが、この両社なんかはレビューが各チーム内で自発的に回るような空気作りができている。でも、まったくコードレビューをやったことがないチームでは、Github を渡したからといっていきなりレビューし始めるなんてことは当然おこらない。この辺は、YAPC::Asia での HIROCASTER さんの発表 GitHubでつくる、たのしい開発現場 なんかを見てても、それが根付くまでの段階があるというのがよく分かる。

ところで、コードレビュー、というとだいたい品質を保証するとかバグをなくすとか、そういう実利的な部分にばかり目が行きがちなので、ついつい、ベテランのエンジニアや要件をよく知っている人がレビュワーを担当するのかな? と考えてしまう。そういう忙しそうな人にレビューをしてもらうとか、そういうフローを回して貰うコストをどうやって考えたらいいのか、云々・・・。

だがしかし、実際にはコードレビューは「自分が書いたコードを誰か他の人に見てもらえる/見られる」という状況そのものが一番重要だったりする。つまりレビューをしてくれる相手はベテランでなくても構わない。

よくよく考えてみれば、コードレビューというフローがなければ、自分が書いたコードなんて有事の際以外にはなかなか他人が見るなんてことはない。それがそうでなくなるというのは、それだけで大きな変化だし、そこから「人が見るなら綺麗に書いておこう」とか「新人が見るのにひどいコードのまま push するわけには」とか「こんなコピペしてたら絶対指摘されるよなあ」みたいな心理が生まれる。その心理を生み出すことが大切で、品質保証やバグ解消なんかを主目的にするのはその次の段階でもいいと、個人的には思っている。

そんなわけで、じげんではどうしたかというと、コードレビューの担当を日替わり交代制にした。これは自分が以前にいた会社で、ユーザーサポートから依頼のあった対応案件をどのエンジニアが対応するかというのを日替わりで回すのでとてもうまく回っているのを思い出して、レビューもそうしてみたらどうか、という話から出たアイデアだった。これは思いの他うまく機能したそうだ。

習慣化のための道具

せっかくテストを書いてコードレビューをするというフローを始めたのだから、やるのであればそれもなるべく正しい方法でやりましょう。ということで Github で Pull Request を基本にし、Jenkins で CI が回るようにあらかじめプロジェクトをセットアップして各開発者の端末には Jenkins Notifier なんかを入れて、とかとか、周辺環境も整えていった。

いや、むしろテストやコードレビューを習慣化させるために Github + Pull Request や Jenkins があるというのが実際のところだ。やり方だけみんな知っていても、それがワークフローとして確立していなければ長く継続するのは難しい。コードレビューだって、レビューをすることにはこんなに良い効果があるって、Google とかの話が聞こえてきたのはもう何年も前だったけど、最近になってようやく巷の Webサービスの開発現場でそれが無理なく定着してきているのは Github というそのワークフローを実現するための道具が手に入ったからだと思う。

結果として、この半年間で見違えるほど開発の中身が見える化されて、最近では浅沼さんをして「Pull Request / レビューなしの開発はあり得ない」といわしめるほどになった、とのことです。

この開発フロー、新しいサービスでは Rails を含め新しいからやりやすいのだけど、後ろのシステムがレガシーだとなかなか適用が難しかったりする。そこをどう解決していくか、一部の取り組みを全体に拡大していくまでみたいなところが今後の課題。とはいえ、ちゃんと正しいやり方で開発を進めるんだというカルチャーの火種はできあがったので、いろいろ困難はあると思うけど、それが全体に浸透していくのは時間の問題だと思う。

まとめ

長くなってしまったけれども、KAIZEN platform Inc.、インクリメンツ、じげん三社のWebサービス開発現場からでした。自分でも書いてみて良く分かったけど、やっぱり Github + Pull Request + コードレビューというのがどの会社にも共通して、開発プロセスのデザインの根幹になっているなと思いました。

Github といえば、前回 YAPC の感想に合わせて

事実、かつて当たり前のようにスタートアップが Rails を採用することがニュースになった時と同じように、昨今のスタートアップは当たり前のように Github でコードをホストして、テストを書いて、Pull Request をして CI をするようになってきている。これはサービス開発の現場に定着していくやり方になると思います。

てなことを書いたけれども、具体的にそれがどういうことなのか、というのを知って貰うのにちょうど良い例というのが、そもそもこのエントリを書くきっかけではあったわけです。(もちろん、自分の携わっている2社、それから個人的にがんばってほしいと応援しているインクリメンツの知名度向上に貢献したいというのも理由の半分以上ですけどね。)

そのほかの事例も知りたいなあという人は、エントリ中で紹介したクックパッドの例とかあとは最近自分が見た中では

この辺もいいと思う。これらを通してみると、共通して使って要る道具とか、あるいはその根底にある共通の考え方や哲学っぽいものが発見できるんじゃないかなと思います。

ちなみに今回紹介した三社はいずれもエンジニアを積極採用しているそうなので、自分もこういう開発プロセスとかやり方の開発を経験してみたいとか、おれにもやらせろ! という人は履歴書を送ってみるといいかもですね。文章に書き起こすの大変だったんで、これくらいしっかり宣伝させてもらって締めとします。

おわり。