Github Actionで個人開発でも簡単にブランチを保護しよう

# はじめに
Github Actionみなさん使ってますか？
もしCIとして使い始めてるなら簡単にブランチの保護設定ができるのでご紹介します。
個人開発のケースみたいにライトに事故防止ができるので結構捗っています。


# ブランチの保護設定とは
こんな感じでCIのパスやレビューのapproveがないとマージできない設定です。
<img width="786" alt="スクリーンショット 2020-01-04 21.58.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152938/f97a8016-f30a-edf1-8714-744cd56ab064.png">

今回は個人開発を想定しているので、Github Actionによるブランチ保護設定のみご紹介します。

# 設定手順

## 今回扱うGithubActionについて
先にパスすべきGithub Action設定を行います。
詳しくは説明しませんが、例として現在個人開発で運用しているファイルを晒します。
jobにはユニットテスト用の`test`と結合テスト用の`up`でそれぞれ名前をつけて運用しています。
今回の保護設定はこの`test`と`up`をパスすればマージできるように設定します。


```yml

name: Node CI

on:
  - pull_request

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: init variable
        run: sed -e "s|<GITHUB_TOKEN>|${GITHUB_TOKEN}|" -e "s|<FIREBASE_TOKEN>|${FIREBASE_TOKEN}|" .env.example > .env
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
      - name: run test
        run: make test
      - name: slack notification
        uses: 8398a7/action-slack@v2
        if: always()
        with:
          status: ${{ job.status }}
          username: github-functions
          icon_emoji: ':octocat:'
          text: ":eyes: :eyes: :eyes: テスト終わったよ :eyes: :eyes: :eyes: :eyes:"
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  up:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: init variable
        run: sed -e "s|<GITHUB_TOKEN>|${GITHUB_TOKEN}|" -e "s|<FIREBASE_TOKEN>|${FIREBASE_TOKEN}|" .env.example > .env
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
      - name: run test
        run: make e2e
      - name: slack notification
        uses: 8398a7/action-slack@v2
        if: always()
        with:
          status: ${{ job.status }}
          username: github-functions
          icon_emoji: ':octocat:'
          text: "デプロイ準備完了 :+1: "
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

Pull requestの度に稼働させていたいので、

```yml
on:
  - pull_request
```

とjobのフックをpull requestに設定させています。

## github.com上の設定
* 設定したいブランチのsettings > branchesにアクセス
* 右の`Add rule`をクリック

<img width="1026" alt="スクリーンシ<img width="1026" alt="スクリーンショット 2020-01-04 22.25.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152938/a60d4af5-11a7-7bb3-ba24-b3a1c14e0d9d.png">


* 保護したいブランチ名をBranch Name Patternに入力  
詳しくは[公式](https://help.github.com/ja/github/administering-a-repository/configuring-protected-branches)を見るとよきですが、ワイルドカード(`*`)も使えます(e.g. develop/* …etc）

* 以下２つのチェックをつける
  * Require status checks to pass before merging
  * Require branches to be up to date before merging

* 必要なステータスにもチェックをつける
  Github Actionを追加済みの場合ここにjob名が追加されているはずなので、必須化させたいjob名のチェックをつけます(今回は`test`と`up`を選択)。
もし追加されていない場合は先にPRを立てるなりしてActionを動かす必要はあるかもです。
<img width="743" alt="スクリーンショット 2020-01-04 22.49.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152938/75d3657f-ee55-bada-96bd-b00b586a2503.png">

* 管理者も設定対象にする
  *  Include administratorsにチェックを入れる。個人開発の場合おそらくリポジトリは管理者権限のあるアカウントで開発を行うはずなのでこのチェックをいれましょう。

* 保存する
スクロールすると `save changes`があるのでボタンをクリックして設定を保存します。(初回は`create`です）

<img width="893" alt="スクリーンショット 2020-01-05 8.43.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152938/e40f0780-3041-afdc-401a-3c1cad7f51b3.png">



以上です。お疲れ様でした。

# 余談
## ステータス追加でファイルを選ぶと動かない？
このような形で一生pendingしてました。バグかわからないですが、job名を明示的に指定するほうが無難で良さそうですね。
<img width="795" alt="スクリーンショット 2020-01-04 22.55.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152938/b108e82a-452f-b003-11e1-dbcb79d49f85.png">

## Circle CIの場合
https://circleci.com/docs/2.0/enable-checks/
もちろん、Github Actionじゃないと出来ない設定ではありません。Circle Ciや他CIでもできる設定です。

# 感想
別にGithub Actionじゃないと出来ないわけではないですが、Github内で完結して安全な設定が自然とできることは結構メリット大きいんじゃないでしょうか？
色々楽に設定ができるので助かってます。