【GitHub Actions】GitHub DiscussionsをSlackで通知する

こんにちは、HRBrainのPlatformチームのほしいです。
弊社では開発者の相談・雑談をする場として、GitHub Discussionsを利用しています。 この機能を使い始めた当初、GitHub Discussionsからの通知を受け取る方法がなく、話題に気付けない人が結構いました。
みんなが頻繁に見るSlackに通知が来れば、GitHub Discussionsでの議論も活発になるのではないかと思い、Slackで通知させる方法を考えました。

公式の通知はまだ?

現状、SlackのGitHub連携ではGitHub Discussionsの機能がリリースされておらず、こちらを利用することはできません。

GitHub Actionsを使って通知できるようにする

SlackのGitHub連携に先立って、GitHub Actionsの機能がリリースされていたため、今回はGitHub Actionsを利用して通知を送ることにしました。 GitHub ActionsからSlackに通知を送るには、rtCamp/action-slack-notifyのようなアクションを使うと便利そうなのですが、今回はリンクやプレビュー表示なども付けたかったので、curlを使います。

name: Discussions Notification
on:
  discussion:
    types: [created]
  discussion_comment:
    types: [created]
jobs:
  discussion_created:
    runs-on: ubuntu-20.04
    if: ${{ github.event.discussion && !github.event.comment }}
    steps:
      - name: Send GitHub Discussion Notification to Slack
        # Note: 
        # - 一度変数に入れることで、$や`をエスケープしている
        # - https://stackoverflow.com/questions/69982822/is-there-a-way-to-escape-and-single-quotes-together-in-bash
        # - printfしないといい感じに"\n"が変換されない
        run: |
          title=$(
          cat <<"EOF"
          ${{ env.DISCUSSION_TITLE }}
          EOF
          )
          body=$(
          cat <<"EOF"
          ${{ env.DISCUSSION_BODY }}
          EOF
          )
          printf -v markdown_message_unescaped %b "<${{ env.DISCUSSION_URL }}|*$title*>\n$body"
          jq -n -r --arg text "$markdown_message_unescaped" '{"token":"${{ secrets.SLACK_BOT_TOKEN }}","channel":"${{ env.CHANNEL_ID }}","blocks":[{"type":"section","text":{"type":"mrkdwn","text":"New Discussion by <${{ env.USER_URL }}|${{ env.USER_NAME }}>"}}],"attachments":[{"blocks":[{"type":"section","text":{"type":"mrkdwn","text":$text}}]}]}'|curl -X POST -H 'Authorization: Bearer ${{ secrets.SLACK_BOT_TOKEN }}' -H "Content-Type: application/json" -d @- https://slack.com/api/chat.postMessage
        env:
          CHANNEL_ID: <slackのチャンネルID>
          DISCUSSION_URL: ${{ github.event.discussion.html_url }}
          DISCUSSION_TITLE: ${{ github.event.discussion.title }}
          DISCUSSION_BODY: ${{ github.event.discussion.body }}
          USER_URL: ${{ github.event.discussion.user.html_url }}
          USER_NAME: ${{ github.event.discussion.user.login }}

  discussion_commented:
    runs-on: ubuntu-20.04
    if: github.event.comment
    steps:
      - name: Send GitHub Discussions Comments to Slack
        run: |
          title=$(cat << "EOF"
          ${{ env.DISCUSSION_TITLE }}
          EOF
          )
          body=$(cat << "EOF"
          ${{ env.COMMENT_BODY }}
          EOF
          )
          printf -v markdown_message_unescaped %b "*<${{ env.COMMENT_URL }}|Comment on $title>*\n$body"
          jq -n -r --arg text "$markdown_message_unescaped" '{"token":"${{ secrets.SLACK_BOT_TOKEN }}","channel":"${{ env.CHANNEL_ID }}","blocks":[{"type":"section","text":{"type":"mrkdwn","text":"New comment by <${{ env.USER_URL }}|${{ env.USER_NAME }}>"}}],"attachments":[{"blocks":[{"type":"section","text":{"type":"mrkdwn","text":$text}}]}]}'|curl -X POST -H 'Authorization: Bearer ${{ secrets.SLACK_BOT_TOKEN }}' -H "Content-Type: application/json" -d @- https://slack.com/api/chat.postMessage
        env:
          CHANNEL_ID: <slackのチャンネルID>
          DISCUSSION_TITLE: ${{ github.event.discussion.title }}
          COMMENT_URL: ${{ github.event.comment.html_url }}
          COMMENT_BODY: ${{ github.event.comment.body }}
          USER_URL: ${{ github.event.comment.user.html_url }}
          USER_NAME: ${{ github.event.comment.user.login }}

SLACK_BOT_TOKENはリポジトリのシークレットに登録してください。

こんな感じでSlackに通知することができます。

f:id:hrb-hoshii-natsuki:20211115122617p:plain
slack通知のイメージ画像

やってみてどうだったか

Slackに通知が来て、GitHub Discussionsの投稿やコメントに気付けるようになったので、ツールの選定など開発者の議論やトラブルシューティングのナレッジがたまる場所としてGitHub Discussionsを使う人が増えました。

難しかったこと

${{ github.event.discussion.body }}等に$'がそのまま入ってくるのが厄介で、結構苦戦しました。
bashのいい勉強になりました。