GitHubのCODEOWNERSを使って自動レビュー依頼&コードの品質を担保する

CI/CD

はじめに

「mainにマージしちゃったの!?CD組んでるからリソース変わっちゃうじゃん!!」
そんな思わぬデプロイが実行されるのを防ぎたい。

「このプルリクエストの承認者は誰にすべきか分からない。聞きたいけど〇〇さん集中してるなぁ、、」
そんな疑問を解消し、確認する手間や精神的な負担を軽減したい。

CODEOWNERSを活用すると、レビューの効率化や責任の明確化を図り、チーム全体の生産性を向上させることができます。この記事ではCODEOWNERSの使い方を紹介します。

CODEOWNERSとは

CODEOWNERSは、GitHubのリポジトリ内で特定のファイルやディレクトリに対して責任を持つユーザーやチームを指定するための機能です。このファイルを使用すると、Pull Request (PR) の際に自動的にレビュー依頼を送ることができます。

引用:GitHub Blog: CODEOWNERS improvements (syntax errors, preview of who will be requested, and more)

メリット

  • 効率的なレビュー: PRの作成時に適切な担当者が自動的に割り当てられるため、レビューの見落としを防ぎます。
  • 責任の明確化: 各ファイルやディレクトリに誰が責任を持つべきかを明示できます。
  • プロセスの統一: 開発フローに一貫性を持たせることができます。

デメリット

  • 柔軟性の欠如: 一度設定すると、異なるケースに応じて柔軟に対応しづらい場合があります。
  • 管理の手間: 大規模なプロジェクトでは、CODEOWNERSファイルを維持・管理するコストが高くなる可能性があります。
  • 誤解のリスク: 無意識に誤った責任者を指定すると、レビューが適切に行われない恐れがあります。

この機能が活躍する場面

モノレポ構成で開発している人の入れ替わりが激しいなどなど、この機能が活躍する場面は多いと思います。ですが、場合によってはファイルの管理が面倒なのと勝手にレビュワーが設定されてイライラすることがあるのも事実。導入するかどうかはよしなに判断していきたいです。

CODEOWNERSの使い方

ここからは、具体的なCODEOWNERSファイルの書き方を紹介します。

.github/ ディレクトリ配下にCODEOWNERSファイルを作成する

CODEOWNERSファイルは、ルートディレクトリ直下かあるいは .github ディレクトリ配下に配置しましょう。 管理のしやすさから.githubディレクトリ配下 の方が分かりやすいのでオススメです。

CODEOWNERSを設定する

CODEOWNERSとして設定したい個人 or チームを書きましょう。拡張子別、ディレクトリ別など、さまざまな設定ができます。
参考:GitHub公式ドキュメント: Example of a CODEOWNERS file

# This is a comment.
# Each line is a file pattern followed by one or more owners.

# These owners will be the default owners for everything in
# the repo. Unless a later match takes precedence,
# @global-owner1 and @global-owner2 will be requested for
# review when someone opens a pull request.
*       @global-owner1 @global-owner2

# Order is important; the last matching pattern takes the most
# precedence. When someone opens a pull request that only
# modifies JS files, only @js-owner and not the global
# owner(s) will be requested for a review.
*.js    @js-owner #This is an inline comment.

# You can also use email addresses if you prefer. They'll be
# used to look up users just like we do for commit author
# emails.
*.go docs@example.com

# Teams can be specified as code owners as well. Teams should
# be identified in the format @org/team-name. Teams must have
# explicit write access to the repository. In this example,
# the octocats team in the octo-org organization owns all .txt files.
*.txt @octo-org/octocats

# In this example, @doctocat owns any files in the build/logs
# directory at the root of the repository and any of its
# subdirectories.
/build/logs/ @doctocat

# The `docs/*` pattern will match files like
# `docs/getting-started.md` but not further nested files like
# `docs/build-app/troubleshooting.md`.
docs/* docs@example.com

# In this example, @octocat owns any file in an apps directory
# anywhere in your repository.
apps/ @octocat

# In this example, @doctocat owns any file in the `/docs`
# directory in the root of your repository and any of its
# subdirectories.
/docs/ @doctocat

# In this example, any change inside the `/scripts` directory
# will require approval from @doctocat or @octocat.
/scripts/ @doctocat @octocat

# In this example, @octocat owns any file in a `/logs` directory such as
# `/build/logs`, `/scripts/logs`, and `/deeply/nested/logs`. Any changes
# in a `/logs` directory will require approval from @octocat.
**/logs @octocat

# 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. Without an owner, changes
# to `apps/github` can be made with the approval of any user who has
# write access to the repository.
/apps/ @octocat
/apps/github

# In this example, @octocat owns any file in the `/apps`
# directory in the root of your repository except for the `/apps/github`
# subdirectory, as this subdirectory has its own owner @doctocat
/apps/ @octocat
/apps/github @doctocat

とりあえず導入からしばらくは以下のような書き方で、コードオーナーを追加したかったらここにユーザー名追加していくだけっていう運用で良いのかなと思います。

# 適宜追加、削除する
*       @global-owner1 @global-owner2

CODEOWNERSをもっと活用する設定

CODEOWNERSの設定により、PR作成時に自動的にレビュー依頼を出すことができるようになりますが、まだCODEOWNERSの真価を発揮させることができていません。
なぜなら、まだPRにCODEOWNERSによる承認が必須でないためです。
これでは、以下の要求を満たすことはできません。

  • 予期せぬCDによるデプロイを防ぐこと
  • コードの質を担保すること

そのため、ここからはブランチ保護ルールでCODEOWNERSによる承認を必須にする設定の設定方法を紹介します。

設定方法

  1. GitHubリポジトリの Settings タブを開く。
  2. Branches セクションで保護したいブランチを選択または作成する。
  3. Require a pull request before merging オプションを有効化。
  4. Require review from Code Owners を有効にする。

5. Required approvals を最低1にする。
  ※プルリクエストがマージされるまでに必要な承認レビューの数の設定なので、ここは適宜変えてください。

承認が必須になっているか確認

これらの設定すると、PRをマージするのにCODEOWNERSによる承認が必須になっていることを確認できます。

引用:GitHub Blog: CODEOWNERS improvements (syntax errors, preview of who will be requested, and more)

懸念点

CODEOWNERSを導入するにあたり、大したことではないですが懸念点を2点ほど挙げます。

構文に気をつける

CODEOWNERS構文には注意点があるようです。:

  • #に注意: #で始まる行はコメントではなくパターンとして認識されます。
  • エスケープが無効: \を使ってパターンをエスケープしても動作しません。
  • 否定パターン: !を使ったパターンの否定が機能しません。
  • 文字範囲: [ ]を使った文字範囲の指定もサポートされていません。

ただ、GitHub上でCODEOWNERSファイルを選択すると、構文が正しいかどうかや指定したユーザーが存在するかどうかをチェックしてくれるので、構文に不安がある場合などは確認してみてください。

あえて構文ミスをしてみました。!を使った否定パターンがエラーになってます。

CODEOWNERSファイルのサイズ制限

ファイルのサイズは最大3MBまでという制限がありますが、ここまで使うチームそうないと思うので問題ないかと。


CODEOWNERSは、プロジェクトにおける責任の明確化とレビューの効率化を実現するための非常に強力なツールです。本記事で紹介したように、ファイルやディレクトリごとに適切な責任者を設定することで、開発プロセスの一貫性を保ちながら、チームの生産性を向上させることができます。

CODEOWNERSを適切に活用し、チーム全体で効率的かつスムーズな開発フローを実現していきましょう。本記事が、皆さんのプロジェクトでのCODEOWNERS導入や運用の参考になれば幸いです。

参考資料: