2021年の(?)CircleCI Slack通知【Orbs v4】

# TL;DR

久しぶりにCircleCIのセットアップをしたのですが、Slack通知周りの仕様が大きくbreaking changeしていました。
前まではwebhookを登録するだけでサクッと通知できたのですが、びっくりするほど手順が増えていたので、備忘録も兼ねて記事に残しておきます。

OrbsというCircleCIが提供するパッケージを利用するのですが、これはクラウド版のみで利用可能なようで、オンプレミス版でどうするのかについては触れていません。

また、Orbsはv3とv4でも仕様がわりと異なっているみたいで、この記事ではv4について書いています。
(circleci/slack @4.1.4)

加えて、2020/12/23現在はまだ公式ドキュメントも整備されておらず、webhookから簡単に登録できると記載があったりもします。
実際にはCircleCIのUIからwebhookの登録は削除されているため、できません。

以下のツイートで、ドキュメントには`Chat Notifications`という項目があるが新UIではこれが見つからない。どうすればいいか？という質問に対して、公式がOrbsに誘導しています。
公開ささている公式SlackAppも使えなくなっているので、「混乱を避けるために削除しては？」という指摘もされていますね。

![Screen Shot 2020-12-23 at 21.34.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174325/620923aa-a819-ea1d-ec9d-9a7d007e9b86.png)

本当にこんなやり方で合ってるのか？という感じですが、もし違っていたら教えていただきたいです。

# 手順

基本的には https://github.com/CircleCI-Public/slack-orb 通りなので参照してください。
以下では補足しています。

## SlackAppを作成する

READMEに従って、指定の権限を有するSlackAppを作ってください
一点READMEにはない注意事項ですが、botの `display name` を設定しないとWorkspaceへのインストール画面で弾かれます。

## トークンを環境変数に設定する

`SlackAppを作成する` で取得したトークンを、CircleCIの該当のプロジェクトのEnvironment Variablesに`SLACK_ACCESS_TOKEN`という命名で設定します。

合わせて、デフォルトの配信先チャンネルのchannel_idを`SLACK_DEFAULT_CHANNEL`という命名で設定します。
channnel_idは、Slackのweb版から取得できます。

`https://app.slack.com/client/<team_id>/<channel_id>`

## workflowに設定する

Orbs `circleci/slack@4.1.4` では、stepで明示的に通知のタイミング等を指定します。

### templateを使用する場合

現状3種類だけですが、templateが提供されています。
利用方法は https://circleci.com/developer/ja/orbs/orb/circleci/slack にあるとおりです。
`pass` `fail` `always` の3つのeventを指定可能で、stepsで設定します。

templatesの中身は https://github.com/CircleCI-Public/slack-orb/tree/master/src/message_templates で確認できます。

### カスタムする場合

とはいえ3種類しかないので、 `fail` 時にメンションとか要らないなぁ となったときなど、細かい調整が効かないです。
そういうときはCircleCI 2.1の `commands` を使って、自分でtemplatesのようなものを設定できます。

例えばこんな感じの通知を出す場合

![Screen Shot 2020-12-23 at 21.18.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174325/ff0ac1d5-58af-ee33-c9d3-99ffe6d6dacd.png)

以下のようなcommndsを設定します。

```yaml
commands:
  notify-test-passed:
    steps:
      - slack/notify:
          event: pass
          custom: |
            {
              "text": "",
              "blocks": [
                {
                  "type": "header",
                  "text": {
                    "type": "plain_text",
                    "text": ":circleci-pass: All test suites were passed!", # :circleci-pass: は自分で追加したemoji
                    "emoji": true
                  }
                },
                {
                  "type": "section",
                  "fields": [
                    {
                      "type": "mrkdwn",
                      "text": "*Repository*: $CIRCLE_PROJECT_REPONAME"
                    },
                    {
                      "type": "mrkdwn",
                      "text": "*Branch*: $CIRCLE_BRANCH"
                    },
                    {
                      "type": "mrkdwn",
                      "text": "*Author*: $CIRCLE_USERNAME"
                    }
                  ]
                },
                {
                  "type": "actions",
                  "elements": [
                    {
                      "type": "button",
                      "text": {
                        "type": "plain_text",
                        "text": "View Job"
                      },
                      "url": "$CIRCLE_BUILD_URL"
                    }
                  ]
                }
              ]
            }
  notify-deploy-passed:
    steps:
      - slack/notify:
          event: pass
          custom: |
            {
              "text": "",
              "blocks": [
                {
                  "type": "header",
                  "text": {
                    "type": "plain_text",
                    "text": ":circleci-pass: Deployment Successful!",
                    "emoji": true
                  }
                },
                {
                  "type": "section",
                  "fields": [
                    {
                      "type": "mrkdwn",
                      "text": "*Repository*: $CIRCLE_PROJECT_REPONAME"
                    },
                    {
                      "type": "mrkdwn",
                      "text": "*Job*: $CIRCLE_JOB"
                    },
                    {
                      "type": "mrkdwn",
                      "text": "*Tag*: $CIRCLE_TAG"
                    }
                  ]
                },
                {
                  "type": "actions",
                  "elements": [
                    {
                      "type": "button",
                      "text": {
                        "type": "plain_text",
                        "text": "View Job"
                      },
                      "url": "$CIRCLE_BUILD_URL"
                    }
                  ]
                }
              ]
            }
```

jobsではこんな感じ

```yaml
  test:
    working_directory: ~/workspace
    steps:
      - checkout
      - attach_workspace:
          at: .
      - run:
          name: Test
          command: yarn test --runInBand
          working_directory: .
      - notify-test-passed # passしたときはこれを実行
      - notify-job-failed  # failしたときはこれを実行
```

yaml内で設定できる環境変数はこちらを参照します。
https://circleci.com/docs/ja/2.0/env-vars/#%E5%AE%9A%E7%BE%A9%E6%B8%88%E3%81%BF%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0




以上です。
拡張性はグンと増しましたが、サクッと設定できなくなってしまった？のはすこし面倒ですね。