電気ひつじ牧場

技術メモ

CircleCIのfailをSlackにメンション付きで通知する

初めに

CIがコケたらSlackに通知するというのは一般的なユースケースだと思います。 特に、失敗したビルドを実行したユーザにだけメンションが飛ばせると便利ですね。 ここでは会社のメールアドレス = Slackの登録メールアドレス = CircleCIの登録メールアドレスのようなよくある環境を想定します(CircleCIのEnterprise版を使っている場合)。

実装

CircleCIとSlackの連携方法ですが複数の方法があります。

Slackが開発しているCircleCI app

https://slack.com/apps/A0F7VRE7N-circleci?tab=more_info

こちらはSlack公式のappになります。インストールして設定するだけですぐに使えるものです。 手軽ですがメンションを飛ばすことはできません

CircleCIのslack orb

https://circleci.com/developer/orbs/orb/circleci/slack

こちらはCircleCIの公式orbです。自作のSlack Appを作成してwebhookで呼び出す必要がありますが、メンションを付与できます。 今回はこれを使います

手順

(1) Your Appsページに飛び、Create Appから適当な名前でAppを作ります

https://api.slack.com/apps

(2) OAuth & Permissions > Scopesで必要なスコープをつけます

必要なスコープは以下の通りです

  • chat:write
  • chat:write.public
  • incoming-webhook
  • users:read
  • users:read.email

アプリをSlackワークスペースに対して認証してSLACK_ACCESS_TOKENを入手します。

(3) CircleCIのコマンド作成

先ほどのSLACK_ACCESS_TOKENはProject VariablesやOrganizationのContextにセットしておき、ワークフロー中でロードされるようにしておきます。

CCIでコマンドを作ります。

commands:
    notify-slack-when-fail:
        steps:
            - run:
                command: |
                    slack_user_id=$(curl -s -H "Authorization: Bearer $SLACK_ACCESS_TOKEN" "https://slack.com/api/users.lookupByEmail?email=$CIRCLE_USERNAME@example.com" | jq -r '.user.id')
                    echo "export SLACK_PARAM_MENTIONS='<@$slack_user_id>'" >> $BASH_ENV 
                when: on_fail
            - slack/notify:
                event: fail
                channel: your_channel
                template: basic_fail_1

Slackの仕様上、APIからメンションに使えるのはSlackユーザIDという文字列です。普段Slack中でメンションを当てる時に使う@electrical-sheepのような名前は使えないので、API経由でクエリする必要があります

あとはこのコマンドをjob stepsの最後で使えば完了

steps:
    - checkout
    - run:
        command: ./terraform.sh 
    - notify-slack-when-fail