📖

renovate automerge 運用と CODEOWNERS 運用をいかに両立させるか

2023/07/05に公開

はじめに

renovate による automerge と CODEOWNERS との相性の悪さがある。

簡単に説明すると、GitHub の Branch protection rule に Require approvalsRequire review from Code Owners が設定されている場合、CODEOWNERS ファイルで指定しているパスを renovate が変更すると automerge ができないという話。

なぜかというと、自動 Approve に使われるような GitHub Bot は CODEOWNERS に追加できない仕様のためである。

renovate が用意しているこういう Bot が、

https://github.com/apps/renovate-approve
https://github.com/apps/renovate-approve-2

CODEOWNERS に追加できない。

https://github.com/renovatebot/renovate-approve-bot/issues/29#issuecomment-673332699

renovate もこのように言及しており、

Important note: Due to a GitHub limitation, it is not possible to assign any app like this one as a CODEOWNER, so unfortunately this bot won't work that way if you have CODEOWNERS set up.

https://github.com/apps/renovate-approve

CODEOWNERS 設定したなら、code owner がその PR 見なきゃいけないんだよって言ってる(それはそう

Depending on the platform, having a CODEOWNERS file could block automerging, because it means a code owner must review the PR.

https://docs.renovatebot.com/key-concepts/automerge/#codeowners

悲しいけど、どうやってこの仕組みに立ち向かっていくかという話。

どうやるか

この2択だと思う。renovate に automerge させる方が簡単。

まずは簡単な方から説明

renovate に automerge させるには

  1. renovate が触るファイルのパスをCODEOWNERSから除外する
  2. renovate-approve(GitHub Bot)に repo の権限を付与する
  3. renovate.json をいじって automerge の設定をしよう

renovate が触るファイルのパスをCODEOWNERSから除外する

除外パターンはこんな感じで書ける

# In this example, @octocat owns any file in the `/apps`
# directory in the root of your repository except for the `/apps/github`
# subdirectory, as its owners are left empty.
/apps/ @octocat
/apps/github

CODEOWNERS ファイルは後勝ちなので、上で広くとって、下で empty で上書きする感じ。

https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners#example-of-a-codeowners-file

renovate-approve(GitHub Bot)に repo の権限を付与する

以下の GitHub Bot に該当のリポジトリの権限を付与する。
Approve 必要数が2までしか renovate だけでは対応できない。

https://github.com/apps/renovate-approve
https://github.com/apps/renovate-approve-2

※ Approve 必要数が1のリポジトリなら、Bot は一個でいいのですが、たまに Bot が発火しないことがあるため2つ入れておくと安定感が増すらしい

renovate.json をいじって automerge の設定をしよう

automerge の設定

ドキュメント見ながらやるのが良さそう
https://docs.renovatebot.com/key-concepts/automerge/

主にこのあたりが、オートマージ自体の設定になります。

{
      "automerge": true,
      "platformAutomerge": true,
}

automerge するパッケージはまとめた方がいい

main ブランチの更新が静かにならないとオートマージされないという話があり、

Keep in mind that Renovate automerges take a bit of time, do not expect Renovate to automerge a PR the second it opens and passes tests. Wait for at least an hour or two before troubleshooting to ensure that Renovate has had the time to run once in a state where tests have passed and the branch is up-to-date with its base branch. If you or others keep committing to the default branch then Renovate cannot find a suitable gap to automerge into!

https://docs.renovatebot.com/key-concepts/automerge/#introduction

また、オートマージ自体が main ブランチの更新になってしまうので、オートマージしたいブランチが複数あると、オートマージ待ち行列ができてしまう。

たとえば、オートマージしたい patch-A ブランチと patch-B ブランチができた場合、patch-A がオートマージされると、

patch-B は rebase して同様の commit を force push する。
んで、CI が pass してしばらく経つとオートマージされる。

このサイクルに時間を使ってしまうので、なるべくオートマージしたいパッケージはまとめておくと良さそう。
groupName を設定することでまとめることができる。
https://docs.renovatebot.com/configuration-options/#groupname

また、main ブランチのコミットが活発な場合は、 automergeSchedule を夜間や週末などコミットが閑散な時間帯に設定するといいかもしれない。

CIが走らないとオートマージできないのでその時は ignoreTests を設定する

オートマージするためには CI が pass していないといけない。逆にいうと CI が走る必要がある。

このパッケージの更新だけだと CI は走らないんだよ〜ってものがあれば、ignoreTests を設定しておこう
https://docs.renovatebot.com/configuration-options/#ignoretests

オートマージできなかったらレビュワーを指定してくれるので指定しておくと良い

When automerge is enabled on a PR, Renovate will not add assignees or reviewers at PR creation time, in order to decrease notifications noise a little. If tests subsequently fail, making automerge not possible, then Renovate will add the configured assignees and/or reviewers.

https://docs.renovatebot.com/key-concepts/automerge/#assignees-and-reviewers

オートマージできるならレビュワーにアサインしちゃうとノイズになっちゃうのでやらないよ。オートマージできなかったらレビュワーにアサインするよ、的なことを言っている。
レビュワーは、

{
  "reviewers": ["team:team-name"],
}

みたいな感じで設定できる。organization の場合、@org/team-name@org/ 部分は不要。
https://docs.renovatebot.com/key-concepts/automerge/#assignees-and-reviewers

チームを当てたが、個人を当ててもいい。

自動approve,merge する仕組みを別途作るには

次に、2択の後者、renovateが出したPRに自動 approve,merge する仕組みを別途作るには、という話だが、これはそういう GitHub Actions なりを作る必要がある。
たとえば、以下のような仕組みを作るイメージ

  • renovate が作った automerge したいPRを判別しやすくする(ここまで renovate.json
    • ラベリングさせておくといい
  • そいつに対して、CODEOWNERS に属するアカウントの PAT(マシンアカウントのものが好ましい)で Approve をする(ここからは GitHub Actions
  • Approve が成功したらマージする、またはオートマージを true にする
    • gh pr merge --merge --auto "1" みたいなイメージ
    • こういう GitHub Actions があったりするので、↑でラベリングした PR が作られたらこいつを走らせるみたいなワークフローを組むと良さそう

Discussion