読者です 読者をやめる 読者になる 読者になる

クックパッドモバイルアプリの開発体制とリリースフロー

こんにちは、技術部モバイル基盤グループの @slightair です。

今回は、クックパッドのモバイルアプリをどのような流れで開発しているか説明したいと思います。 この記事では技術的な話ではなく、どのようにして、どのようなことを考えて僕らがモバイルアプリを開発しているかに触れたいと思います。

開発体制

クックパッドにはモバイルアプリを専門で開発するようなチームはありません。 必要に応じて、誰でもモバイルアプリ開発に取り組みます。 機能追加・修正を行ったらリポジトリにプルリクエストを送ります。 プルリクエストが来たら、アプリ開発を行うエンジニア同士でレビューします。

様々な修正をひとつのバージョンにまとめるのは、僕が所属する技術部と後述するリリースマネージャーで行います。

リリースマネージャー

バージョンごとに、そのリリースの責任をもつリリースマネージャーをひとり選びます。 リリースマネージャーは、バージョンに含める機能追加・不具合修正の進捗確認、リリース作業、リリース後の監視を行います。 リリースマネージャーがリリースに関する作業を受け持つことで、他の開発者が自分の開発に集中できるようになりました。

リリースマネージャーがやるべき作業をまとめたリリース issue を作成しています。 チェックリストにすることで、何をすべきか、何がまだ終わっていないかがわかるようになり、開発フローをうまく回すことができるようになりました。

f:id:Slightair:20150224181304p:plain:w250:left f:id:Slightair:20150224181315p:plain:w328

リリースマネージャーはアプリ開発者の中から持ち回りで選んでいますが、通常の業務に加えて担当するとなると負担が大きいので、作業の自動化を少しずつ進めようと考えているところです。 例えば、自動的にリリースビルドを作成したりアップロードしたりする仕組みやリリース後監視を楽にするダッシュボードを作ろうとしています。

開発イテレーション

開発では、以下の様な項目を1イテレーションとして回しています。

  • 開発期間(10営業日)
  • テスト期間(3営業日)
  • サブミット、リリース
    • iOSは審査で一週間くらい待った後リリース
    • Androidは 2日おきに 10%、50%、100% と段階的リリース

開発期間開始時に各事業部でタスクを整理して、GitHub Enterprise の issue にします。 issue でどのバージョンにどのような変更をいれるか管理するようにしています。

開発期間10営業日のうち8日目をプルリクエスト受付最終日としています。 これは、開発期間最終日に駆け込みでプルリクエストが大量にやってきてコードレビューが終わらないという事態になるのを防ぐためです。 機能追加が間に合わないとわかった時点で、修正を次のバージョンに回すなどの調整を行います。 開発期間が終わればコードフリーズとし、以降の修正はこのバージョンの修正によっておきた不具合修正など最低限にとどめます。

テスト期間の3営業日では、不具合の洗い出しとその改修を行います。 事業として優先度の高い内容を除くと、多くは前回リリースからの実装差分に焦点を充てて確認を行います。 基本的に、不具合の改修もこの期間内に行います。ここで行うのは主にリリース前の手動テストです。 この期間でなくとも、自動テストや手動テストを必要に応じて回し、不具合があれば修正します。

基本的には決まったペースでイテレーションを回していきたいのですが、必ず守っているわけでもありません。 特に iOS の場合は審査の都合で計画通りにリリースすることができない場合があります。 期日の決まった機能追加があっても、他の修正が原因でリジェクトされてしまったり不具合が起きたりしてリリースできない恐れがあります。 そのため、スケジュールだけでなくバージョンに含める機能の調整を行うことがあります。 全体に影響をあたえるような大きな変更がある場合は、他の修正を次にまわしてもらうなどの調整をしています。

リリース

テスト期間が無事終わったら、Android の場合は段階的リリース、iOSの場合はサブミットして審査が通り次第リリースします。

Android には段階的リリースをできる仕組みがあるので、10%、50%、100% と少しずつ対象ユーザを広げてリリースします。 10%リリースで問題が見つかれば修正して 再度 10%リリースを行います。 段階的リリースを行うのは、不具合によって迷惑をかけてしまうユーザをなるべく少なくするためです。 また、不具合による被害の拡大を防ぐためでもあります。 もちろん一番よいのは 10% リリースにあたったユーザにも不具合を出さないことなのでテスト期間を十分に設けていますが、起きるときは起きてしまいます。 ユーザが増えることで見えてくる不具合もあるので、慎重にリリースを進めています。

リリース可能な状態になったら翌日の午前中にリリース準備・公開作業を行うようにしています。 また休前日にはリリースを行いません。 休日中に不具合が見つかったとしても、きちんと対応することができないためです。

リリース後監視

アプリをリリースした後は以下の項目を確認しています。

  • アクティブユーザ数の伸び
  • APIのエラーレスポンス数
  • APIのエラー
  • クラッシュ数

アプリが利用しているAPIでエラーが増えていれば、なにか不具合につながるような予期せぬことが起きている可能性があります。 アプリのクラッシュ数が増えていたら最悪です。 リリースした日の夕方や翌日の朝など時間を決めて、アプリに異常がないか確認しています。

アプリエンジニア間の連携の取り方

あちこちの事業部にアプリエンジニアがいる状況は、事業部内での意思疎通が図りやすいメリットはありつつも、アプリ開発の足並みを揃えるのが難しいデメリットがあります。 そのため、毎日アプリエンジニアが集まる朝会を開いています。 朝会ではアプリに関する全体連絡やスケジュールの確認、各自の進捗報告などを行っています。 Android, iOS それぞれ 10分程度の軽いものです。 朝会によって、アプリに今何が起きているのかがみんなに伝わります。

また、開発期間の開始やリリース後には社内ブログで周知しています。 これによってエンジニア以外にもアプリのリリーススケジュールを意識してもらったり、アプリのどこが変わったのか伝わりやすくしています。

ふりかえり

少し前の記事「KPTで粘り強く品質改善に取り組んだ話」にもありますが、イテレーションが終わるごとに、そのバージョンの開発期間中に起きたことを少しでもコミットしたメンバーを集めて振り返っています。 よりよく開発を進めたり、良いアプリを作るために少しずつ改善を続けていきます。

おわりに

クックパッドでのモバイルアプリ開発の流れを説明しました。 モバイルアプリの品質を損なわずにどう開発を続けていくのがよいか、アプリエンジニア達で試行錯誤し、今はこの形に落ち着いています。 このやり方が必ずしも正解というわけでもないし、まだまだ困っていることもたくさんありますがより良い方法を考えていきたいと思っています。

/* */ @import "/css/theme/report/report.css"; /* */ /* */ body{ background-image: url('http://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527163350.png'); background-repeat: repeat-x; background-color:transparent; background-attachment: scroll; background-position: left top;} /* */ body{ border-top: 3px solid orange; color: #3c3c3c; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; line-height: 1.8; font-size: 16px; } a { text-decoration: underline; color: #693e1c; } a:hover { color: #80400e; text-decoration: underline; } .entry-title a{ color: rgb(176, 108, 28); cursor: auto; display: inline; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; font-size: 30px; font-weight: bold; height: auto; line-height: 40.5px; text-decoration: underline solid rgb(176, 108, 28); width: auto; line-height: 1.35; } .date a { color: #9b8b6c; font-size: 14px; text-decoration: none; font-weight: normal; } .urllist-title-link { font-size: 14px; } /* Recent Entries */ .recent-entries a{ color: #693e1c; } .recent-entries a:visited { color: #4d2200; text-decoration: none; } .hatena-module-recent-entries li { padding-bottom: 8px; border-bottom-width: 0px; } /*Widget*/ .hatena-module-body li { list-style-type: circle; } .hatena-module-body a{ text-decoration: none; } .hatena-module-body a:hover{ text-decoration: underline; } /* Widget name */ .hatena-module-title, .hatena-module-title a{ color: #b06c1c; margin-top: 20px; margin-bottom: 7px; } /* work frame*/ #container { width: 970px; text-align: center; margin: 0 auto; background: transparent; padding: 0 30px; } #wrapper { float: left; overflow: hidden; width: 660px; } #box2 { width: 240px; float: right; font-size: 14px; word-wrap: break-word; } /*#blog-title-inner{*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-position: left 0px;*/ /*}*/ /*.header-image-only #blog-title-inner {*/ /*background-repeat: no-repeat;*/ /*position: relative;*/ /*height: 200px;*/ /*display: none;*/ /*}*/ /*#blog-title {*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-image: url('http://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527172848.png');*/ /*background-repeat: no-repeat;*/ /*background-position: left 0px;*/ /*}*/