Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
Considerate- App Update Delivery Jumpei Matsuda 1
Slide 2
Slide 2 text
よくあるリリースフローの問題点とは? 理想的なワークフローの性質を満たすテクニック アプリファイルから取得できる情報 R8 Rules のレビュー方法 リリースフローで意識すべき構成 Considerate App Update Delivery 2 Jumpei Matsuda @red_fat_daruma DeployGate, Inc. 資料・解説置き場 jmatsu/droidkaigi-2022
Slide 3
Slide 3 text
この発表の範囲 PlayStore その他アプリストアへの配布 組織内配布などの Sideloading ✅ ❌ 3 資料・解説QR
Slide 4
Slide 4 text
この発表の範囲 PlayStore その他アプリストアへの配布 組織内配布などの Sideloading ✅ ❌ 4 DroidKaigi 2021 Lite の発表を 🙏 https://youtu.be/DA2ziL4qgZk 資料・解説QR
Slide 5
Slide 5 text
リリースフローでありがちな問題点 アプリファイルから取得できる値やその方法 それらを検証・監視する利点と構成 リリースフロー自動化の入門キット 細かい CI 設定記述等 今日持ち帰ってほしいもの ✅ ✅ ✅ ❌ ❌ 5 資料・解説QR
Slide 6
Slide 6 text
● 受け入れテストで最終確認をし、アップロードするだけ 一般的なワークフローの概要図 6 受け入れ テスト VCS (Git etc.) ストア リリース Lints, 自動テスト, コード レビュー 日常的な開発 Approved なアプリ リリース候補版 リリースフロー コード 変更
Slide 7
Slide 7 text
● 日常的な開発で検証すべきだった項目の受け皿に ● 各ステージの In/Out がうまく利用されていない よくある悲しい現実 7 受け入れ テスト (最後の砦) VCS (Git etc.) ストア リリース コード 変更 日常的な開発 リリースフロー 後回しにした検証 アプリの再ビルド リリース候補(?)版 Lints, 自動テスト, コード レビュー
Slide 8
Slide 8 text
● それまでのステージで非機能要件などが検証されている ● 各ステージの成果物がリレーされ、再生成しないで済む ● (手動であっても)安全な作業が可能 リリースフローが期待している状態 8
Slide 9
Slide 9 text
● リリースフローにしわ寄せ ≒ コスト化 & 高リスク ○ 差し戻すときのコストが異常に高い ○ 可視化しづらい非機能要件の検証が動作チェックで代替される ● ステージ間の In/Out が独立している ○ 手動やCI変更時に成果物を取り違えるリスクの増加 ○ 各ステージで環境を揃え、冪等性の前提を担保するという手間 期待に答えられない現実 9
Slide 10
Slide 10 text
● 動作に影響を及ぼす恐れ ○ ライブラリアップデート時の Proguard/R8 Rule 変更 ● 将来的に大変面倒くさい ○ 意図しない permission の追加 ● 発覚時にビジネス判断を必要とする ○ アプリサイズの肥大化 ○ required feature の追加 (による対応端末の減少) ○ automatic update を無効化する変更 ※API 22 以下 e.g. 可視化されない・後回しにされがちな検証 10
Slide 11
Slide 11 text
どう検証すればいいの? 実際に動かすしかない? 11
Slide 12
Slide 12 text
● ツールチェインやアプリの設定の多くは宣言的 ○ 静的解析、それこそただの grep や diff で十分検出可能 ○ 推移的依存で一見見えなくても、取り出せればレビュー可能 ● 技術的に難しいものもある ○ e.g. 対応端末数変化の具体的な台数の算出 ■ Google さん、デバイスカタログAPI作ってくださいお願いします ○ 端末依存の挙動差異など、実際に動かすことで確定する部分 実行しなくてもリスク検出が可能なものは多い 12
Slide 13
Slide 13 text
Mobile CI/CD 改善案件で いつも適用するものを紹介 13
Slide 14
Slide 14 text
● それまでのステージで非機能要件などが検証されている ● 各ステージの成果物がリレーされ、再生成しないで済む ● (手動であっても)安全な作業が可能 リリースフローが期待している状態 14
Slide 15
Slide 15 text
● それまでのステージで非機能要件などが検証されている ○ アプリファイルに含まれる情報の監視 ○ R8 Rules のレビュー ● 各ステージの成果物がリレーされ、再生成しないで済む ● (手動であっても)安全な作業が可能 リリースフローが期待している状態 15
Slide 16
Slide 16 text
● それまでのステージで非機能要件などが検証されている ○ アプリファイルに含まれる情報の監視 ○ R8 Rules のレビュー ● 各ステージの成果物がリレーされ、再生成しないで済む ● (手動であっても)安全な作業が可能 リリースフローが期待している状態 16
Slide 17
Slide 17 text
17 様々なファイル情報を取得するメリット ● ビジネス要件やミス防止に関わりやすい ○ ファイルサイズの肥大化はインストール率の低下に (諸説有) ○ バージョン名に判別子を入れておけば容易に環境を判断できる ● 日頃から監視することで異常に気づきやすい ○ e.g. APK 10MB の違和感が薄いが、3MB -> 10MB の変化は異常 リリースフローが期待している状態 > 非機能要件の検証 > アプリファイルに含まれる情報の監視
Slide 18
Slide 18 text
アプリ情報は AAB を対象にした検査がオススメ - 1/2 ● APKとAABで取得できる情報量に少し差がある ○ APK は実行ファイルで、AAB はパッケージファイル ● AAB の情報 = APK - 最終署名 + α ○ e.g. PlayStoreの機能提供に必要な情報 18 e.g. Proguard Mapping アップロード署名 中間・最終署名情報 AAB ✅ ✅ ❌ APK ❌ ❌ ✅ ✅ 含む ❌ 含まない リリースフローが期待している状態 > 非機能要件の検証 > アプリファイルに含まれる情報の監視
Slide 19
Slide 19 text
アプリ情報は AAB を対象にした検査がオススメ - 2/2 ● APKだとResourcesの参照が簡単にいかないことも ○ Remap されたファイルパス (case-sensitive) の復元 ※1 ■ e.g. drawable-hdpi/ic_launcher.png ↔ res/_3.png ○ AndroidManifest や他XML の decode が必要 ■ ただし non-XML 形式なら aapt/aapt2 で閲覧可能 ● 3rd party ツールを利用すればできるが、今回は skip ○ 興味があれば参考リポジトリの 3rd party ツール集を 19 ※1: AGP 4.2 辺りのAAPT2から基本的に適用されてしまう リリースフローが期待している状態 > 非機能要件の検証 > アプリファイルに含まれる情報の監視
Slide 20
Slide 20 text
● google/bundletool ○ PlayStore で利用されている実ツール ● 取得できる値 ○ AndroidManifest の内容、各種リソース名・値(module別) ○ APK のサイズ(要APKS生成) ● 取得できない値 ○ その他XMLの内容 20 現状、AAB からデータを取るなら bundletool 一択 リリースフローが期待している状態 > 非機能要件の検証 > アプリファイルに含まれる情報の監視
Slide 21
Slide 21 text
21 最低限 bundletool で収集しておくといい値 リリースフローが期待している状態 > 非機能要件の検証 > アプリファイルに含まれる情報の監視 資料・解説QR ● ビルド環境が判断できる・できそうな値 ○ package name, version code, version name ● アプリ挙動に影響する値 ○ target sdk version の変更 ● ビジネス要件に関係する値 ○ min sdk version の変更 ○ uses-features(required) の追加 ○ uses-permissions の追加・削除 ○ 実際に配信されることになる APK のサイズの増加 詳細な取り方や 取得スクリプトはこちらで🙏 GitHub: jmatsu/droidkaigi-2022
Slide 22
Slide 22 text
● ビルド環境が判断できる・できそうな値 ○ package name, version code, version name ● アプリ挙動に影響する値 ○ target sdk version の変更 ● ビジネス要件に関係する値 ○ min sdk version の変更 ○ uses-features(required) の追加 ○ uses-permissions の追加・削除 ○ 実際に配信されることになる APK のサイズの増加 22 最低限 bundletool で収集しておくといい値 リリースフローが期待している状態 > 非機能要件の検証 > アプリファイルに含まれる情報の監視 資料・解説QR
Slide 23
Slide 23 text
● チームによってはこれらもリリースブロッカーになりうる ● パフォーマンス影響 ○ AppStartup の meta data の増加 ○ Content Provider の増加 ● セキュリティ面 ○ exported=true なコンポーネントの追加 ○ 自分のパッケージ空間外のコンポーネントの追加 23 発展: 余裕があればさらに見ておくといい値 リリースフローが期待している状態 > 非機能要件の検証 > アプリファイルに含まれる情報の監視
Slide 24
Slide 24 text
NOTE: ここまでの値を実行時に検証する必要はない 24 ● Package Manager APIはベンダー依存 💀 < THIS IS ANDROID ○ 例えば一部APIでFire OSの挙動が大きく異なる ● そのアプリ自身に関するAPIに挙動差はないけれど・・・ ○ DeployGateなどを利用してもインストールの手間はしんどい ■ アップデートすらできないと再署名・再ビルドから手戻り リリースフローが期待している状態 > 非機能要件の検証 > アプリファイルに含まれる情報の監視
Slide 25
Slide 25 text
● それまでのステージで非機能要件などが検証されている ○ アプリファイルに含まれる情報の監視 ○ R8 Rules のレビュー ● 各ステージの成果物がリレーされ、再生成しないで済む ● (手動であっても)安全な作業が可能 リリースフローが期待している状態 25
Slide 26
Slide 26 text
● アプリの挙動に直結する ○ 受け入れテスト(ないしは動作テスト)で差し戻されるとつらい ○ ライブラリのアップデート時に稀によくある ● 低コストで確認できて、かつ「なぜ」が可視化されるべき ○ ❌ 実際に動かすテストの機会を増やす ○ ✅ Rule 記述自体の変更をレビューできるようにする R8 の Rule は必ずレビュー対象するべき 26 リリースフローが期待している状態 > 非機能要件の検証 > R8 Rules のレビュー
Slide 27
Slide 27 text
● オプションを足すだけでいい ○ -printconfiguration proguard-merged-config.txt ● ただし実行ユーザー依存の値をトリミングする必要がある ○ minify${variant}WithR8 タスクに hook する ○ 正規表現による置換で対応可能 最終的な Rule を保存し、VCS 管理化に置く 27 リリースフローが期待している状態 > 非機能要件の検証 > R8 Rules のレビュー
Slide 28
Slide 28 text
● どのライブラリ由来なのかも表示されるので調査しやすい ○ どのバージョンかも書かれているのでお得(?) 差分をテキストベースで可視化 28 リリースフローが期待している状態 > 非機能要件の検証 > R8 Rules のレビュー
Slide 29
Slide 29 text
● 他にも可視化オプションがある ○ -printseeds : どの entry が keep されたか ○ -printusage : どの entry が remove されたか ● 意図しない差分がある ⇒ R8 の breaking changes or bug ○ AGP の更新や最新の R8 を使うときの検査として応用可能 ○ Google Issue Tracker に全力で質問しにいきましょう R8 の Breaking changes / Bug の判断 (Advanced) 29 リリースフローが期待している状態 > 非機能要件の検証 > R8 Rules のレビュー
Slide 30
Slide 30 text
● それまでのステージで非機能要件などが検証されている ○ アプリファイルに含まれる情報の監視 ○ R8 Rules のレビュー ● 各ステージの成果物がリレーされ、再生成しないで済む ● (手動であっても)安全な作業が可能 リリースフローが期待している状態 30
Slide 31
Slide 31 text
● 開発フロー内 ○ アプリファイルは基本変化し続ける ○ 常に最新のアプリファイルに価値がある ● リリースフロー内 ○ アプリファイルそのものを変更することはない ○ その時のアプリファイルに価値がある 開発フローとリリースフローを明確に分ける 31 リリースフローが期待している状態 > ステージ間の成果物リレー
Slide 32
Slide 32 text
開発フローからの成果物を保存する Pool で分断 32 GitHub Release, S3, GCS, GDrive コード変更 etc. リリースフローが期待している状態 > ステージ間の成果物リレー > 開発フローとリリースフローを明確に分ける 受け入れ テスト ストア リリース リリースフロー 日常的な開発 リリース候補版 リリース候補版(?) VCS (Git etc.)
Slide 33
Slide 33 text
リリースフロー内は Pool を対象として再定義 33 GitHub Release, S3, GCS, GDrive 受け入れ テスト Approve Reject コード変更 etc. VCS (Git etc.) リリース候補版 (approved) リリース候補版 (approve待ち) リリースフローが期待している状態 > ステージ間の成果物リレー > 開発フローとリリースフローを明確に分ける ストア リリース
Slide 34
Slide 34 text
● それまでのステージで非機能要件などが検証されている ○ アプリファイルに含まれる情報の監視 ○ R8 Rules のレビュー ● 各ステージの成果物がリレーされ、再生成しないで済む ● (手動であっても)安全な作業が可能 リリースフローが期待している状態 34
Slide 35
Slide 35 text
手段が目的化すると自動化はリスクになる Gradle やコマンドラインで完結させたい Web console の操作が面倒くさいので自動化したい ビルド環境の依存性や属人性を減らしたい 人的ミスや Secrets 管理リスクを減らして安全性を高めたい ❌ ❌ ✅ ✅ 35 リリースフローが期待している状態 > 安全な手動の実現
Slide 36
Slide 36 text
自動化は Pool -> アップロードの部分だけにする ● すでに存在する成果物を対象にできるものだけ選ぶ ○ PlayStore なら Triple-T/gradle-play-publisher (GPP) ● 自然とアップロードの設定だけになるので複雑化しない ○ Web コンソールに入力する値とほぼ1対1対応になる 36 リリースフローが期待している状態 > 安全な手動の実現 ビルドをさせないようにする設定はたった 1行だけ
Slide 37
Slide 37 text
● Web コンソールであれば表示される警告が見えない ○ e.g. dangerous permission の追加、配布対象端末数の変化 ● 手動手順を復元しづらいことがある ○ ビルド方法や設定の切り替えが絡むとタスクの独立性がガタ落ち GPP を利用する上での認識すべき危うさ 37 リリースフローが期待している状態 > 安全な手動の実現
Slide 38
Slide 38 text
● Web コンソールであれば表示される警告が見えない ○ e.g. dangerous permission の追加、配布対象端末数の変化 ● 手動手順を復元しづらいことがある ○ ビルド方法や設定の切り替えが絡むとタスクの独立性がガタ落ち GPP を利用する上での認識すべき危うさ 38 今回紹介したテクニックが適用されていれば無視できる リリースフローが期待している状態 > 安全な手動の実現
Slide 39
Slide 39 text
リリースフローに日頃やるべき検証を押し付けない bundletool を使って AAB ファイルからデータを取り出す R8 のレビューは低コストで実現できる リリースフローとそれまでのフローは明確に分ける GPP などで自動化すべきはアップロード操作だけ まとめ 01 02 03 04 05 39 Jumpei Matsuda @red_fat_daruma DeployGate, Inc. 資料・解説置き場 jmatsu/droidkaigi-2022