Alibaba CloudでCI/CD pipelineを構築するbest practice(3)_CircleCIのテスト結果をSlackに通知


https://qiita.com/dennis_wang/private/8b6ce8436c0fd9c2260a

前回の記事ではcircleciを利用してdocker imageをbuildし、alibaba cloudのACRにpushするまでやりました。
CIの結果は、CircleCIのダッシュボードから確認する必要があります。コミットの度に発火するCIの結果を、都度確認しに行くのはちょっと面倒です。
本記事では、CircleCIのテスト結果をSlackに通知する方法について解説します。

# Slack Integrationsの設定手順
ちなみに以前からCircleCIを利用されている方は、<a href="https://alibabacloud-japan.slack.com/apps/A0F7VRE7N-circleci?tab=more_info">このSlackアプリ</a>とWebhookを利用して連携を行っていたかもしれません。ですが現在では、この方法は推奨されておらず、本エントリーで紹介するOrbを使う必要があるようです。

以下にて手順を解説します。なお具体的な手順は<a href="https://github.com/CircleCI-Public/slack-orb/wiki/Setup">ドキュメント</a>にも詳しく記載されていますので、こちらも参照してください。

CircleCIからSlackへ通知を送るための手順：
1. Slackワークスペースにアプリをインストールし、OAuthトークンを発行する
1. 発行されたトークンをCircleCIのコンテキストに登録する
1. CircleCIのワークフロー内に通知処理を実装する

# 1. Slackワークスペースにアプリをインストールし、OAuthトークンを発行する
- まずSlackの<a href="https://api.slack.com/apps">Your Apps</a>を開き、`Create an App`をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/846604da-d86d-748a-2b42-c7f42241f4d9.png)

- 今回はゼロからスクラッチするので、`From scratch`を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/72fee283-2528-ee7a-f778-6f708afdfd73.png)
- アプリの名前と、インストールするワークスペースを決めます。ここでは名前を`CircleCI-notification`にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/d46f990b-faa1-77d4-cbfa-587b279ed190.png)
- アプリの設定画面に遷移しますので、左ペインからOAuth & Permissionsをクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/668a489b-3a79-c767-5fb8-c6a038b883b9.png)
- 画面を下へスクロールさせると、Scopesという項目の中にBot Token Scopesという項目があります。Add an OAuth Scopeをクリックして、アプリに必要な権限をつけましょう。CircleCIからの通知に必要な権限はchat:write、files:write、chat:write.publicの3つです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/6361f14d-ad50-68a8-ab83-b5a5aa10e07b.png)
- 左ペインの`Install App`をクリックしてから、`Install to Workspace`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/faabab7a-1a56-731c-411b-33b551c873e1.png)

- インストールの確認画面が表示されます。インストール先と権限を確認したら、許可するをクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/e31a6ffc-3924-f672-2d15-80beeea95497.png)
- インストールが完了すると、OAuthトークンが表示されます。この文字列を控えておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/e1635500-cecb-fdfb-4ba3-4b76b5832de3.png)

- slack channel作成(既存のチャンネルを使いたい場合はこのステップをスキップしてください。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/fff378f1-854b-025b-899e-4a777088a8b6.png)

- slack channelに上記作られたアプリを追加(これは非常に大事です。やらないと通知がslack channelに送られない。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/014d919c-83fd-c60c-c9ca-b5f339cb16d0.png)

# 2. 発行されたトークンをCircleCIのコンテキストに登録する
続いてCircleCIのワークフロー内から、先ほど発行されたトークンを利用できるようにします。これには<a href="https://circleci.com/docs/ja/contexts/">コンテキスト</a>と呼ばれる仕組みを利用するのが一般的です。
コンテキストは組織内の各プロジェクトで、環境変数を安全に共有できる仕組みです。
コンテキストはSlackのトークンだけでなく、AWSのアクセスキーやk8sのクレデンシャルなど、様々な機密情報を安全に保管するために利用できます。
またコンテキストへのアクセスは、GitHubのOrganization内に設けたTeamsごとに制限することができます。デフォルトでコンテキストは全員が読み取ることが可能なため、他プロジェクトのメンバーに見えてはならない情報は、アクセス制限をかけることも検討してください。


- CircleCIにログインし、`Organization Settings`→`Contexts`を開いて`Create Context`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/7a8fbaff-ab1f-48ad-e8fe-391f4ff395fd.png)
- コンテキストの名前を決めましょう。ここでは`slack_oauth_token`としました。`Create Context`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/2f8606cf-2e21-d3bd-a257-021b76433738.png)
- 先ほどのコンテキスト一覧画面に、作成したslack_oauth_tokenコンテキストが表示されますので、コンテキスト名をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/c7d189ca-3c96-5a43-e474-0754dcd1cfaa.png)
- 環境変数の登録画面に遷移します。Add Environment Variableをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/d51973c3-1df7-7e06-b965-eb2b23154611.png)
- `SLACK_ACCESS_TOKEN`と`SLACK_DEFAULT_CHANNEL`という名前の環境変数を作成
    - SLACK_ACCESS_TOKEN : 先ほど発行されたトークンを入力
    - SLACK_DEFAULT_CHANNEL：デフォルトで通知を行うチャンネルIDを入力
    :::note info
    SLACK_DEFAULT_CHANNELは表示上のチャンネル名ではなく、チャンネルIDであることに注意してください。
    Slackのデスクトップアプリを利用しているなら、該当のチャンネル名を右クリックしてリンクをコピーし、得られるURLの末尾にある文字列がチャンネルIDです）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/61f8595a-8591-fa98-5033-8a1b59eb1ba6.png)

# 3. CircleCIのワークフロー内に通知処理を実装する
CircleCI Orbは, パッケージ化されたビルドコマンド/パイプラインです。
プログラミング言語に例えるなら、外部ライブラリをインポートして関数を使えるようにする機能に該当します。Orbを使えば様々なジョブやコマンドを再利用できます。
本来であれば何行にも渡って記述していた処理を, ほんの数行で管理することができます.
AWS連携やSlack連携など, 需要が高いジョブは幸いCircleCI公式経由でリリースされています。

https://circleci.com/ja/orbs/

また今回のSlack通知のような、一般的な機能は公式にOrb化され公開されているため、自分で実装する必要がありません。
ここではOrbを利用することで、Slackに通知を行うslack/notifyというコマンドを利用可能にしています。

- 上記の<a href="https://circleci.com/developer/orbs">Orbs Registry</a>にアクセスし、slackを検索してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/4f8817a4-2e92-fc3c-4e5f-b67b8f15da5f.png)
- 以下のページを参考にして、circleci上でconfig.ymlを編集

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/7c29f269-0266-8a75-c77a-6914397d0937.png)

1. slackのorbをtopレベルに追加
    ```
    orbs:
      slack: circleci/slack@4.12.0
    ```
2. 以下を既存の`step`に追加
    ```
    - slack/notify:
        event: pass
        template: basic_success_1
    ```
3. context追加
ワークフロー内では、Slackのトークンを読み込むため、コンテキストにアクセスする設定を行っています。context: コンテキスト名を指定しておけば、該当ジョブ内では環境変数にコンテキストの内容が自動的に読み込まれます。なおワークフロー内に複数のジョブがある場合、それぞれのジョブは独立したコンテナ内で実行されるため、コンテキストを利用する必要があるすべてのジョブそれぞれに、contextの記述を追加する必要がある点に気をつけてください。
    ```
    workflows:
      say-hello-workflow:
        jobs:
          - build-docker-image:
              context:
                - acr
                - slack_oauth_token
    ```

# 4. 通知確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/a0250572-b744-c17f-a611-e5f11e867935.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28664/e6ab11a5-5965-ee1a-03e9-94e0fc649b49.png)
このように、ワークフローの結果がSlackに通知できるようになりました。