dely Tech Blog

クラシル・TRILLを運営するdely株式会社の開発ブログです

RenovateをiOSアプリ開発に導入してみた

f:id:funzin:20201127152405p:plain はじめまして、dely開発部のfunzinです。普段はクラシルのiOSアプリ開発を担当しています。

この記事は「dely #1 Advent Calendar 2020」の4日目の記事です。

adventar.org

adventar.org

昨日は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は以下の手順で導入が完了します。

  1. GitHub Apps経由でRenovateをRepositoryに追加
  2. Repository配下にrenovate.jsonを作成
  3. Documentを参考にしながらrenovate.jsonを修正
  4. 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の一覧はこちらです。

f:id:funzin:20201127152143p:plain

このようにPodfileGemfileに定義したライブラリのバージョンが更新されている場合、PRが生成されていることが確認できます。

f:id:funzin:20201127152200p:plain

実際に運用してみて

今まではライブラリをアップデートしたい場合、能動的にライブラリの情報を取りに行くことがほとんどでしたが、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 について詳しく知りたい方は是非参加してみてください!

bethesun.connpass.com