GitHub Actions を利用したコードレビュー依頼の自動化

変更ファイルや所属グループを元に自動でコードレビュー依頼を出すことができる GitHub Action を紹介したいと思います！実際のユースケースを元に製作し運用しているので、同じように役に立つチームもあるのではないかと思います！

* [Auto Request Review](https://github.com/marketplace/actions/auto-request-review)

具体的には「コードオーナーとレビュアーを分けたい（誰がマージ可能かを区別するため）」や「GitHub のメンバーの数が多すぎて毎回レビュアーを探すのが手間かつ、常に同じメンバーにしかレビュー依頼を出さない」というケースで、非常に役立っています。

## モチベーション

誰がどのプルリクエストをレビューするかは、チームによって様々だと思います。ランダムにレビューをアサインするチームもあれば、チームメンバー全員に見てもらうという方針のチームもあるかと思います。GitHub の[コードレビューアサインメント](https://docs.github.com/en/github/setting-up-and-managing-organizations-and-teams/managing-code-review-assignment-for-your-team)や[コードオーナー](https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners)を利用することで、ある程度のユースケースは確かにカバー可能ですが、カバーできないケースもまた存在します。

本記事で紹介する [Auto Request Review](https://github.com/marketplace/actions/auto-request-review) では、以下のケースをカバーすることが可能です！

- 変更されたファイルを元にレビュー依頼を出したい
- プルリクエスト作成者に応じたレビュアーを指定したい
- 自分のチームメンバー全員にレビューをしてもらいたい
- レビュアーとコードオーナーを区別したい

要は、ある特定のメンバーに対して、所属グループや変更ファイルを元にしてレビュー依頼を出したい場合に役立ちます。


### コードオーナーとレビュアー
コードオーナーはそのコードに対して責任がある人であり、レビュアーはレビューをする人だと言えると思います。そして、チームによっては明確にこれらを区別していることがあります。例えば、プルリクエストをマージするのに、「コードオーナーの承認 + チームメンバーの誰か」としているチームもあると思います。また、「コードオーナーには絶対見てほしいけど、他の人には時間があれば見ておいてほしい」みたいなケースもあるかと思います。


## 主な機能
以下のことが可能になります。

- 変更ファイルを元に自動でレビュアーをアサインする
- プルリクエスト作成者ごとに個別のレビュアーをアサインする
- プルリクエスト作成者の所属するグループを元に自動でレビュアーをアサインする
- どのレビュアーにもマッチしなかった場合、デフォルトのレビュアーをアサインする
- 特定の条件でのみレビュー依頼を出す

### 変更ファイルを元に自動でレビュアーをアサインする
[glob](https://en.wikipedia.org/wiki/Glob_(programming))を使ってレビュアーを定義できます。

```yaml
files:
  '**/*.js':
    - js-lovers
```

### プルリクエスト作成者ごとに個別のレビュアーをアサインする
プルリクエスト作成者ごとに個別のレビュアーを設定できます。

```yaml
reviewers:
  groups:
    engineers:
      - engineer_a
      - engineer_b
  per_author:
    engineers:
      - engineers
    designer_a:
      - lead_designer
    designer_b:
      - lead_desinger
      - desinger_a
```


### プルリクエスト作成者の所属するグループを元に自動でレビュアーをアサインする
グループアサインメントの機能を有効にしていれば、プルリクエスト作成者の所属するメンバー全員に自動でレビュー依頼が送られます。

```yaml
reviewers:
  groups:
    js-lovers:
      - js-man
      - js-woman

options:
  enable_group_assignment: true
```

### どのレビュアーにもマッチしなかった場合、デフォルトのレビュアーをアサインする
デフォルトのレビュアーも設定可能です。どのレビュアーもマッチしなかった場合、この方達に依頼が飛びます。

```yaml
reviewers:
  default:
    - repository-owners
```

### 特定の条件でのみレビュー依頼を出す
もしまだ準備できてないプルリクエストのレビューをしてほしくない、というのであれば、 `ignore_draft` と `ignored_keywords` オプションが利用可能です。

プルリクエストが下書き状態かつ `ignore_draft` が `true` であれば、レビュー依頼は送られません。また、プルリクエストのタイトルに `ignored_keywords` に定義されている文字列が含まれている場合も同様です。

```yaml
options:
  ignore_draft: true
  ignored_keywords:
    - DO NOT REVIEW
```

## 設定
2つの YAML ファイルを準備する必要があります。

- レビュアー設定
- ワークフロー設定

### レビュアー設定
レビュアーの設定用ファイルです。[glob](https://en.wikipedia.org/wiki/Glob_(programming)) を利用し、レビュアーを定義することができます。 内部実装には [minimatch](https://github.com/isaacs/minimatch) を利用しています。

フォーマットは以下のとおりです。

```yaml
reviewers:
  # デフォルトレビュアー
  defaults:
    - repository-owners
    - octocat

  # レビュアーグループ（GitHub usernames の配列）
  groups:
    repository-owners:
      - me # username
      - you # username
    core-contributors:
      - good-boy # username
      - good-girl # username
    js-lovers:
      - js-man # username
      - js-woman # username

  # プルリクエスト作成者ごとのレビュアー
  # キーがレビュイーで、それぞれレビュアーの配列を持つ
  per_author:
    engineers:
      - engineers # group
    lead_designer:
      - js-lovers # group
      - desinger_a # username
    designer_a:
      - lead_designer # username
    designer_b:
      - lead_desinger # username
      - desinger_a # username

files:
  # キーが glob での表現になります
  # 上で定義したレビュアーグループもしくは GitHub usernames が利用可能です
  '**':
    - repository-owners # group
  '**/*.js':
    - core-contributors # group
    - js-lovers # group
  '**/*.yml':
    - core-contributors # group
    - yamler # username
  '.github/**':
    - octopus # username
    - cat # username

options:
  ignore_draft: true
  ignored_keywords:
    - DO NOT REVIEW
  enable_group_assignment: false
```

設定ファイルはデフォルトでは `.github/auto_request_review.yml` ですが、ワークフローの設定ファイルで上書きが可能です。

### ワークフロー設定
ワークフローの設定ファイルを `.github/workflows`内に作成します。 例えば `.github/workflows/auto_request_review.yml` のような感じです。

```yaml
name: Auto Request Review

on:
  pull_request:
    types: [opened, ready_for_review, reopened]

jobs:
  auto-request-review:
    name: Auto Request Review
    runs-on: ubuntu-latest
    steps:
      - name: Request review based on files changes and/or groups the author belongs to
        uses: necojackarc/auto-request-review@v0.2.0
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          config: .github/reviewers.yml # Config file location override
```