npmパッケージなどはrenovateにより自動で更新PRを出すことができる。その良い設定と運用を考察。
前提
- npmパッケージ更新PRが複数あると、1つマージすると ほぼ必ず
pnpm-lock.yaml
などのロックファイルやpackage.json
がconflictし、rebase/mergeやconflict解消が必要になる。 - github branch protectionでPRのブランチが最新であることをマージ条件として必須にしてある。
-
同じくbranch protectionでCODEOWNERSのレビュー必須にしており、renovateのautomerge
設定は運用できないのでfalseにしてある。- package.jsonなど、renovateが変更するファイルパスをCODEOWNERSから除外すれば(それらを人間が変更してもレビュー不要になってしまうが)、自動マージでき、大幅に効率化できる
- https://zenn.dev/kimuchan/articles/9152895c1761a9
rebaseWhen
rebaseWhenはデフォルトでautoだが、これはneverの方がよい。
rebaseWhen: 'never',
後述のprConcurrentLimitが1でない場合はrenovate のPRが複数同時にできる。そのとき何か1つPRマージするたびに全renovate PRが自動でrebaseされる。CIリソースを無駄に使う上、1つずつしかマージできないので、renovate PRを10個処理するだけでも9+8+7+6+5+4+3+2+1回のrebaseとCIが走る。しかもrenovate PRが10個のまま滞留していると、renovateでないPRをマージしても常に10回rebaseされ続ける。実際に発生した問題としてこれが起因でgithub actions・vercel・chromaticの枠を浪費した。
また、renovateのバグか分からないが、自動commitと組み合わせると危険なときがある。あるPRで自前のGithub Actionによる自動commitとrenovateによるrebase commitを無限に繰り返し上書きし合う挙動をしたことがあり、これもCIリソースを浪費した。
公式は
It is also recommended to avoid rebaseWhen=never as it can result in conflicted branches with outdated PR descriptions and/or status checks.
Avoid setting rebaseWhen=never and then also setting prCreation=not-pending as this can prevent creation of PRs.
と非推奨にしているが、PRの状態が最新であることをマージ条件として必須に設定すれば事故は防げるし、PRを最新にrebaseしたかったらチェックボックスを押すだけなので手動でも問題ない。
prConcurrentLimit
prConcurrentLimit はデフォルトで10だが、これを1にすると、1リポジトリに対して1つのPRだけ出て、マージすると次のPRが1つだけ出て、ということを繰り返すようになる。これはメリットとデメリットがあるが、1の方が良いように思われる。
prConcurrentLimit: 1,
1つに絞るメリットとデメリットを考察すると以下のようになる。
- メリット
- renovate PR同士で必ず発生するconflictがなくなり、rebaseしなくていい
- conflict解消,rebaseによるCIやり直しで無駄にリソースを使用しない
- 一度に大量のrenovate PRの通知が来ない
- 処理する時間がないときにも大量のrenovate PRが滞留しない
- デメリット
- 事前に対応工数を見積もろうと思ってもやりづらい
- PRが1つしかできないので、Dependency Dashboardに羅列されている分を見るしかないが、対象のライブラリのリリースノートやcode diffに行きづらいので差分が分かりづらいし、CIが成功するかどうか分からない
- 1つしかPRがないことで油断して忘れているとずっと更新されないライブラリが出てくる
- 事前に対応工数を見積もろうと思ってもやりづらい
複数にする場合、例えば月に1回だけ複数のPRを出し、それを眺めていって工数を見積もり、その月内にそれを全部処理する運用になる。
1つにする場合、一定工数を取ってなるべくその範囲でPRを処理し続ける運用になる。