Github Actionsで大体自動化してみた話

# はじめに
今回は前回、前々回、前々前回の続きの話です
前回 → [Github Actionsを使ってSlackに通知してみた話](https://qiita.com/dosukoi_android/items/612dcb79fe84b2d8bb50)
前々回  → [Github Actionsを使って自動テストする話](https://qiita.com/dosukoi_android/items/a3464548b3aa293c62dd)
前々前回 → [Github Actionsを使ってDeployGateにデプロイする話](https://qiita.com/dosukoi_android/items/e41f5c2c2a7120685af8)

これらを使ってGithubのフローを大体自動化してみましょう

# 自動化の適用範囲


テストをCIで走らせるタイミングはチームによって変わってきますが、現在僕が参加しているチームではGithub Actionsの実行時間が増えるのがあまりよろしくないので(お金がかかるから)、Approveした段階でテストを回すようにしています。

またビルドに関してもプルリクエストを出すタイミングのみCIを走らせています。

なので自動化するのは
Approveした後のテスト→Slack通知→マージ→デプロイ

ここの部分を自動化しました。

つまりレビュワーがApproveしたらあとは全て自動でやってくれます
とても便利ですね

# やり方

テストの方法、Slack通知、デプロイの方法は上記のリンクから見てください

まずは全体を見ていきましょう

```yaml
name: DevUnitTest

on:
  pull_request_review:
    types: [ submitted ]
    branches: [ master ]

jobs:
  test:
    if: github.event.review.state == 'approved'
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: set up JDK 1.8
        uses: actions/setup-java@v1
        with:
          java-version: 1.8
      - name: UnitTest
        run: ./gradlew testDebugUnitTest
      - name: Unit Test Success Notification
        if: ${{ success() }}
        run: |
          curl \
            -X POST \
            -H "Content-Type: application/json" \
            -d '{"attachments": [{"color": "#26A745", "title": "${{ github.event.pull_request.title }}", "title_link": "${{ github.event.pull_request.html_url }}", "text": "Success Unit Test", "author_name": "${{ github.event.pull_request.user.login }}"}]}' \
            ${{ secrets.SLACK_WEBHOOK}}
      - name: Unit Test Failure Notification
        if: ${{ failure() }}
        run: |
          curl \
            -X POST \
            -H "Content-Type: application/json" \
            -d '{"attachments": [{"color": "#D73A49", "title": "${{ github.event.pull_request.title }}", "title_link": "${{ github.event.pull_request.html_url }}", "text": "Failure Unit Test", "author_name": "${{ github.event.pull_request.user.login }}"}]}' \
            ${{ secrets.SLACK_WEBHOOK}} && exit 1
      - name: Wait For Status Check
        if: ${{ success() }}
        run: sleep 5s
      - name: Automatic Merge
        if: ${{ success() }}
        run: |
          curl \
          -X PUT \
          -H "Authorization: token ${{ secrets.PERSONAL_ACCESSTOKEN }}" \
          -H "Content-Type: application/json" \
          -d '{"sha": "${{ github.event.pull_request.head.sha }}", "merged": "true", "message": "Pull Request successfully merged"}' \
          "${{ github.event.pull_request.url }}/merge"

```

# 解説
今回はマージの部分のみ見ていきます。

```yaml
- name: Wait For Status Check
  if: ${{ success() }}
  run: sleep 5s
  - name: Automatic Merge
  if: ${{ success() }}
  run: |
    curl \
    -X PUT \
    -H "Authorization: token ${{ secrets.PERSONAL_ACCESSTOKEN }}" \
    -H "Content-Type: application/json" \
    -d '{"sha": "${{ github.event.pull_request.head.sha }}", "merged": "true", "message": "Pull Request successfully merged"}' \
    "${{ github.event.pull_request.url }}/merge"
```

## 処理を待たなきゃいけない！？

```yaml
- name: Wait For Status Check
  if: ${{ success() }}
  run: sleep 5s
```

この部分を見て、「ん？なぜ5秒も待つ必要がある？」と思った方もいるかもしれません。
僕もその一人です。

これをしないと
``Head branch was modified. Review and try the merge again.``

と怒られてしまうのです。

正直原因はほぼわかりません
https://stackoverflow.com/questions/38796617/how-to-avoid-delaying-github-pull-request-merge-using-api
こちらが関係してそうですが、原因わかる方教えていただけたら幸いです。

## マージする
あとはマージするのみ！

```yaml

- name: Automatic Merge
  if: ${{ success() }}
  run: |
    curl \
    -X PUT \
    -H "Authorization: token ${{ secrets.PERSONAL_ACCESSTOKEN }}" \
    -H "Content-Type: application/json" \
    -d '{"sha": "${{ github.event.pull_request.head.sha }}"}' \
    "${{ github.event.pull_request.url }}/merge"
```

[Githubのマージ用のAPI](https://developer.github.com/v3/pulls/#merge-a-pull-request)を叩きます
必要な情報は以下の通り
![スクリーンショット 2020-11-21 18.25.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411927/c8df15b0-6648-0db4-486d-beace7b01954.png)


必須なのはshaのみなので、[pull_request_reviewのWebhookのpayload](https://docs.github.com/ja/free-pro-team@latest/developers/webhooks-and-events/webhook-events-and-payloads#pull_request_review)から持ってきます。

# まとめ
以上でGithub Actionsの自動化は終わりになります。

まとめると

1. プルリクエストを出す
2. レビューする
3. ダメだったら修正
4. Approveする
5. [自動でテスト](https://qiita.com/dosukoi_android/items/a3464548b3aa293c62dd)←ここから自動化
6. マージする(今回の記事)
7. [Slackに通知](https://qiita.com/dosukoi_android/items/612dcb79fe84b2d8bb50)
8. [デプロイ](https://qiita.com/dosukoi_android/items/e41f5c2c2a7120685af8)

CIの目的は人間以外でできる作業はとことんサボること、ヒューマンエラーをなくすることです
今回のCIでそれをほとんど達成できたと思います。

個人的に心残りは大体CircleCIでやりたかったんですが、CircleCIだとGithub Actionsほどトリガーがないので(自分調べ)ここまで便利にできないということですね

# P.S.
Approve何度もしてくれたテックリード、感謝申し上げます