Github Actionsを使ってSlackにいい感じにSuccess, Failを送る

###はじめに

Github Actionsを使ってPRのタイミングでテストが通ったか落ちたかの判定をしたい。
Github ActionsのSlack連携が日本語であまり見つからなかったので、後に続く人のためにこの記事を残そうと思う。
※Deployは含まれておりません。

---

###対象となる読者

`Github Actions` でCI/CDにライトにトライしたい方。

---

###大まかな手順

- 対象のGithubリポジトリ作成
- .github/workflows/pullrequest.ymlを準備 (ymlのファイル名は何でも良い)
- [Slack Apps](https://api.slack.com/apps)の作成
- pullrequest.ymlと作成したSlack APP(Github Actions)の連携

ymlにはMarketplaceから以下の2つを導入しました。
[GitHub Action for Yarn](https://github.com/marketplace/actions/github-action-for-yarn)
[Post Slack messages](https://github.com/marketplace/actions/post-slack-message)

---

### ymlの設定(Slack連携前)

<img width="1440" alt="スクリーンショット 2020-06-26 16.39.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170254/2fe3fdd4-9a25-0c34-3413-6d7e9280643a.png">

図のようにリポジトリのActionタブから直接作成可能ですが、今回はローカルで作成しました。

`.github/workflows/pullrequest.yml` を作成

```pullrequest.yml
# This is a basic workflow to help you get started with Actions

name: Pull request CI

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
  pull_request:
    branches:
      - master
      - develop

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  build:
    name: Build & Test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: borales/actions-yarn@v2.0.0
        name: yarn install
        with:
          cmd: install # will run `yarn install` command
      - uses: borales/actions-yarn@v2.0.0
        name: yarn build
        with:
          cmd: build # will run `yarn build` command
      - uses: borales/actions-yarn@v2.0.0
        name: yarn run check
        with:
          cmd: run check # will run `yarn run check` command
      - uses: borales/actions-yarn@v2.0.0
        name: yarn run lint
        with:
          cmd: run lint # will run `yarn run lint` command
```

確認したいのは `Build` と `Prettier` でのフォーマッティングと `ESLint` でのLint。
ちなみに、コマンドのscriptは以下の通りです(一部抜粋)

```package.json
  "scripts": {
    "build": "yarn build",
    "check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,md}\"",
    "lint": "eslint 'src/**/*.js*'",
  }
```

実際にPRを出してみて、Github Actionsが正常に動いているか確認を行います。

### Slack Apps の作成

[Slack api](https://api.slack.com/apps) から `Create New App` を選択する。

<img width="1098" alt="スクリーンショット 2020-06-26 16.54.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170254/d826f7b1-7729-9795-fb3f-f3b7afe8ce04.png">

`App Name` と `Workspace` を選択して `Create App` する。(App Nameは何でもokですがここではGithub Actionsとしています）

<img width="815" alt="スクリーンショット 2020-06-26 16.56.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170254/5b7b637c-8c0d-1fc7-b170-3cb248cb9a49.png">

Iconは適宜入れてあげましょう。

<img width="1440" alt="スクリーンショット 2020-06-26 16.58.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170254/d8f6e7b3-418d-f105-9f8f-a635931ceacd.png">

Iconは [slack-action](https://github.com/abinoda/slack-action/tree/master/docs/app-icons) のリポジトリから取得出来ます。

`Install App to Workspace` から作成した `Github Action` を接続します。
※APPをはじめて作成した場合は、 `OAuth & Permissions > Scopes` が記入されていないので、AppのInstallが出来ません。Scopeを追加しましょう。
ちなみに、ここの `Bot Scope Token` は色々選択出来ますが、 `chat:write` がないとGithub ActionsでSlackに通知が送れないので入れ忘れに注意。

<img width="1440" alt="スクリーンショット 2020-06-26 17.10.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170254/0d5af62b-5481-41ac-5ff5-76e3629d6cc7.png">

### 対象のSlackチャンネルに Slack Appをinviteする

```
#app_nameはあなたが付けたAppの名称
/invite @app_name
```

### Slack Apps と Github Actions の連携

`pullrequest.yml` に以下の記述を追加します。

```pullrequest.yml
      # When test fail
      - name: Notify slack
        if: failure()
        env:
          SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
        uses: pullreminders/slack-action@master
        with:
          args: '{\"channel\":\"SLACK_CANNEL_ID\",\"attachments\":[{\"color\":\"#F32013\",\"blocks\":[{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"*PR Fail:* ${{ github.event.pull_request.title }}\"}},{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"*Who?:* ${{ github.event.pull_request.user.login }}\n*Request State:* ${{ github.event.pull_request.state }}\"}},{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"<${{ github.event.pull_request.html_url }}|View Pull Request>\"}}]}]}'

      # When test pass
      - name: Notify slack
        if: success()
        env:
          SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
        uses: pullreminders/slack-action@master
        with:
          args: '{\"channel\":\"SLACK_CANNEL_ID\",\"attachments\":[{\"color\":\"#2eb886\",\"blocks\":[{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"*PR Success:* ${{ github.event.pull_request.title }}\"}},{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"*Who?:* ${{ github.event.pull_request.user.login }}\n*Request State:* ${{ github.event.pull_request.state }}\"}},{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"<${{ github.event.pull_request.html_url }}|View Pull Request>\"}}]}]}'
```

`SLACK_CANNEL_ID:` ブラウザでSlackのチャンネルにアクセスした時の最後の/以下の文字
`SLACK_BOT_TOKEN:` Slack Appの `Bot User OAuth Access Token > Bot User OAuth Access Token` の値

argsでSlackにどのようなフォーマットで送るか詳しく編集出来ます。

参照:
1. [Block Kit](https://api.slack.com/block-kit) 
2. [Github Actionsコンテキストの構文](https://help.github.com/ja/actions/reference/context-and-expression-syntax-for-github-actions)

### SLACK_BOT_TOKENをGithubで設定

`Setting > Secret` から SLACK_BOT_TOKENを登録します。

<img width="1373" alt="スクリーンショット 2020-06-26 17.42.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170254/4a0d29db-eee6-3b5f-5c30-efed344a9dc9.png">

### Slackの通知結果

<img width="443" alt="スクリーンショット 2020-06-26 17.38.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170254/6e409b73-4bfb-3b3e-9f56-e610cd355739.png">

テストが通った場合と落ちた場合が色分けして出力されます。

最終コード↓

```pullrequest.yml
# This is a basic workflow to help you get started with Actions

name: Pull request CI

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
  pull_request:
    branches:
      - master
      - develop

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  build:
    name: Build & Test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: borales/actions-yarn@v2.0.0
        name: yarn install
        with:
          cmd: install # will run `yarn install` command
      - uses: borales/actions-yarn@v2.0.0
        name: yarn build
        with:
          cmd: build # will run `yarn build` command
      - uses: borales/actions-yarn@v2.0.0
        name: yarn run check
        with:
          cmd: run check # will run `yarn run check` command
      - uses: borales/actions-yarn@v2.0.0
        name: yarn run lint
        with:
          cmd: run lint # will run `yarn run lint` command

      # When test fail
      - name: Notify slack
        if: failure()
        env:
          SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
        uses: pullreminders/slack-action@master
        with:
          args: '{\"channel\":\"SLACK_CANNEL_ID\",\"attachments\":[{\"color\":\"#F32013\",\"blocks\":[{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"*PR Fail:* ${{ github.event.pull_request.title }}\"}},{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"*Who?:* ${{ github.event.pull_request.user.login }}\n*Request State:* ${{ github.event.pull_request.state }}\"}},{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"<${{ github.event.pull_request.html_url }}|View Pull Request>\"}}]}]}'

      # When test pass
      - name: Notify slack
        if: success()
        env:
          SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
        uses: pullreminders/slack-action@master
        with:
          args: '{\"channel\":\"SLACK_CANNEL_ID\",\"attachments\":[{\"color\":\"#2eb886\",\"blocks\":[{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"*PR Success:* ${{ github.event.pull_request.title }}\"}},{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"*Who?:* ${{ github.event.pull_request.user.login }}\n*Request State:* ${{ github.event.pull_request.state }}\"}},{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"<${{ github.event.pull_request.html_url }}|View Pull Request>\"}}]}]}'
```

やったね！