GithubActionsでワークフローの結果をSlack通知する方法

## 概要
- ソースコードの変更をトリガーにGithub ActionsでAWS Lambdaへの自動デプロイを行うフローを構築した。
- デプロイの結果をActionsの画面で見るのは面倒なので、ジョブの結果を通知するGithbu Actionsを構築したので記録として残しておく
- 今回の最終的な構成は下キャプチャのような構成となる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531653/d3374d0a-8a32-16b7-832d-25a721c6f44a.png)


## 対象
- Github ActionsでSlack通知を実現したい方
- 依存関係のあるJobがあり、同Jobの結果をもとに通知の内容を変更したいと思っている方


## 手順

#### Slack通知用のIncoming webhookを取得する
- 通知する先のチャンネルを用意する
- 用意したらチャンネルの右上（キャプチャ赤枠）のアイコンを押下する
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531653/c87976f0-9afe-1ab9-a395-806077442599.png)
- 「インテグレーション」のタブを押して「アプリを追加する」を押下する
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531653/9ffb6806-5bbf-a302-74a4-49e7c9fe8690.png)
- 「Incoming WebHooks」と入力して、キャプチャの赤枠をクリックする
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531653/85fa62e4-c73f-718a-7777-d1f764443267.png)
 - 「Slackに追加する」を押下する
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531653/2b1b5b11-a9dc-a9a7-393a-32dc678371ad.png)
- 該当のチャンネルを選択(クリックしても反応しないので、↓矢印を押すとチャンネルが出てくる)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531653/043293e7-32cf-2c8e-0587-dcac76c830ed.png)
- 追加するをクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531653/df464758-0784-cba8-3530-791ed45f1209.png)
- Webhook URLを控えておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531653/eb06126d-16c5-78c6-137e-cfec9d435593.png)


- チャンネルに追加されたことを確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531653/16afeb35-098f-1979-400a-94c1c99fad18.png)


#### 通知するためのGithub Actionsを記述する
- GitHub Actions Library にある `Slack Notify` を使用する
  - https://github.com/marketplace/actions/slack-notify
- 本記事では、`Slack Notify`を使用したslack_notify.ymlというファイルを作成し、モジュールとして呼び出す形で使用している(デプロイだけでなく、他の用途でもSlack通知のニーズがありそうなので、モジュールとして切り出し汎用的に使用できるようにする意図)
- ポイント
  - [needsコンテキスト](https://docs.github.com/ja/actions/learn-github-actions/contexts#needs-context )を使用して、Jobの依存関係を作る
  - `[jobs.<job_id>.if]`で依存関係のJobの結果次第で後続の処理の実行を判定している
    - ifを使用できるコンテキストの種類：github, needs, vars, inputs
    - 実行可能な関数：always, cancelled, success, failure
    - https://docs.github.com/ja/actions/learn-github-actions/contexts#context-availability

```yaml depoy_to_development.yml
name: Deploy to Development

on:
  push:
    branches:
      - main
    paths:
      - ".github/workflows/**"
      - "app/**"

permissions:
  id-token: write
  contents: read

jobs:
  # 何かしらの依存関係のあるjob
  deploy_api:
    uses: ./.github/workflows/xxxx.yml
    with:
      xxxx:xxxx
      xxxx:xxxx
    secrets: inherit

  # Slack通知処理を呼び出す
  slack_notification:
    # deploy_apiの後に実行されるようにする
    needs: deploy_api
    # deploy_apiが成功していても失敗していても実行されるようにする
    if: ${{ always() }}
    uses: ./.github/workflows/slack_notify.yml
    with:
      slack_channel: info-gha
      # needs.<job_id>.resultで前のジョブの結果を参照できる(success、failure、cancelled、および skipped)
      slack_color: ${{ needs.deploy_api.result == 'success' && 'good' || 'danger' }}
      slack_username: GitHub Actions Results
      slack_icon: https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png
      slack_title: Deployment to Development dev-qrcode-generator-lambda
      slack_message: ${{ needs.deploy_api.result == 'success' && ':white_check_mark:Deployment successful' || ':x:Deployment failed' }}
    secrets: inherit

```

- ポイント
  -  `SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}`で取得したSlackのIncoming WebHook URLを指定している
  -  URLはGithub リポジトリの`secrets`に格納している
    -  `secrets`についてわからない方はこちらの方の[記事](https://qiita.com/mkin/items/75a4928a1fafe5eacd17#%E3%82%B7%E3%83%BC%E3%82%AF%E3%83%AC%E3%83%83%E3%83%88%E6%83%85%E5%A0%B1%E3%81%AE%E8%A8%AD%E5%AE%9A)にわかりやすく記載されているため、参照をお願いします。
  - 各変数の設定は、`Slack Notify`の公式ページに詳しく載っています(キャプチャは公式ページから引用)
  　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531653/ed196a35-a7b2-6a93-f442-c5438942a71a.png)


```yml slack_notify.yml
name: Slack Notification

on:
  workflow_call:
    inputs:
      slack_channel:
        description: "The Slack channel to send the notification to"
        required: true
        type: string
      slack_color:
        description: "The color to display in Slack"
        required: true
        type: string
      slack_username:
        description: "The username to display in Slack"
        required: true
        type: string
      slack_icon:
        description: "The icon to display in Slack"
        required: true
        type: string
      slack_title:
        description: "The title to display in Slack"
        required: true
        type: string
      slack_message:
        description: "The message to send to Slack"
        required: true
        type: string

jobs:
  slackNotification:
    name: Slack Notification
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Slack Notification
        uses: rtCamp/action-slack-notify@v2
        env:
          SLACK_CHANNEL: ${{ inputs.slack_channel }}
          SLACK_COLOR: ${{ inputs.slack_color }}
          SLACK_USERNAME: ${{ inputs.slack_username }}
          SLACK_ICON: ${{ inputs.slack_icon }}
          SLACK_TITLE: ${{ inputs.slack_title }}
          SLACK_MESSAGE: ${{ inputs.slack_message }}
          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
```

## 実行
- `needs`を設定すると、Job間で線が結ばれ、順次実行される形となる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531653/94d5c148-7d26-eea7-8eb2-c02fbe590d63.png)

- Slack 通知
     - 実行者のGithubアカウントや実行されたワークフローのURL、トリガー対象のCommitのURLを自動で転記してくれるので便利
    - 依存関係のJob成功パターン
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531653/b5be9c3f-f455-e17e-e29a-8dc06c4ed311.png)
    
    - 依存関係のJob失敗パターン
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531653/7fbdacb4-33d3-3e42-5560-aea0149c707c.png)

## まとめ
- ライブラリを使って簡単に作成できた
- ニーズに応じて色々拡張できそうだと思った
- 今回指定したライブラリのオプション以外にもさまざまなオプションを指定できるので、時間ができたら試そうと思った
- 今回作成したコード
  - https://github.com/Kyohei-takiyama/qrcode-generate-api/tree/main/.github/workflows