ライブラリの自動メンテナンスにRenovateを導入してみた
Renovateとは
ライブラリの依存関係を検出し、バージョンを自動更新してくれるツール。様々な言語やバージョン管理ツールに対応している。(公式サイト)
類似ツールはDependabot
導入背景
自分が担当しているシステムはyarn+Node構成でライブラリの定期メンテナンスはGithubActionsでyarnコマンドを駆使して頑張って自動化していましたが、yarnV4へのメジャーバージョンアップ対応でのコマンドの非互換や仕様変更によりGithubActionsが動かなくなってしまいました。
GithubActions内で使用するActionsやコマンド自体のメンテコストもあったため、もっと楽な方法はないか模索した結果Renovateを導入することにしました。
事前準備
PATを作成しておく
GithubでRenoavte用にPAT(Personal Access Token)を作成しておきます。
権限にrepo, read:packagesを追加します。
参考: GitHub and GitHub Enterprise Server
導入手順
参考はInstalling and onboarding Renovate into repositories
RenovateをGithubにインストールする
- https://github.com/apps/renovate からインストールをクリック。
- Renovateを有効にしたいリポジトリを選択してSaveする。
Renovateの詳細設定を行う
-
リポジトリで Renovate を有効にすると、「Configure Renovate」というプルリクエストが作成され、renovate.jsonファイルが追加されている。
-
configure optionsを参考に設定を色々カスタマイズしていく。
-
あとは設定をBaseブランチにマージして指定したスケジュールにPRが作成されるのを待つだけ。
node, yarnの場合のサンプルコード
代表的な設定項目だけ追加したやつ。
より細かい設定をするならconfigure optionsを参照。
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended"
],
"dependencyDashboard": false, // 依存関係ダッシュボード作るか
"timezone": "Asia/Tokyo",
"schedule": [ // renovateを実行するスケジュール
"before 10am on the first day of the month",
"every weekend",
"before 5:00am"
],
"enabledManagers": [
"yarn"
],
"ignorePaths": [ // 除外するディレクトリ
"**/node_modules/**",
"**/bower_components/**",
"**/scripts/fourkeys/**"
],
"separateMajorMinor": false,
"automerge": false, // baseブランチ(main)への自動マージを拒否
"encrypted": {
"npmToken": "{暗号化されたPAT}" // https://app.renovatebot.com/encryptで暗号化した物を指定する
},
"packageRules": [
{
"groupName": "monthly_maintenance", // groupName単位でPRが作成される
"matchDepTypes":[ "dependencies" ],
"matchUpdateTypes": ["minor", "patch"]
},
{
"matchDepTypes": [ "dependencies"],
"matchUpdateTypes": ["major"],
"enabled": false
},
{
"groupName": "monthly_maintenance",
"matchDepTypes":[ "devDependencies" ],
"matchUpdateTypes": ["major", "minor", "patch"]
},
{
"groupName": "monthly_maintenance",
"matchDepTypes":[ "devDependencies" ],
"matchUpdateTypes": ["major"],
"matchPackagePrefixes": ["@types/"],
"enabled": false
},
{
"groupName": "monthly_maintenance",
"matchPackageNames": ["node"],
"allowedVersions": "< 19.0" // enginesも更新されるので制御する
},
{
"groupName": "monthly_maintenance",
"matchPackageNames": ["yarn"],
"allowedVersions": "<= 4.0.2" // yarnも更新されるので制御する
}
]
}
運用してみて困ったこと/嬉しかったこと
😔失敗している原因がわからない
設定ファイルの記述にミスがあったりすると指定した日時にPRが作成されない。
なんてことがありました。
PRが作成されないため、当然何が原因で失敗したかを知る術が無いことが結構困りました。
dependaBotではGithubの画面上から失敗時のログを確認することができるため、Renovateに比べるとデバッグが楽です。
そういう場合は後述するローカルで擬似的にrenovateを実行させるデバッグ方法で設定ファイルの正しさを検証することができます。
😎PRのグルーピング機能が便利だった
Renovatではサンプルコードで記述したように、どのライブラリをどのバージョンまで上げるかみたいな条件を複数指定でき、かつ1つのPRにまとめることができます。
dependaBotではRenovate程細かく設定できず、SemVerやDependency-Type毎にPRが作成される形になります。
devDepの@types系とdepのライブラリはマイナーバージョンまで上げて、devDepの@types以外はメジャーバージョンまで上げるという運用をしていたのでRenovateのグルーピング機能は要件にあっており使いやすかったです。
ローカルでの検証方法
Renovateをローカルにインストールする
# renovateインストール
$ npm install -g renovate
動作をプレビューする
ファイルへの変更やPRを作成せずにメッセージをログに記録してデバッグすることができます。
$ LOG_LEVEL=debug \ # ログレベルを指定
RENOVATE_CONFIG_FILE=./renovate.json \ # 設定ファイルのパスを指定
renovate \
--token=${PAT} \ # PATを指定
--dry-run \ # PRを作成せずに結果をローカル出力するモード
--schedule= \ # 即時実行
--require-config=ignore \ # baseブランチのrenovate.jsonの設定を無視
'{リポジトリ名}' > {出力先ファイル名}.txt"
最後に
今回はアプリケーションコードへの導入を例に紹介しましたが、GithubActionsやIacコードも更新することができるため、ある程度ノウハウが溜まったら別の機会に紹介できたらと思います。
導入コストもそこまでかからないため、もしシステムメンテナンスを自動ができていなければ是非Renovateを導入してみてはいかがでしょうか。
Discussion
// yarnも更新されるので制御する
の行に全角スペースが入ってるのがすごく気になる