はじめまして、dely開発部のfunzinです。普段はクラシルのiOSアプリ開発を担当しています。
この記事は「dely #1 Advent Calendar 2020」の4日目の記事です。
昨日はMeilCliさんの【C#】null許容値型のnonnull判定どれが早いかクイズという記事でした。 パフォーマンス計測もしていてとてもよくまとまっているので気になる方はぜひ見てみてください。
さっそく本題ですが、この記事ではクラシルのiOSアプリ開発にRenovateを導入したことについてお話しします。
Renovateとは
Renovateとはパッケージマネージャー(e.g, Bundler, npm)で管理しているライブラリのアップデート作業を自動化してくれるサービスです。似たようなサービスでは2019年にGitHubにjoinしたDependabotがあります。
なぜ導入したか
クラシルのiOSアプリ開発では、BundlerやCocoaPodsで管理しているライブラリのアップデートを手動で行っていました。必要なタイミングにならないとライブラリのアップデートが行われないため、定期的にライブラリをアップデートすることがありませんでした。
そのため、いざバージョンを上げる時に大幅な修正対応が発生し開発コストが増加する原因となっていたため、日常的にアップデートする仕組みにしておきたかったのがRenovateを導入した大きな理由です。
なぜDependabotではなくRenovateを採用したのか
Dependabotに比べてiOS開発で利用するパッケージマネージャー(e.g. SwiftPackageManager, CocoaPods)のサポートが多かったことが導入の決め手でした。
CocoaPodsと同様にiOSでよく使われているCarthageは残念ながら対応していません。
導入手順
Renovateは以下の手順で導入が完了します。
- GitHub Apps経由でRenovateをRepositoryに追加
- Repository配下に
renovate.json
を作成 - Documentを参考にしながら
renovate.json
を修正 - RenovateがPRを生成
サンプル
実際にどのようなPRが生成されるかを確認できるようにサンプルのRepositoryを用意しました。 こちらのios-renovate-exampleでCocoapodsやBundlerでどのようなPRが作成されるか確認できます。
プロジェクトの構成は新規作成したプロジェクトにpod install
を実行したのみなので最小限の構成となっています。
Configファイル
https://github.com/funzin/ios-renovate-example からconfigファイルを抜粋したものです。
Podfile
platform :ios, '9.0' target 'ios-renovate-example' do use_frameworks! pod 'RxSwift', '~> 5.0.0' pod 'RxCocoa', '~> 5.0.0' pod 'Nuke', '~> 8.4.1' pod 'SwiftLint', '~> 0.40.0' end
renovate.json
{ "packageRules": [ { "groupName": "RxSwift", "managers": [ "cocoapods" ], "packageNames": [ "RxCocoa", "RxRelay", "RxSwift" ] }, { "groupName": "SwiftLint", "managers": [ "cocoapods" ], "packageNames": [ "SwiftLint" ], "enabled": false } ] }
1つのPRでまとめて更新してほしいものをpackageNames
でまとめています。
また、バージョンを更新したくない場合、"enabled": false
を設定することでPRが生成されなくなります(e.g. SwiftLint)
Gemfile
source 'https://rubygems.org' gem 'cocoapods', '1.9.3'
Renovateが生成したPR
実際に生成されたPRの一覧はこちらです。
このようにPodfile
やGemfile
に定義したライブラリのバージョンが更新されている場合、PRが生成されていることが確認できます。
実際に運用してみて
今まではライブラリをアップデートしたい場合、能動的にライブラリの情報を取りに行くことがほとんどでしたが、RenovateがPRを生成してくれることで受動的にライブラリの更新をしやすくなりました。
クラシルの開発フローでは、Renovateが生成したPRにライブラリのリリースノートを貼って、チームメンバーにレビューリクエストを投げるような仕組みにしています。また、1人のメンバーがライブラリ周りの管理をするのではなく、毎週アップデート担当を設けて、リリースノートの添付、レビューリクエスト、マージまでの役割を担うことで、アップデートのフローが属人化しないようにも努めています。
余談
クラシルアプリに導入当初はBundlerとCocoaPodsで管理しているライブラリをRenovateの自動アップデート対象としていました。しかし、並行してXcodeGen対応も同時に行っていたためprojectファイルを.gitignore
に追加したタイミングでCocoaPodsの自動アップデートが動かなくなってしまいました。これはprojectファイルがRepository配下に存在しないため、Renovate側で実行ができなくなったためです。
これらの対策として、CocoaPodsは自前で自動アップデートの仕組みを作ることでRenovateからは除外し、現在ではBundlerのみをRenovateでアップデートするようにしています。
まとめ
Renovateの導入をすることで、ライブラリの自動アップデートまわりを多く任せることができました。自前でライブラリの自動アップデート環境を用意するのは大変だと思うのでこの機会に是非導入してみてはいかがでしょうか?
明日はyasuoさんの「エンジニアがゼロから始めるプロダクトマネジメント」です。
また、dely ではエンジニアを絶賛募集中です! ご興味あればこちらのリンクからお気軽にエントリーください! join-us.dely.jp
さらに TechTalk というイベントも行っているので、dely について詳しく知りたい方は是非参加してみてください!