Share
Embed
Google Play Consoleのリリーストラックを有効活用してリリースフローの最適化を行った話
DroidKaigi 2019での発表スライドです。
02/08 (金) 18:30〜 Room4
https://droidkaigi.jp/2019/timetable/70900
もん
February 08, 2019
Transcript
47 slides
-
クックパッドアプリの開発体制 • リリースサイクルを回し開発を行う ◦ 開発期間 ◦ テスト期間 ◦ リリース期間 •
複数の部署にエンジニアがいて、それぞれの部署で持っている機能が違う ◦ 会員獲得、広告、投稿、検索、技術基盤など -
会員獲得 検索 技術基盤 開発期間 テスト リリース 開発期間 テスト リリース 開発期間
テスト リリース v18.1 v18.2 v18.3 1week 1week 1week Google Play 段階公開 クックパッドアプリの開発フロー (〜2017) -
開発期間 テスト リリース 開発期間 テスト リリース 開発期間 テスト リリース v18.1
v18.2 v18.3 1week 1week 1week クックパッドアプリの開発フロー (〜2017) リリース マネージャー 会員獲得 検索 技術基盤 -
開発期間 テスト リリース 開発期間 テスト リリース 開発期間 テスト リリース v18.1
v18.2 v18.3 1week 1week 1week クックパッドアプリの開発フロー (〜2017) 会員獲得 検索 技術基盤 • リリーススケジュールの設定 • キックオフ, 触る会, KPT会の調整・実施 • 開発期間中の進捗管理・状況確認 • アプリのバージョンアップ • Google Playへのapkアップロード • リリース後の監視作業 (バグ報告、お問い合わせなどの監視 ) • etc.. リリース マネージャー -
クックパッドアプリの開発フロー(〜2018年前半) • リリースマネージャを2人に分割 ◦ 「エンジニアが必要な作業」「エンジニア以外でも出来る作業」 ◦ 別々の人間が行うことでエンジニアの負荷を分散 • 経験則で作っていたリリーススケジュールを一定の規則性をもたせて作成 ◦
毎週月曜日に開発が終了、翌週リリース開始、などのスケジュール固定化を図る ◦ スケジュール調整の問題解決に向けて -
クックパッドアプリの開発フロー (〜2018前半) リリース マネージャー • リリーススケジュールの設定 • キックオフ, 触る会, KPT会の調整・実施
• 開発期間中の進捗など管理・状況確認 • アプリのバージョンアップ • Google Playへのapkアップロード • リリース後の監視作業 (バグ報告、お問い合わせなどの監視 ) • etc.. -
クックパッドアプリの開発フロー (〜2018前半) リリースマネージャー (ディレクター) リリース作業者 (エンジニア) • アプリのバージョンアップ • Google
Playへのapkアップ ロード • リリース後の監視作業 (バグ報 告、お問い合わせなどの監視 ) • etc.. • リリーススケジュールの設定 • キックオフ, 触る会, KPT 会の調整・実施 • 開発期間中の進捗など管理・ 状況確認 • etc... -
クックパッドアプリの開発フロー(〜2018年前半) • リリース作業者の負担は減ったが、リリースマネージャーとリリース作業者のコ ミュニケーションコストが発生 • スケジュール調整は健在していて根本解決していない ◦ 各種MTGの調整 ◦ スケジュール遅延時、リリース中止時に各部署との調整
• リリースの間隔が長いため、高速な価値検証サイクルを回しにくい ◦ 短くしようにも人間によるオペレーションが一番のボトルネックになっている -
新・クックパッドアプリのリリースフロー • コンセプトは「機械に人間が合わせる」 • 機械によって自動でリリース作業が実行される • 人間のオペレーションを極力減らし、様々な作業を自動化 ◦ リリースサイクルを短く出来るため、高速な価値検証・不具合修正を行える ◦
機械的に実行することでスケジュールの延期などが発生しにくい構造に -
新・クックパッドアプリのリリースフロー 開発終了 テスト開始 リリース v19.1 開発終了 テスト開始 不具合により リリーススキップ v19.2
• 毎週決まった曜日・時間にリリース用のAPKを生成し、アップロード • リリース用のAPKに対して自動テスト, 開発者によるチェックを実施 • 両者のチェックによりリリース可能かどうかを判断 ◦ リリース可能=そのままリリース(人間が判断し手動で公開) ◦ リリース不可能=その週のリリースを中止、次のリリースまでお預け 1week 1week v19.3 開発終了 テスト開始 機能追加 不具合修正 -
新・クックパッドアプリのリリースフロー 開発終了 テスト開始 リリース v19.1 開発終了 テスト開始 不具合により リリーススキップ v19.2
• 開発期間, テスト期間, リリース期間の短縮 ◦ テストの自動実行、手動テストの整理 ◦ 段階公開の廃止 • 調整作業が必要なMTG, 作業などの見直し ◦ キックオフ、触る会、 KPTの廃止 ◦ リリース後監視の自動化 1week 1week v19.3 開発終了 テスト開始 機能追加 不具合修正 -
リリースマネージャー (ディレクター) リリース作業者 (エンジニア) 新・クックパッドアプリのリリースフロー • アプリのバージョンアップ • Google Playへのapkアップ
ロード • リリース後の監視作業 (バグ報 告、お問い合わせなどの監視 ) • etc.. • リリーススケジュールの設定 • キックオフ, 触る会, KPT会 の調整・実施 • 開発期間中の進捗など管理・ 状況確認 • etc... -
リリースマネージャー (ディレクター) リリース作業者 (エンジニア) 新・クックパッドアプリのリリースフロー • 機械による自動実行 • リリース用APKの公開 •
アプリのバージョンアップ • Google Playへのapkアップ ロード • リリース後の監視作業 (バグ報 告、お問い合わせなどの監視 ) • etc.. • リリーススケジュールの設定 • キックオフ, 触る会, KPT会 の調整・実施 • 開発期間中の進捗など管理・ 状況確認 • etc... -
なぜfastlaneを選んだのか • Groovy書きたくない ◦ Gradle PluginにもGoogle Play Publisher APIを実行するものはある ◦
個人的に、リリース用のタスクを gradleで管理したくない • iOSではfastlaneが主流で、クックパッドiOSアプリもfastlaneを使用 • 社内の配信基盤へのアップロードなどの仕組みを共通化しやすい -
fastlane sample ## fastlane/Fastfile platform :android do lane :upload_to_google_play do
supply( package_name: "your.app.package.name", json_key: "path/to/json_key", apk: "path/to/apk/file", track: "alpha" // "production", "beta", "alpha", "internal", "rollout" ) end end • json_key: Google Play Publisher APIを使うためのAPI Key • track: 後述 • コマンドラインから実行 $ fastlane android upload_to_google_play -
Google Play Console トラック トラック fastlane track 公開範囲 リリース前レ ポート
特徴 製品版 production 一般公開(誰でも見れる) ✕ オープンテスト版 beta 一般公開(誰でも見れる) 参加人数を絞ることが可能 (1000 人〜) ◯ クローズドテスト 版 alpha 限定公開(テスター登録者のみ) 2000人まで登録可 Googleグループ登録可 ◯ 内部テスト版 internal 限定公開(テスター登録者のみ) 100人まで登録可 ◯ 公開から反映までが早い -
Google Play Console リリース前レポート • Firebase Test Labを使った自動テストを実行 ◦ クローラによるモンキーテスト
◦ 複数の端末で、表示やパフォーマンス、セキュリティの問題をチェック • Roboスクリプトをアップロードするとクロール前に実行 • 結果の通知はメールのみ (!!) -
クックパッドアプリでのトラック活用 v19.1 v19.2 機能追加 不具合修正 ①masterにマージされるたびに内部テスト版にアップロード ②毎週決まった日時に 内部テスト版をスクリプトで クローズドテスト版に昇格 ③テストが完了したら
クローズドテスト版をコンソールから 製品版に昇格 • Apple Storeと違いサブミット時に制限などないので、ひたすらアップロードする形式 にした -
バージョンを自動で更新する ## fastlane/Fastfile platform :android do lane :build_and_upload_new_version_code_apk do versionCodes
= google_play_track_version_codes( package_name: "com.cookpad.android.activites", json_key: "path/to/json_key", track: "internal" ) # versionCodesはarrayかつ文字列で返ってくるため # 最大値をIntに変換しつつ+1する versionCode = versionCodes.max&.to_i&.+1 || 0 # gradle実行時にparameterで渡してversionCodeを上書き出来るようにする gradle( task: "assembleRelease", properties: { "versionCode": versionCode } ) # ビルドしたapkをアップロード supply(...) end end -
バージョンを自動で更新する // app/build.gradle def defaultVersionCode = ~~ android { defaultConfig
{ // 引数で渡された propertyを見て、アプリの versionCodeを指定する if (project.hasProperty("versionCode")) { def newVersionCode = project.property("versionCode") versionCode Math.max(defaultVersionCode, newVersionCode) } else { // 引数になかった場合は default値を使用 versionCode defaultVersionCode } } } -
クックパッドアプリでのバージョニング • versionCodeの自動化は出来たが、出来ればある程度人間が識別可能なバー ジョンも用意したい • 今まではversion.propertiesに以下のようなフォーマットで用意していた # version.properties version.major =
19 # 年下2桁 version.minor = 4 # リリースサイクル回数 version.patch = 0 # 過去のバージョン互換 version.build = 1 # 段階公開時のパッチリリース回数 -
クックパッドアプリでのバージョニング • 自動化するために 「リリースサイクル回数」⇒「リリースが実行される週番号」に変更 • patch, buildに関しては、versionCodeの自動更新で更新される値とした # version.properties version.major
= 19 # 年下2桁 version.minor = 4 # 週番号 (2019年4週目) -
version.propertiesを自動更新 // build.gradle // version.propertiesを更新するタスクを定義 task(bumpUpVersion).doLast { def calendar =
Calendar.getInstance(Locale.JAPAN) calendar.add(Calendar.WEEK_OF_YEAR, 2) def major = (calendar.get(Calendar.YEAR) % 100).toString() // 年下2桁 def minor = calendar.get(Calendar.WEEK_OF_YEAR).toString() // 週番号 def vProperties = new Properties() vProperties.setProperty("version.major", major) vProperties.setProperty("version.minor", minor) rootProject.file('version.properties').withWriter { vProperties.store(it, "Generated by gradle task 'bumpUpVersion'.") } } -
version.propertiesを自動更新 ## fastlane/Fastfile platform :android do lane :bump_up_version do gradle(task:
'bumpUpVersion') // gitを操作してversion.propertiesの変更差分をmasterにpush git_add(path: 'version.properties') git_commit(path: 'version.properties', message: 'Bump up new version') push_to_git_remote(remote: 'origin', tags: false) end end -
内部テスト版をアルファ版に昇格 ## fastlane/Fastfile platform :android do lane :promote_internal_to_alpha do supply(
package_name: "com.cookpad.android.activites", json_key: "path/to/json_key", track: "internal", track_promote_to: "alpha" # 対象のトラックに昇格 ) end end -
その他にも • changelogsの自動生成 ◦ 年下2桁, 週番号で更新文言ファイルを用意 ◦ 内部テスト版をアップロードする際にファイルをコピーして利用 • issueの自動生成やマイルストーンの作成
◦ GitHubのAPIを実行するlaneが用意されている -
変えてみてどうだったか • リリースに関する諸作業が自動化されることで、開発作業に集中できるように なった • スケジュールの調整作業は減ったが、完全には無くならなかった ◦ テスト期間中に重大な問題が発生したがそのバージョン内で修正してリリースしたいという話が 出るようになった ◦
masterに変更を加えずアルファ版をアップロードできる手段を用意した • クローズドテスト版を使うことで、全社員が気軽に開発版に触れられるようになっ た -
参考資料 クックパッドモバイルアプリの開発体制とリリースフロー https://techlife.cookpad.com/entry/2015/02/25/093000 クックパッドアプリはみんなが寝ている間にサブミットされる https://techlife.cookpad.com/entry/2018/09/14/090000 Android版クックパッドアプリで採用している技術の現状確認 2018年版 https://techlife.cookpad.com/entry/2018-11-19-technical-selection-for-android-cookpad 毎週リリースを実現するテスト活動 https://techlife.cookpad.com/entry/2018/12/12/120000
クックパッドのモバイルアプリ開発が「機械に人が合わせる」リリースフローに行き着いた理由 http://www.atmarkit.co.jp/ait/articles/1902/04/news019.html