Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
alpha-release-automation
Search
もん
August 21, 2018
Technology
5.1k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
alpha-release-automation
2018-08-21 Cookpad.apk #1
Fukuo Kadota
もん
August 21, 2018
More Decks by もん
See All by もん
令和に始めるcode generation
litmon
0
170
Cookpad Summer Internship 2019 Day4 Android
litmon
0
10k
クックパッドマートAndroid 徹底解剖
litmon
1
720
Google Play Consoleのリリーストラックを有効活用してリリースフローの最適化を行った話
litmon
2
5.3k
クックパッドアプリのリリースフローに関して
litmon
0
2.3k
AccessibilityServiceを使ってアプリの可能性を広げよう
litmon
1
2.7k
Other Decks in Technology
See All in Technology
3人で1000GPU超を統合運用する?マルチクラウド&オンプレを跨ぐ、構築と運用のリアル!
kazukun0716
1
180
.NET WebAssemblyで実現するクライアントサイドAI推論:NuGetからViteまで、2つのエコシステムを繋ぐビルド戦略
yamachu
1
870
EventBridge に「合流」はない ― サーバーレスのワークフローを育てるということ / No Join in EventBridge
yusukeshimizu
2
550
作って終わりじゃないサーバーレス 〜9年運用する大規模EC物流API基盤の設計・運用のリアル〜
zozotech
PRO
0
530
AgentCore Runtime上にAgentic Coding基盤を構築・展開する際の設計ポイントと限界点 / Design considerations and limitations when building an agentic coding platform on AgentCore Runtime
har1101
6
760
品質と信頼性を地続きにする
grimoh
2
1k
C#未経験の僕がAIに読めるコードを書かせるまで
maguroalternative
0
300
AIエージェントを安全で速い現場監督にする:Jev・Obsidian・メタハーネス
x5gtrn
PRO
0
120
あけおめLINE 傾向とその対策
nasa9084
0
330
技術的負債から考える、AI時代のエンジニアリング投資 — ビズリーチの技術的負債と向き合った経験から、変更し続けられるソフトウェアを考える/ technical-debt-con2026
visional_engineering_and_design
4
3.8k
GitHub Agentic Workflows を触ってみる
htkym
2
620
Hermes Agentで、AIが調べて記事を書くブログを作った話
blueb
0
110
Featured
See All Featured
Bash Introduction
62gerente
615
220k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.8k
The Limits of Empathy - UXLibs8
cassininazir
1
690
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
2
2.2k
A Modern Web Designer's Workflow
chriscoyier
699
190k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Google's AI Overviews - The New Search
badams
0
1.6k
Crafting Experiences
bethany
1
350
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
Into the Great Unknown - MozCon
thekraken
41
2.7k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
530
Code Reviewing Like a Champion
maltzj
528
40k
Transcript
Cookpad.apk #1 alpha release automation 技術部 モバイル基盤グループ 門田
自己紹介 • かどたふくお • 技術部モバイル基盤グループ ◦ 主な仕事:Kotlin大臣、リリース自動化など • twitter: @_litmon_
github: @litmon speakerdeck: @litmon
今までのリリースフローおさらい
クックパッドのリリースフロー • 実は以前にも紹介したことがある ◦ 「クックパッド リリースフロー」で検索したら出てきます ◦ https://speakerdeck.com/litmon/kutukupatudoapurifalseririsuhuroniguan-site • 今回は、ここで話していた「自動化」周りの話をします
• fastlane/supply は知っている前提で話します ◦ 分からない人はこの機会に調べてみてください ◦ 雑に言うと「Google PlayにリリースするAPIをいい感じにラップしてくれてる便利ツール」
「クックパッドアプリのリリースフローに関して」P25 から抜粋
軽くおさらい v18.4 開発開始 リリース コードフリーズ 開発期間 テスト期間 リリース期間 v18.5 開発開始
軽くおさらい v18.4 開発開始 リリース コードフリーズ 開発期間 テスト期間 リリース期間 v18.5 開発開始
• あるバージョンの開発が開始し、 masterブランチに対して新規機能開発やバグ 修正などを行う ◦ 例: v18.4 の開発が開始 • バージョン名はそのまま Github Enterprise上でマイルストーンとして管理され、 追加したいfeatureごとにissueが切られて管理される ◦ そのマイルストーンの issueを見ればどういう機能が入るバージョンなの かが明確になる
軽くおさらい リリース コードフリーズ テスト期間 リリース期間 v18.5 開発開始 • あるバージョンの開発が一通り終了し、リリース前のテスト期間へと移行する •
その際、ブランチを RC-<version> として切ることで、masterへは次のバージョ ンの新機能開発をマージ可能な状態にする ◦ コードフリーズ • テスト期間ではQITチームによる品質チェックを行い、 テスト期間中に見つかった不具合やバグなどは RCブランチに順次修正を加え ていく • ある程度修正が落ち着いたら RCブランチの差分をmasterに適用する
軽くおさらい リリース リリース期間 v18.5 開発開始 • テスト期間が終了し、リリース可能な品質であることが確認できたらそのバー ジョンを公開する • リリース用の署名を付けた
apkはJenkins Jobによって作成 • fastlane/supply をラップしたRubyスクリプトを使用し、 開発者のPCを使って apkをアップロードする • 20, 50, 100% と段階的に公開率を操作し、新たな不具合が見つかったら必要 に応じてリリースを中止したりパッチリリースを行う
以前のリリースフローの問題点 • fastlane/supply をラップしたRubyスクリプトを使用し、 ◦ メンテナンスが大変 ◦ Rubyスクリプト内でコマンドラインツールとしての supplyを実行していてひたすら冗長 •
開発者のPCを使って apkをアップロードする ◦ apkはJenkins Jobでビルドしているのに、わざわざ開発者の手元に持ってくるのが手間 ◦ Google Publishing APIを叩くためのAPI Key(Publisher.json)をリリースを行う開発者が持つ必 要があり危険 ◦ ミスタイプとかしそうでヒューマンエラーが怖い
難しい・・・
他にも問題はある • パッチリリースを行うときに、バージョンの更新を行う必要がある ◦ 1回1回は大したことない作業だが重なると大変 ◦ 大規模な修正を加えたときはパッチリリースが増えがちなので、毎度毎度面倒が発生する ◦ masterにマージする際にコンフリクトが発生しがち
他にも問題はある • RCブランチを運用すると、masterとRCで差分が生じた際に面倒になる ◦ RCに入れるべき変更を masterに間違えて投げてしまったり、 RCの差分をmasterに適用しよう としたときにコンフリクトが発生したり、 …… ◦
マイルストーンごとにこの作業を行う人を立てているが、負担が大きい • 各マイルストーンに入れたい施策のために開発時期を調整するオペレーション が何度も発生していた ◦ 1イテレーションが2週間ほどなので、「どうしてもこの時期に出したいが、開発がちょっと間に合 わない」みたいな場合に調整が発生する
そもそも人間が 作業するのは面倒!!!
こうしたい • apkアップロード作業は特定のタイミングに勝手に実行されていればいい • 品質チェックが通った時点で、リリース作業は公開ボタンを押すだけに したい • RCブランチを廃止したい
自動でリリースする
自動アルファリリースを導入する • さまざまな手作業からの開放 ◦ リリース用apk作成のためのJenkins Job実行 ◦ リリースのためのPublishing.jsonファイルの用意 ◦ リリース用apkを手元にダウンロード
◦ リリース用スクリプトの実行 ◦ バージョンの更新作業 • 逆に言うと、これらを機械的に実行できるよう調整する必要がある
自動アルファリリースを導入する Before • RCブランチにリリースに必要なものが揃ってからapkをビルド • リリースするときに手動でスクリプトを実行しリリース After • RCブランチに変更があった時点でapkをビルドし自動でアップロード •
リリースの判断をしたときにPlay Consoleから手作業で昇格
自動アルファリリースを導入するために • 一番の技術的な障害は「versionCode」の取扱い ◦ Google Playの仕様上、各トラックにアップロードする apkは以前アップロードしたものよりも大き い必要がある • 現在リリースされているversionCodeはAPIで取得することができるため、ビルド
時にversionCodeを渡すようにした
build.gradleの変更 android { defaultConfig { if (project.hasProperty("versionCode")) { def newerVersionCode
= Math.max( Integer.parseInt(project.property("versionCode")), getVersionCode(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) ) def newerVersionName = getVersionNameFromVersionCode(String.valueOf(newerVersionCode)) println("versionCode: " + newerVersionCode) println("versionName: " + newerVersionName) versionCode newerVersionCode versionName newerVersionName } else { versionCode getVersionCode(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) versionName getVersionName(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) } } }
build.gradleの変更 android { defaultConfig { if (project.hasProperty("versionCode")) { def newerVersionCode
= Math.max( Integer.parseInt(project.property("versionCode")), getVersionCode(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) ) def newerVersionName = getVersionNameFromVersionCode(String.valueOf(newerVersionCode)) println("versionCode: " + newerVersionCode) println("versionName: " + newerVersionName) versionCode newerVersionCode versionName newerVersionName } else { versionCode getVersionCode(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) versionName getVersionName(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) } } } gradle実行時にpropertyを渡すようにする 実行時は `./gradlew assembleRelease -PversionCode=180501001` のように渡せる
build.gradleの変更 android { defaultConfig { if (project.hasProperty("versionCode")) { def newerVersionCode
= Math.max( Integer.parseInt(project.property("versionCode")), getVersionCode(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) ) def newerVersionName = getVersionNameFromVersionCode(String.valueOf(newerVersionCode)) println("versionCode: " + newerVersionCode) println("versionName: " + newerVersionName) versionCode newerVersionCode versionName newerVersionName } else { versionCode getVersionCode(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) versionName getVersionName(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) } } } versionMajor, versionMinorなどの値は以下のように決まっている - versionMajor: 年度 - versionMinor: 年度内のリリース回数 (パッチリリース含まない ) - versionBuild100, versionBuild: パッチリリース回数 - marketId: リリース先(以前は色々あったが現在は 1つのみ) versionCodeは <versionMajor(2桁)><versionMinor(2桁)><versionBuild100(2桁)><versionBuild(2桁)><marketId>(1桁) で構成されている 例: 180500011
build.gradleの変更 android { defaultConfig { if (project.hasProperty("versionCode")) { def newerVersionCode
= Math.max( Integer.parseInt(project.property("versionCode")), getVersionCode(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) ) def newerVersionName = getVersionNameFromVersionCode(String.valueOf(newerVersionCode)) println("versionCode: " + newerVersionCode) println("versionName: " + newerVersionName) versionCode newerVersionCode versionName newerVersionName } else { versionCode getVersionCode(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) versionName getVersionName(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) } } } versionMajor, versionMinorなどの値は以下のように決まっている - versionMajor: 年度 - versionMinor: 年度内のリリース回数 (パッチリリース含まない ) - versionBuild100, versionBuild: パッチリリース回数 - marketId: リリース先(以前は色々あったが現在は 1つのみ) versionNameも同様に “v<versionMajor(2桁)>.<versionMinor(2桁)>.<versionBuild100(2桁)>.<versionBuild(2桁)>” となっている 例: v18.5.0.1
build.gradleの変更 android { defaultConfig { if (project.hasProperty("versionCode")) { def newerVersionCode
= Math.max( Integer.parseInt(project.property("versionCode")), getVersionCode(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) ) def newerVersionName = getVersionNameFromVersionCode(String.valueOf(newerVersionCode)) println("versionCode: " + newerVersionCode) println("versionName: " + newerVersionName) versionCode newerVersionCode versionName newerVersionName } else { versionCode getVersionCode(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) versionName getVersionName(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) } } } versionMajor, versionMinorの値は今までのリリースフロー通りの値を使うようにしたので、引数 に渡ってきた値とこれからリリースしたいバージョンの大小を比較しビルドするようにした
build.gradleの変更 android { defaultConfig { if (project.hasProperty("versionCode")) { def newerVersionCode
= Math.max( Integer.parseInt(project.property("versionCode")), getVersionCode(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) ) def newerVersionName = getVersionNameFromVersionCode(String.valueOf(newerVersionCode)) println("versionCode: " + newerVersionCode) println("versionName: " + newerVersionName) versionCode newerVersionCode versionName newerVersionName } else { versionCode getVersionCode(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) versionName getVersionName(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) } } } versionNameは前述どおりの仕様なので versionCodeから組み立てられるのでそれ用のメソッド を用意
build.gradleの変更 android { defaultConfig { if (project.hasProperty("versionCode")) { def newerVersionCode
= Math.max( Integer.parseInt(project.property("versionCode")), getVersionCode(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) ) def newerVersionName = getVersionNameFromVersionCode(String.valueOf(newerVersionCode)) println("versionCode: " + newerVersionCode) println("versionName: " + newerVersionName) versionCode newerVersionCode versionName newerVersionName } else { versionCode getVersionCode(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) versionName getVersionName(versionMajor, versionMinor, versionBuild100, versionBuild, marketId) } } } versionCodeを引数から与えない場合 (開発時など)はデフォルトのversionCode, versionNameを 指定するようにしている
fastlane/supplyでビルドに必要なversionCodeを取得 platform :android do lane :retrieve_newer_version_from_google_play do alpha_version_codes = google_play_track_version_codes(
json_key: ENV.fetch('GOOGLE_PLAY_PUBLISHER_PATH'), package_name: 'com.cookpad.android.activities', track: 'alpha', ) alpha_version_code = alpha_version_codes.max&.to_i rollout_version_codes = google_play_track_version_codes( json_key: ENV.fetch('GOOGLE_PLAY_PUBLISHER_PATH'), package_name: 'com.cookpad.android.activities', track: 'rollout' ) rollout_version_code = rollout_version_codes.max&.to_i production_version_codes = google_play_track_version_codes( json_key: ENV.fetch('GOOGLE_PLAY_PUBLISHER_PATH'), package_name: 'com.cookpad.android.activities', ) production_version_code = production_version_codes.first [alpha_version_code, rollout_version_code, production_version_code].compact.max&.+10 || 0 end end
fastlane/supplyでビルドに必要なversionCodeを取得 platform :android do lane :retrieve_newer_version_from_google_play do alpha_version_codes = google_play_track_version_codes(
json_key: ENV.fetch('GOOGLE_PLAY_PUBLISHER_PATH'), package_name: 'com.cookpad.android.activities', track: 'alpha', ) alpha_version_code = alpha_version_codes.max&.to_i rollout_version_codes = google_play_track_version_codes( json_key: ENV.fetch('GOOGLE_PLAY_PUBLISHER_PATH'), package_name: 'com.cookpad.android.activities', track: 'rollout' ) rollout_version_code = rollout_version_codes.max&.to_i production_version_codes = google_play_track_version_codes( json_key: ENV.fetch('GOOGLE_PLAY_PUBLISHER_PATH'), package_name: 'com.cookpad.android.activities', ) production_version_code = production_version_codes.first [alpha_version_code, rollout_version_code, production_version_code].compact.max&.+10 || 0 end end fastlane/supplyには元々versionCodeを取得するためのlaneがあるので、それを使って取り出す ( https://docs.fastlane.tools/actions/supply/#retrieve-track-version-codes ) 引数にはAPI KeyになるJSONファイルのPATHと、対象になるアプリの packageName、あとは取 り出したいtrackを指定する アルファリリースを自動化するためには、 alphaトラックに上がっている apkのversionCodeよりも 大きくないといけないので、 alphaトラックに上がっている versionCodeの中で最も大きいものをま ず取り出す
fastlane/supplyでビルドに必要なversionCodeを取得 platform :android do lane :retrieve_newer_version_from_google_play do alpha_version_codes = google_play_track_version_codes(
json_key: ENV.fetch('GOOGLE_PLAY_PUBLISHER_PATH'), package_name: 'com.cookpad.android.activities', track: 'alpha', ) alpha_version_code = alpha_version_codes.max&.to_i rollout_version_codes = google_play_track_version_codes( json_key: ENV.fetch('GOOGLE_PLAY_PUBLISHER_PATH'), package_name: 'com.cookpad.android.activities', track: 'rollout' ) rollout_version_code = rollout_version_codes.max&.to_i production_version_codes = google_play_track_version_codes( json_key: ENV.fetch('GOOGLE_PLAY_PUBLISHER_PATH'), package_name: 'com.cookpad.android.activities', ) production_version_code = production_version_codes.first [alpha_version_code, rollout_version_code, production_version_code].compact.max&.+10 || 0 end end alphaリリースを自動化するために versionCodeを上げる必要があるため、 versionCode + 10 の値を返却するようにする + 10にしているのは、前述した marketIdは固定値で下1桁目に位置しているためその値を除いた 値を変える必要があるから 例: v18.5のアルファリリース時の versionCode 180500011 → 180500021 → 180500031 → ...
fastlane/supplyでビルドに必要なversionCodeを取得 platform :android do lane :retrieve_newer_version_from_google_play do alpha_version_codes = google_play_track_version_codes(
json_key: ENV.fetch('GOOGLE_PLAY_PUBLISHER_PATH'), package_name: 'com.cookpad.android.activities', track: 'alpha', ) alpha_version_code = alpha_version_codes.max&.to_i rollout_version_codes = google_play_track_version_codes( json_key: ENV.fetch('GOOGLE_PLAY_PUBLISHER_PATH'), package_name: 'com.cookpad.android.activities', track: 'rollout' ) rollout_version_code = rollout_version_codes.max&.to_i production_version_codes = google_play_track_version_codes( json_key: ENV.fetch('GOOGLE_PLAY_PUBLISHER_PATH'), package_name: 'com.cookpad.android.activities', ) production_version_code = production_version_codes.first [alpha_version_code, rollout_version_code, production_version_code].compact.max&.+10 || 0 end end さらにクックパッドでは段階リリースも行っているた め、たとえば180500011のversionCodeのアプリを alphaトラックからrolloutトラックに昇格した場合、 - alphaトラック: 公開中apkなし - rolloutトラック: 公開中apkあり(180500011) の状態になり、この状態でパッチリリースを行うため のビルドを行おうとしても alpha_version_codes # => [] となってしまう
fastlane/supplyでビルドに必要なversionCodeを取得 platform :android do lane :retrieve_newer_version_from_google_play do alpha_version_codes = google_play_track_version_codes(
json_key: ENV.fetch('GOOGLE_PLAY_PUBLISHER_PATH'), package_name: 'com.cookpad.android.activities', track: 'alpha', ) alpha_version_code = alpha_version_codes.max&.to_i rollout_version_codes = google_play_track_version_codes( json_key: ENV.fetch('GOOGLE_PLAY_PUBLISHER_PATH'), package_name: 'com.cookpad.android.activities', track: 'rollout' ) rollout_version_code = rollout_version_codes.max&.to_i production_version_codes = google_play_track_version_codes( json_key: ENV.fetch('GOOGLE_PLAY_PUBLISHER_PATH'), package_name: 'com.cookpad.android.activities', ) production_version_code = production_version_codes.first [alpha_version_code, rollout_version_code, production_version_code].compact.max&.+10 || 0 end end そのため、 - rolloutトラックに存在するversionCode - alphaトラックに存在するversionCode - productionトラック(rollout 100%)に存在する versionCode の中から最も高いものを選択して使用する必要があ る
fastlane/supplyを使ってビルド→アップロード lane :build_newer_version_release_apk do version_code = retrieve_newer_version_from_google_play gradle(task: 'assembleProdExternalRelease', properties:
{ 'versionCode': version_code }) end lane :upload_newer_version_apk_to_google_play_alpha do version_code = retrieve_newer_version_from_google_play gradle(task: 'copyChangelog', properties: { 'versionCode': version_code }) supply( json_key: ENV.fetch('GOOGLE_PLAY_PUBLISHER_PATH'), package_name: 'com.cookpad.android.activities', track: 'alpha', apk: 'cookpad/build/outputs/apk/cookpad-prod-external-release.apk', mapping: 'cookpad/build/outputs/mapping/prodExternal/release/mapping.txt', skip_upload_images: true, skip_upload_screenshots: true, ) gradle(task: 'releng', properties: { 'versionCode': version_code }) end
fastlane/supplyを使ってビルド→アップロード lane :build_newer_version_release_apk do version_code = retrieve_newer_version_from_google_play gradle(task: 'assembleProdExternalRelease', properties:
{ 'versionCode': version_code }) end lane :upload_newer_version_apk_to_google_play_alpha do version_code = retrieve_newer_version_from_google_play gradle(task: 'copyChangelog', properties: { 'versionCode': version_code }) supply( json_key: ENV.fetch('GOOGLE_PLAY_PUBLISHER_PATH'), package_name: 'com.cookpad.android.activities', track: 'alpha', apk: 'cookpad/build/outputs/apk/cookpad-prod-external-release.apk', mapping: 'cookpad/build/outputs/mapping/prodExternal/release/mapping.txt', skip_upload_images: true, skip_upload_screenshots: true, ) gradle(task: 'releng', properties: { 'versionCode': version_code }) end versionCodeは先程定義した retrieve_newer_version_from_google_play を使って取得 assembleタスクにプロパティを渡すようにして、新しいバージョンの apkをビルドする
fastlane/supplyを使ってビルド→アップロード lane :build_newer_version_release_apk do version_code = retrieve_newer_version_from_google_play gradle(task: 'assembleProdExternalRelease', properties:
{ 'versionCode': version_code }) end lane :upload_newer_version_apk_to_google_play_alpha do version_code = retrieve_newer_version_from_google_play gradle(task: 'copyChangelog', properties: { 'versionCode': version_code }) supply( json_key: ENV.fetch('GOOGLE_PLAY_PUBLISHER_PATH'), package_name: 'com.cookpad.android.activities', track: 'alpha', apk: 'cookpad/build/outputs/apk/cookpad-prod-external-release.apk', mapping: 'cookpad/build/outputs/mapping/prodExternal/release/mapping.txt', skip_upload_images: true, skip_upload_screenshots: true, ) gradle(task: 'releng', properties: { 'versionCode': version_code }) end supplyを素直に使ってalphaトラックへアップロード アップロードするapkは先ほどビルドしたものを使用する クックパッドではアップロード前に apkの軽いチェックを挟んでいるため、 laneを分けている
実行するときはこんな感じ $ bundle exec fastlane android build_newer_version_release_apk $ bundle exec
fastlane android upload_newer_version_apk_to_google_play_alpha fastlane便利・・・ あとはこれをJenkins Jobで実行するようにトリガの設定などを行うだけ
導入してみてどうだったか • apkのビルド・アップロードを人間が意識しなくて良くなったので、 リリースの作業を行うエンジニア(自分)が楽になった ◦ 人間に依存しないようになったので属人性が排除された • コンソール上から公開率の操作を行うだけになったので、非エンジニアでも簡単 に変更が加えられるようになった ◦
エンジニアが作業する必要がなくなったため、開発に集中できるように ◦ なったらいいなぁ
今後どうしていきたいか • まだまだ人間が管理している箇所が多い ◦ versionMajor, versionMinorは人間が管理している ◦ コードフリーズ・RCブランチの運用など • 「人間がスケジュールを管理する」のではなく
「スケジュールによって人間が動く」未来を作りたい ◦ リリースフローに関する人間の作業を徹底的に排除 ◦ これによって、調整業や面倒な仕事から脱却したい
余談 • 段階リリースを中止しているときにalphaリリースを実行しようとすると、APIから 謎のエラーが返ってきて出来ない ◦ なにか知っている人いたら教えてください :pray:
余談 • 段階リリースを中止しているときにalphaリリースを実行しようとすると、APIから 謎のエラーが返ってきて出来ない ◦ なにか知っている人いたら教えてください :pray:
余談 • 段階リリースを中止しているときにalphaリリースを実行しようとすると、APIから 謎のエラーが返ってきて出来ない ◦ なにか知っている人いたら教えてください :pray: • アルファリリース自動化を導入後、Playコンソールから段階リリースを操作して 間違って100%リリースをしてしまったことがあった
◦ 事故怖い。コンソール怖い。 ◦ 今後はアルファリリースからの昇格も Slack bot上で完結できるようにしたい ……
おわり!
次回予告 • Dangerを使ってKotlinのコンパイル時エラーや警告を表示してみた 〜プロジェクトkyoto-sensei〜 • Kotlinをクックパッドアプリに導入したときのあれこれ • Android版クックパッドアプリで採用している技術の現状確認 2018年版 inspired
by https://techlife.cookpad.com/entry/2015/06/25/093507