「Ateam Finergy Inc. Advent Calendar 2020」7日目は @okonomi が担当します。
はじめに
「Renovate」は依存ライブラリの自動更新ツールです。
私が担当しているサービスでもRenovateを導入していて、半年ほど運用してみてそれなりに軌道に乗ってきたので、一度振り返ってみようと思います。
前提として、下記のような環境・アプリで運用しています。
- self-hosted Gitlab
- フロントエンドのコードを含んだRailsアプリ
Renovateはローカルでも試せる
Renovateに対する私の理解不足だったんですが、RenovateはWebサービスとしての提供のほかにOSSとしても公開されており、ローカル環境で動かすことができます。
CLIをnpmでインストールすればとりあえずRenovateを使ってみることができます:
$ npm install -g renovate
プロジェクトへの初期セットアップはこんなかんじです:
$ renovate --token xxxx --onboarding=true okonomi/renovate-sandbox
上記コマンドでrenovate.json
を作成するMerge Requestが作成されます:
--token
はAPIトークンです。デフォルトだとGithubのAPIトークンで、--platform
で別のプラットフォームを指定した場合はそれに合わせてAPIトークンを取得・設定します(指定できるプラットフォームはドキュメント参照):
あと--log-level debug
や--dry-run true
を付けておくとうまくいかないときの原因調査が早いです。
その他のオプションはこちらにまとまっています:
導入時にありがちですが、APIトークンのパーミッションが足りなかったりAPIエンドポイントがズレてたり、本質的ではないところでハマりがちなので、試行錯誤のループが早くなってよかったです。
あとRenovateの運用環境が整うまでは、renovate
コマンドを週一とかで人力で叩くようにするだけでもとりあえず使い始めることができたりします。
Merge Requestのランダムアサイン
Renovateがライブラリ更新のMerge Requestを作ってくれるのですが、そのままだと放置されたり一部の人に対応が集中したりしそうだなと思ったので、チームのエンジニアにランダムでアサインするようにしました。
設定はこんなかんじです:
"assignees": [
"user1",
"user2",
"user3"
],
"assigneesSampleSize": 1,
assignees
にアサイン候補のユーザーIDを列挙して、assigneesSampleSize
でひとつのMerge Requestに何人アサインするかを指定します。
結果、みんなに均等に作業分担されるようになったのと、どういうライブラリを使ってるとか、アップデートで動かなくなったときにどこで使ってるかを確認したりで、アプリに対するナレッジがそれなりに平準化する効果もあった気がします。
group:allNonMajor
の有効化
Renovateは設定項目が膨大なので、よくあるユースケース向けにプリセットを用意してくれています。
その中のgroup:allNonMajor
を有効にしておくと、メジャーアップデートは個別のMerge Requestに、それ以外のマイナー/パッチアップデートはひとつのMerge Requestにまとめてくれます。
こんなかんじです:
"extends": [
"group:allNonMajor"
],
メジャーアップデートのMerge Requestは破壊的変更がないかChangelogやDiffをしっかり確認、それ以外はCIがとおってればOKというふうにレビューの負荷を下げることができます。
gemの更新はしていない
gemの更新はRenovateではやっていません。RenovateはGemfile
にバージョン指定があるgemしか更新してくれないためです。
gemの更新は別途gitlabci-bundle-update-mrを導入しています。
gitlabci-bundle-update-mrもRenovateと同様にMerge Requestへのランダムアサインが可能です。
ただ、gitlabci-bundle-update-mrは逆にバージョン指定があるgemは更新してくれないので、Renovateと併用してもいいかも、と思っています。
Auto Mergeはしていない
Merge RequestのCIが通ったら自動的にマージするようにも設定できるのですが、今のところはやっていません。
自動テストを完璧に書けている自信がないのと、環境によって動く動かないがあったりするので(IE11とか…)、コードレビューを通すようにしています。
@types
はグループ化したほうがいいかも
前述のようにマイナー/パッチアップデートはグループ化してるのですが、TypeScriptの型定義の更新は差分を見ても「なるほど」としか言えないことが多く、レビュー時のノイズになりがちなので、別のMerge Requestにまとめると良さそうかもと思っています。
都合のいいことにgroup:definitelyTyped
というプリセットが用意されています。
設定ファイルはJSON5型式がいいかも
Renovateの設定ファイルはいくつかの名前や型式に対応しています。
その中にjson5
という見慣れない拡張子があります。これはJSON5という形式で、ざっくりいうとコメントが書けるJSONと思っておけばよさそうです(正確にはECMAScript 5.1の記法が使えるJSONの拡張フォーマット)。
Renovateの設定は追い込んでいくと複雑になりがちでコメントを残しておきたくなるので、JSON5型式はメリットがありそうです。
まとめ
Renovateを半年運用して得られた知見を振り返ってみました。
Renovate導入前は手動でアップデートしていたことを考えるとだいぶ楽になったと思う反面、レビューがそれなりに大変なので、Auto Mergeを有効化するなど引き続き改善していきたいと思います。