DroidKaigi2022に登壇します + Renovate運用の話

クラスターでSoftware Engineerをやっているuzzuです。サイバーパンク エッジランナーズ はもう観ましたか?とても良いアニメでしたので感想文を書きたい所なのですが、この記事ではDroidKaigi2022への登壇の告知と、Renovateの運用について紹介します。

クラスターからは今年のDroidKaigiに1件の登壇を予定しています。

当日を楽しみにしています。ぜひお声がけいただけると嬉しいです。


話は変わりまして、クラスターでのRenovate運用について紹介します。

Renovate は プロジェクト内の依存ライブラリの更新を自動的に検知し、更新を手助けしてくれるツールです。今となっては多くの企業のプロジェクトで導入されているかと思います。クラスターにおいても段階的に導入を始めており、いい感じに機能してくれています。

颯爽とPull Requestキリ番を踏み抜くRenovate君

Renovateの導入はAndroidアプリから始めました。理由としては自分がAndroidアプリ開発もやっているというのはありますが、Androidアプリ開発のメンバーは兼務の方が多く、ライブラリ更新については着手がどうしても後手に回ってしまう状態であったため、作業負荷を軽減して少しの余力で開発環境を最新の状態に保つことができるようにしたいというのがありました。開発環境が常に最新の状態であることはSoftware Engineerにとっての福利厚生ですしね。

Renovateの導入方法については 公式ドキュメント がありますので省略しますが、クラスターでは以下のようにしています。

JSON5を採用

https://docs.renovatebot.com/getting-started/running/#global-config

Renovateの設定ファイルは JSON5 フォーマットで記述しています。強いこだわりがある選定ではないですが、この手の設定ファイルというのは何かとWhy, Why notなコメントを残したくなる事が多いですし、近年は設定ファイルの記述にJsonnetが採用されるケースが増えてきたりなど、設定ファイルをJSONライクな記述で書くことに抵抗がなくなりつつあるので、JSON5は選択肢として悪くないかなと思います。

Monorepo開発での段階的な導入

クラスターの開発は厳密なMonorepo開発とまではいきませんが、大凡のクライアントアプリとサーバーの実装が1つのGit Repositoryで管理されています。その経緯や意図などについては別の機会で触れていければと思いますが、そういったGit Repository構成においても ignorePaths のようなignore系の設定を用いて段階的に導入できるのはRenovateの良い所ですね。現在はAndroidプロジェクトへの導入は一段落して、 iOSアプリのプロジェクトに導入して試行錯誤しており、その次はサーバーサイドのプロジェクトへの導入を計画しています。

CIとの連携、テストの拡充

Renovateの運用にはCIとの連携が不可欠です。半自動的に(やろうと思えば自動的に)ライブラリを更新すれば、別のライブラリの振る舞いが変わるような変更が入ることもあります。ChangeLogに載っていない変更内容が影響を及ぼす事もあります。

クラスターでは通常のPull Request運用と同じくRenovateによるPull RequestにおいてもテストCIを回しています。しかしながらこれだけでは不十分で、CI上で実行するテストが拡充されていないと、CIは通ってもPull Requestのマージ後に思わぬ不具合が見つかる事があります。

直近のAndroid関連の話でいうと、androidx.activity 1.5.1への更新によってfacebook-android-sdkを使用したログイン処理が正常に動作しなくなる、という事がありました(version 14.1.1にて解消済)。この問題はリリース前のQAにて見つかり、結果としてユーザへの影響はありませんでしたが、多くのandroidxライブラリがandroidx.activityに依存している点について蔑ろにしていた(androidx.navigation、androidx.lifecycleなど)所があります。

直近CIでのE2Eテストの安定化という別の課題を抱えている為にまだ着手できていないのですが、ユーザがワールドやイベントに辿り着くまでに通る処理についてテストケースを拡充しつつ、定常的にCIでE2Eなテストを回すようにして、より早い段階で後方互換性のない変更に気づけるようにしていきたいです。

運用ルール

上記を踏まえた上で、クラスターでは以下のような運用ルールでRenovateを運用しています。

プラットフォームを跨いで影響を及ぼすライブラリの更新は対象外にする

前述の通り、大凡のクライアントアプリとサーバーの実装が1つのGit Repositoryで管理されています。加えて、クライアントアプリとWeb APIとの通信にはOpenAPIを採用したり、クライアントアプリ内部においてはUnityと各プラットフォームネイティブな実装との連携にProtocol Buffersを採用するなど、各コンポーネントで相互にやりとりが必要な箇所については何かしらコード生成を要するプロトコルを用いて実装されています。

そのプロトコル実装を自動的に更新してしまうのはあらぬ不具合をもたらす可能性があるため、更新対象外としepic化して進行しています。

本番の実装に影響がないライブラリ更新はChangeLogを確認してどんどんマージ

本番に影響のあるライブラリ更新はJIRAチケットを作成して関連づけてリグレッションQAを通すようにしています。しかし、テストやデバッグ用途のライブラリについても同様のフローをとると運用コストが跳ね上がってしまうので、本番に影響のない更新はCIが通ったら気軽にどんどんマージして良いとしています。ただし、最低限ChangeLogは確認して、どんな変更があったかコメントを残すようにしています。

尚、人は時に取りこぼす事もあるので、Weekly meetingでRenovate Pull Request確認コーナーを設けており、最悪その場ではPull Requestに目を通すようにしています。

通常のPull Requestと同じようにすぐにレビューする。放置しない

ライブラリ更新も立派なPull Requestですので、素早くレビューします。CIが失敗したら原因をすぐに確認し、ライブラリ更新のブロッカーがあるようであればJIRAチケットを切っておいてPull Requestは閉じるようにしています。

この辺り、自動マージしても良さそうなライブラリが出てきたら良しとして、より運用コストを下げたい所ではありますが、現状の見解としてはクライアントアプリのRenovate運用だと自動マージを適用して良さそうなケースがないな〜というのがあります。

なんでだろうというところを掘り下げると、Pull Requestが飛んできて自動マージしない事で、ChangeLogを見にいくきっかけにもなっているんですよね。テストライブラリの更新だけだとしても、より良いAPIが増えたのであればおさえておきたいですし、パッチバージョンのリリースで新機能が入ったりする事もありますし、世の中は様々です。Software EngineerはPull Requestが飛んでくると処理したくなる生き物なので、Pull Requestが飛んでくるだけで恩恵があるんだな〜と感じています。

おわりに

この記事ではDroidKaigiの登壇予告と、クラスターでのRenovateの運用について紹介しました。

クラスターでは新機能をどんどんリリースしつつも開発環境をより最新に保つ事で、長期的な意味でリリースを加速する取り組みを行っています。この記事を読んで cluster での開発に興味をもっていただけた方は是非とも↓からエントリーをお願いします!