GitHub Actionsでチームの人に自動でレビューをアサインする

# はじめに
GitHubでチームの人にレビューをアサインする際、メンバーが多いと一人一人アサインしていくのはとても面倒ですよね。
そこでこの記事では、GitHub ActionsでPR作成時にチーム内の人に自動アサインするワークフローを作ってみます。

今回は以下のactionを使用させていただきました。
https://github.com/marketplace/actions/review-assign-action

# 実装
```yaml:.github/workflows/review-assign.yml
name: Review Assign
 
on:
  pull_request:
    types: [opened, ready_for_review, edited]
 
jobs:
  assign:
    runs-on: ubuntu-latest
    steps:
      - uses: hkusu/review-assign-action@v1
        with:
          assignees: ${{ github.actor }}
          reviewers: hoge, fuga, piyo
          draft-keyword: wip
```
これだけです。
アサイン処理が走るトリガーは以下の通り。
（トリガー内容は筆者が確認できている範囲です。まさか公式に詳細が記載されていないとは...）

- opened
    - PRが作成されたとき
- ready_for_review
    - draft PRから通常のPRに変更したとき
- edited
    - PRのタイトルや概要を編集したとき

また、`draft-keyword: wip`を設定しているので、PRタイトルにwip（大文字小文字区別なし）が含まれているとアサインされません（wipを編集で外すとアサインされます）。

上記トリガーでワークフローが走ったら、`reviewers`に指定したhoge、fuge、piyoさんにアサインされます。
（`assignees`はPR作成者がGitHub上でわかりやすく表示されます。不要なら削除して構いません。）

しかし、この実装だとreviwerが増減するたびにファイルの変更が必要となります。面倒ですね。
これを改善するために、GitHubのTeamsを活用します。

```yaml:.github/workflows/review-assign.yml
name: Review Assign
 
on:
  pull_request:
    types: [opened, ready_for_review, edited]
 
jobs:
  assign:
    runs-on: ubuntu-latest
    steps:
      - name: Get Reviewers List
        run: |
          team=$(curl -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ORG_TOKEN }}" https://api.github.com/orgs/<Organization名>/teams/<自分の所属するチーム名>/members | jq -r '.[].login | select(. != "${{ github.actor }}")')
          reviewers=`echo "${team}" | sort | uniq -u | tr '\n' ',' | sed -e 's/,$//'`
 
          echo ${reviewers}
          echo "::set-output name=REVIEWERS::${reviewers}"
        id: reviewers
      - name: Assign Review
        uses: hkusu/review-assign-action@v1
        id: assign
        with:
          assignees: ${{ github.actor }}
          reviewers: ${{ steps.reviewers.outputs.REVIEWERS }}
          draft-keyword: wip
```

これで、自分を除くチームメンバーに自動でアサインすることができるようになりました。

# Appendix：TeamsにChild Teamsが紐づいている場合
最後に少し特殊なケースとして、GitHubのTeamsにChild Teamsが紐づいているケースを見ていきます。
Child Teamsが紐づいているケースとしては、バックエンドチームが管理しているリポジトリにSREもCI/CDの関係でリポジトリ管理に携わっているケースなどです（バックエンドのTeamsにSREのChild Teamsが紐づいている）。
この場合、バックエンドの範囲でのコード修正はバックエンドメンバーにレビューいてもらいたいですよね。そこで以下のように実装してみます。

```yaml:.github/workflows/review-assign.yml
name: Review Assign
 
on:
  pull_request:
    types: [opened, ready_for_review, edited]
 
jobs:
  assign:
    runs-on: ubuntu-latest
    steps:
      - name: Get Reviewers List
        run: |
          child=$(curl -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ORG_TOKEN }}" https://api.github.com/orgs/<Organization名>/teams/<chile teams名>/members | jq -r '.[].login')
          if [ `echo "${child}" | grep ${{ github.actor }}` ]; then
                exit 0
          fi
 
          team=$(curl -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.ORG_TOKEN }}" https://api.github.com/orgs/<Organization名>/teams/<自分の所属するチーム名>/members | jq -r '.[].login | select(. != "${{ github.actor }}")')
          reviewers=`echo -e "${team}\n${child}" | sort | uniq -u | tr '\n' ',' | sed -e 's/,$//'`
 
          echo ${reviewers}
          echo "::set-output name=REVIEWERS::${reviewers}"
        id: reviewers
      - name: Assign Review
        uses: hkusu/review-assign-action@v1
        id: assign
        with:
          assignees: ${{ github.actor }}
          reviewers: ${{ steps.reviewers.outputs.REVIEWERS }}
          draft-keyword: wip
```

# おわりに
いかがでしたでしょうか。
今回はワークフローの実行にパーソナルアクセストークンを使用していますが、個人に依存した実装だと属人性が排除できないのでGitHub Appsなどで生成したTokenを使う方がいいでしょう。こちらは後日追記していきたいと思います。
ではまた。

# 参考記事
https://qiita.com/hkusu/items/39eb92dbd4d6db8a14d8