$30 off During Our Annual Pro Sale. View Details »

Considerate App Update Delivery at DroidKaigi 2022

Considerate App Update Delivery at DroidKaigi 2022

よくあるリリースフローが持ちがちな問題点として、日頃から見逃されがちな検証や陥りやすい構造をあげ、それらをどうやって解決していくのかを紹介します

Room Backdrop - 2022/10/06 14:05-14:30

https://droidkaigi.jp/2022/timetable/365055

What is DroidKaigi?

DroidKaigiはエンジニアが主役のAndroidカンファレンスです。
Android技術情報の共有とコミュニケーションを目的に、2022年10月5日(水)〜7日(金)の3日間開催します。

Matsuda Jumpei

October 06, 2022
Tweet

More Decks by Matsuda Jumpei

Other Decks in Programming

Transcript

  1. Considerate-
    App Update Delivery
    Jumpei Matsuda
    1

    View Slide

  2. よくあるリリースフローの問題点とは?
    理想的なワークフローの性質を満たすテクニック
    アプリファイルから取得できる情報
    R8 Rules のレビュー方法
    リリースフローで意識すべき構成
    Considerate App Update Delivery
    2
    Jumpei Matsuda
    @red_fat_daruma
    DeployGate, Inc.
    資料・解説置き場
    jmatsu/droidkaigi-2022

    View Slide

  3. この発表の範囲
    PlayStore その他アプリストアへの配布
    組織内配布などの Sideloading


    3
    資料・解説QR

    View Slide

  4. この発表の範囲
    PlayStore その他アプリストアへの配布
    組織内配布などの Sideloading


    4
    DroidKaigi 2021 Lite の発表を
    🙏
    https://youtu.be/DA2ziL4qgZk
    資料・解説QR

    View Slide

  5. リリースフローでありがちな問題点
    アプリファイルから取得できる値やその方法
    それらを検証・監視する利点と構成
    リリースフロー自動化の入門キット
    細かい CI 設定記述等
    今日持ち帰ってほしいもの





    5
    資料・解説QR

    View Slide

  6. ● 受け入れテストで最終確認をし、アップロードするだけ
    一般的なワークフローの概要図
    6
    受け入れ
    テスト
    VCS
    (Git etc.)
    ストア
    リリース
    Lints,
    自動テスト,
    コード
    レビュー
    日常的な開発
    Approved なアプリ
    リリース候補版
    リリースフロー
    コード
    変更

    View Slide

  7. ● 日常的な開発で検証すべきだった項目の受け皿に
    ● 各ステージの In/Out がうまく利用されていない
    よくある悲しい現実
    7
    受け入れ
    テスト
    (最後の砦)
    VCS
    (Git etc.)
    ストア
    リリース
    コード
    変更
    日常的な開発 リリースフロー
    後回しにした検証
    アプリの再ビルド
    リリース候補(?)版
    Lints,
    自動テスト,
    コード
    レビュー

    View Slide

  8. ● それまでのステージで非機能要件などが検証されている
    ● 各ステージの成果物がリレーされ、再生成しないで済む
    ● (手動であっても)安全な作業が可能
    リリースフローが期待している状態
    8

    View Slide

  9. ● リリースフローにしわ寄せ ≒ コスト化 & 高リスク
    ○ 差し戻すときのコストが異常に高い
    ○ 可視化しづらい非機能要件の検証が動作チェックで代替される
    ● ステージ間の In/Out が独立している
    ○ 手動やCI変更時に成果物を取り違えるリスクの増加
    ○ 各ステージで環境を揃え、冪等性の前提を担保するという手間
    期待に答えられない現実
    9

    View Slide

  10. ● 動作に影響を及ぼす恐れ
    ○ ライブラリアップデート時の Proguard/R8 Rule 変更
    ● 将来的に大変面倒くさい
    ○ 意図しない permission の追加
    ● 発覚時にビジネス判断を必要とする
    ○ アプリサイズの肥大化
    ○ required feature の追加 (による対応端末の減少)
    ○ automatic update を無効化する変更
    ※API 22 以下
    e.g. 可視化されない・後回しにされがちな検証
    10

    View Slide

  11. どう検証すればいいの?
    実際に動かすしかない?
    11

    View Slide

  12. ● ツールチェインやアプリの設定の多くは宣言的
    ○ 静的解析、それこそただの grep や diff で十分検出可能
    ○ 推移的依存で一見見えなくても、取り出せればレビュー可能
    ● 技術的に難しいものもある
    ○ e.g. 対応端末数変化の具体的な台数の算出
    ■ Google さん、デバイスカタログAPI作ってくださいお願いします
    ○ 端末依存の挙動差異など、実際に動かすことで確定する部分
    実行しなくてもリスク検出が可能なものは多い
    12

    View Slide

  13. Mobile CI/CD 改善案件で
    いつも適用するものを紹介
    13

    View Slide

  14. ● それまでのステージで非機能要件などが検証されている
    ● 各ステージの成果物がリレーされ、再生成しないで済む
    ● (手動であっても)安全な作業が可能
    リリースフローが期待している状態
    14

    View Slide

  15. ● それまでのステージで非機能要件などが検証されている
    ○ アプリファイルに含まれる情報の監視
    ○ R8 Rules のレビュー
    ● 各ステージの成果物がリレーされ、再生成しないで済む
    ● (手動であっても)安全な作業が可能
    リリースフローが期待している状態
    15

    View Slide

  16. ● それまでのステージで非機能要件などが検証されている
    ○ アプリファイルに含まれる情報の監視
    ○ R8 Rules のレビュー
    ● 各ステージの成果物がリレーされ、再生成しないで済む
    ● (手動であっても)安全な作業が可能
    リリースフローが期待している状態
    16

    View Slide

  17. 17
    様々なファイル情報を取得するメリット
    ● ビジネス要件やミス防止に関わりやすい
    ○ ファイルサイズの肥大化はインストール率の低下に
    (諸説有)
    ○ バージョン名に判別子を入れておけば容易に環境を判断できる
    ● 日頃から監視することで異常に気づきやすい
    ○ e.g. APK 10MB の違和感が薄いが、3MB -> 10MB の変化は異常
    リリースフローが期待している状態 > 非機能要件の検証 > アプリファイルに含まれる情報の監視

    View Slide

  18. アプリ情報は AAB を対象にした検査がオススメ - 1/2
    ● APKとAABで取得できる情報量に少し差がある
    ○ APK は実行ファイルで、AAB はパッケージファイル
    ● AAB の情報 = APK - 最終署名 + α
    ○ e.g. PlayStoreの機能提供に必要な情報
    18
    e.g. Proguard Mapping アップロード署名 中間・最終署名情報
    AAB ✅ ✅ ❌
    APK ❌ ❌ ✅
    ✅ 含む ❌ 含まない
    リリースフローが期待している状態 > 非機能要件の検証 > アプリファイルに含まれる情報の監視

    View Slide

  19. アプリ情報は 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から基本的に適用されてしまう
    リリースフローが期待している状態 > 非機能要件の検証 > アプリファイルに含まれる情報の監視

    View Slide

  20. ● google/bundletool
    ○ PlayStore で利用されている実ツール
    ● 取得できる値
    ○ AndroidManifest の内容、各種リソース名・値(module別)
    ○ APK のサイズ(要APKS生成)
    ● 取得できない値
    ○ その他XMLの内容
    20
    現状、AAB からデータを取るなら bundletool 一択
    リリースフローが期待している状態 > 非機能要件の検証 > アプリファイルに含まれる情報の監視

    View Slide

  21. 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

    View Slide

  22. ● ビルド環境が判断できる・できそうな値
    ○ package name, version code, version name
    ● アプリ挙動に影響する値
    ○ target sdk version の変更
    ● ビジネス要件に関係する値
    ○ min sdk version の変更
    ○ uses-features(required) の追加
    ○ uses-permissions の追加・削除
    ○ 実際に配信されることになる APK のサイズの増加
    22
    最低限 bundletool で収集しておくといい値
    リリースフローが期待している状態 > 非機能要件の検証 > アプリファイルに含まれる情報の監視
    資料・解説QR

    View Slide

  23. ● チームによってはこれらもリリースブロッカーになりうる
    ● パフォーマンス影響
    ○ AppStartup の meta data の増加
    ○ Content Provider の増加
    ● セキュリティ面
    ○ exported=true なコンポーネントの追加
    ○ 自分のパッケージ空間外のコンポーネントの追加
    23
    発展: 余裕があればさらに見ておくといい値
    リリースフローが期待している状態 > 非機能要件の検証 > アプリファイルに含まれる情報の監視

    View Slide

  24. NOTE: ここまでの値を実行時に検証する必要はない
    24
    ● Package Manager APIはベンダー依存 💀 < THIS IS ANDROID
    ○ 例えば一部APIでFire OSの挙動が大きく異なる
    ● そのアプリ自身に関するAPIに挙動差はないけれど・・・
    ○ DeployGateなどを利用してもインストールの手間はしんどい
    ■ アップデートすらできないと再署名・再ビルドから手戻り
    リリースフローが期待している状態 > 非機能要件の検証 > アプリファイルに含まれる情報の監視

    View Slide

  25. ● それまでのステージで非機能要件などが検証されている
    ○ アプリファイルに含まれる情報の監視
    ○ R8 Rules のレビュー
    ● 各ステージの成果物がリレーされ、再生成しないで済む
    ● (手動であっても)安全な作業が可能
    リリースフローが期待している状態
    25

    View Slide

  26. ● アプリの挙動に直結する
    ○ 受け入れテスト(ないしは動作テスト)で差し戻されるとつらい
    ○ ライブラリのアップデート時に稀によくある
    ● 低コストで確認できて、かつ「なぜ」が可視化されるべき
    ○ ❌ 実際に動かすテストの機会を増やす
    ○ ✅ Rule 記述自体の変更をレビューできるようにする
    R8 の Rule は必ずレビュー対象するべき
    26
    リリースフローが期待している状態 > 非機能要件の検証 > R8 Rules のレビュー

    View Slide

  27. ● オプションを足すだけでいい
    ○ -printconfiguration proguard-merged-config.txt
    ● ただし実行ユーザー依存の値をトリミングする必要がある
    ○ minify${variant}WithR8 タスクに hook する
    ○ 正規表現による置換で対応可能
    最終的な Rule を保存し、VCS 管理化に置く
    27
    リリースフローが期待している状態 > 非機能要件の検証 > R8 Rules のレビュー

    View Slide

  28. ● どのライブラリ由来なのかも表示されるので調査しやすい
    ○ どのバージョンかも書かれているのでお得(?)
    差分をテキストベースで可視化
    28
    リリースフローが期待している状態 > 非機能要件の検証 > R8 Rules のレビュー

    View Slide

  29. ● 他にも可視化オプションがある
    ○ -printseeds : どの entry が keep されたか
    ○ -printusage : どの entry が remove されたか
    ● 意図しない差分がある ⇒ R8 の breaking changes or bug
    ○ AGP の更新や最新の R8 を使うときの検査として応用可能
    ○ Google Issue Tracker に全力で質問しにいきましょう
    R8 の Breaking changes / Bug の判断 (Advanced)
    29
    リリースフローが期待している状態 > 非機能要件の検証 > R8 Rules のレビュー

    View Slide

  30. ● それまでのステージで非機能要件などが検証されている
    ○ アプリファイルに含まれる情報の監視
    ○ R8 Rules のレビュー
    ● 各ステージの成果物がリレーされ、再生成しないで済む
    ● (手動であっても)安全な作業が可能
    リリースフローが期待している状態
    30

    View Slide

  31. ● 開発フロー内
    ○ アプリファイルは基本変化し続ける
    ○ 常に最新のアプリファイルに価値がある
    ● リリースフロー内
    ○ アプリファイルそのものを変更することはない
    ○ その時のアプリファイルに価値がある
    開発フローとリリースフローを明確に分ける
    31
    リリースフローが期待している状態 > ステージ間の成果物リレー

    View Slide

  32. 開発フローからの成果物を保存する Pool で分断
    32
    GitHub Release,
    S3, GCS, GDrive
    コード変更
    etc.
    リリースフローが期待している状態 > ステージ間の成果物リレー > 開発フローとリリースフローを明確に分ける
    受け入れ
    テスト
    ストア
    リリース
    リリースフロー
    日常的な開発
    リリース候補版
    リリース候補版(?)
    VCS
    (Git etc.)

    View Slide

  33. リリースフロー内は Pool を対象として再定義
    33
    GitHub Release,
    S3, GCS, GDrive
    受け入れ
    テスト
    Approve
    Reject
    コード変更
    etc.
    VCS
    (Git etc.)
    リリース候補版
    (approved)
    リリース候補版
    (approve待ち)
    リリースフローが期待している状態 > ステージ間の成果物リレー > 開発フローとリリースフローを明確に分ける
    ストア
    リリース

    View Slide

  34. ● それまでのステージで非機能要件などが検証されている
    ○ アプリファイルに含まれる情報の監視
    ○ R8 Rules のレビュー
    ● 各ステージの成果物がリレーされ、再生成しないで済む
    ● (手動であっても)安全な作業が可能
    リリースフローが期待している状態
    34

    View Slide

  35. 手段が目的化すると自動化はリスクになる
    Gradle やコマンドラインで完結させたい
    Web console の操作が面倒くさいので自動化したい
    ビルド環境の依存性や属人性を減らしたい
    人的ミスや Secrets 管理リスクを減らして安全性を高めたい




    35
    リリースフローが期待している状態 > 安全な手動の実現

    View Slide

  36. 自動化は Pool -> アップロードの部分だけにする
    ● すでに存在する成果物を対象にできるものだけ選ぶ
    ○ PlayStore なら Triple-T/gradle-play-publisher (GPP)
    ● 自然とアップロードの設定だけになるので複雑化しない
    ○ Web コンソールに入力する値とほぼ1対1対応になる
    36
    リリースフローが期待している状態 > 安全な手動の実現
    ビルドをさせないようにする設定はたった
    1行だけ

    View Slide

  37. ● Web コンソールであれば表示される警告が見えない
    ○ e.g. dangerous permission の追加、配布対象端末数の変化
    ● 手動手順を復元しづらいことがある
    ○ ビルド方法や設定の切り替えが絡むとタスクの独立性がガタ落ち
    GPP を利用する上での認識すべき危うさ
    37
    リリースフローが期待している状態 > 安全な手動の実現

    View Slide

  38. ● Web コンソールであれば表示される警告が見えない
    ○ e.g. dangerous permission の追加、配布対象端末数の変化
    ● 手動手順を復元しづらいことがある
    ○ ビルド方法や設定の切り替えが絡むとタスクの独立性がガタ落ち
    GPP を利用する上での認識すべき危うさ
    38
    今回紹介したテクニックが適用されていれば無視できる
    リリースフローが期待している状態 > 安全な手動の実現

    View Slide

  39. リリースフローに日頃やるべき検証を押し付けない
    bundletool を使って AAB ファイルからデータを取り出す
    R8 のレビューは低コストで実現できる
    リリースフローとそれまでのフローは明確に分ける
    GPP などで自動化すべきはアップロード操作だけ
    まとめ
    01
    02
    03
    04
    05
    39
    Jumpei Matsuda
    @red_fat_daruma
    DeployGate, Inc.
    資料・解説置き場
    jmatsu/droidkaigi-2022

    View Slide