GitHub Actionsが特定のイベントでfailした時だけSlackに通知する
ちょっと前に取り組んだのでメモしておきます。GitHub Actionsの話ばっかり書いている…
2つの実現方法
GitHub Actionsの結果をSlackに通知する方法は2つあります。
- GitHub integration for Slack: Slack側にGitHub連携を追加し、GitHubへの認証を行うことでSlackから情報を取得できるようにする
- Slack appとSlack action: GitHub Actions側でSlackへの認証をしておいて、Slack appに情報を飛ばせるようにする
ざっくりいうと視点が逆という感じなんですが、それぞれにpros/consがあります。
- GitHub integration for Slack
- メリット: 導入がめちゃくちゃ楽。Slackで
subscribe
コマンドを打つだけで成形されたメッセージを受け取れる - デメリット: Actionsの結果による制御ができない(つら)。失敗だけ通知するとか、結果に応じてチャンネルを変えるとか無理
- メリット: 導入がめちゃくちゃ楽。Slackで
- Slack app
GitHub integration for Slackを使う場合の設定
前述の通り細かい制御は不可能なので、こっちはタイトルとずれた内容になります(タイトル通りのことは後半に)。
- Slackにインテグレーションを追加する
/github subscribe <organization>/<repository> workflows:{name:"<workflow name>" event:<events> branch:"<branch>"}
を実行する- 不要な更新も追加されてしまったらunscribeする
例えば上記は
/github subscribe ihcomega56/github-actions-failure-test workflows:{name:“Integration Tests” event:“schedule”,“push” branch:“main”}
としています。これは
ihcomega56/github-actions-failure-test
リポのIntegration Tests
ワークフローが- 定期実行(
schedule
)またはmain
へのpush
により
実行された場合、結果を通知せよと言っています。
そして、上の画像のようにインテグレーションくんがissueやPRなどの更新もすべてキャッチしようとしてしまったら、要らないものは外します。ワークフローの通知以外は不要だとすると、
/github unsubscribe ihcomega56/github-actions-failure-test issues pulls commits releases deployments
を叩くと、スペース区切りで指定した機能はまとめてオフになります。
設定値の詳細はぜひ公式へ: github.com
ということで、これだけで見た目もいい感じのメッセージが受け取れるようになるのでお手軽便利です。1実行につき、ワークフローが走り始めた時・終わった時の2回通知が来ます。
ちなみにこの拡張のリポジトリはコントリビューションを受け付けておらず、機能改善したい際はお願いすることだけが許されています。通知を失敗時だけにしたいよ!というissueも既に存在するので、欲しい方はいいねしましょう!!!!!
もうひとつ補足として、(un)subscribe
はチームの誰が実行してもいいと思います。SlackとGitHubに十分な権限*1さえあれば、Aさんが登録したものをBさんが解除みたいなことも出来るため、チームリーダーやadminっぽい人に頼まなくて大丈夫なはずです。
Slack appを使う場合の設定
自分のチームでは結果に応じてチャンネルを振り分けたいということになったので設定ファイルを書きました。
github.com (↑最終的には1つ目の方法に変わったのでマージされてないけど、実際のPR)
ポイントを抜粋すると、GitHub Actionsに下記のようなステップたちを追加します。日本語のコメントはこのブログ用に解説としてつけたものです。
※インデントは左に詰めてあるのでこのままだと動きません
# トリガーたち。これらのうち、定期実行およびmainへの更新時のみ通知したい # (例えばPRのオープン時とかは要らない。通知されなくともマージするまで何度も見るので) on: schedule: # scheduled at 3PM and 3AM daily - cron: '0 3,15 * * *' pull_request: types: - opened - synchronize - reopened - ready_for_review - closed
# Send the result to Slack when a PR is merged and tests were executed regularly - name: Notify success # 成功した && 定期実行かmain更新がされた場合、下記を走らせる if: ${{ success() && contains(fromJson('["push", "schedule"]'), github.event_name) }} uses: slackapi/slack-github-action@v1.23.0 with: # 成功通知用のチャンネルIDをsecretsに追加しておく channel-id: ${{ secrets.CHANNEL_ID_FOR_MESSAGES }} # If https://github.com/slackapi/slack-github-action/issues/84 is fixed, payload.json can be shared among the following two steps (DRY). payload: | { "text": "Integration tests finished successfully.", "attachments": [{ "title": ":white_check_mark: ${{ github.workflow }} #${{ github.run_number }}", "title_link": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}", "color": "#36a64f" }] } env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - name: Notify failure # 失敗した && 定期実行かmain更新がされた場合、下記を走らせる if: ${{ failure() && contains(fromJson('["push", "schedule"]'), github.event_name) }} uses: slackapi/slack-github-action@v1.23.0 with: # 失敗通知(アラート)用のチャンネルIDをsecretsに追加しておく channel-id: ${{ secrets.CHANNEL_ID_FOR_ALERTS }} payload: | { "text": "Integration tests failed. Check the following workflow and fix it.", "attachments": [{ "title": ":x: ${{ github.workflow }} #${{ github.run_number }}", "title_link": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}", "color": "#ff0000" }] } env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
(なんかyamlの解析うまくいってなくて表示おかしいかもw)
補足すると
github.event_name
はpush
,pull_request
などイベントによる振り分けに使える。1つだけならイコール==
でいけるが、複数の場合は上記のようにfromJson
などと書く(参考: 公式docたち GitHub Actions のワークフロー構文 - GitHub Docs, 式 - GitHub Docs)- Slackにメッセージを送るのは公式のアクションを使っている
- SlackのチャンネルIDはチャットのURLから取れる。ブラウザで希望のチャンネルにアクセスすると
https://app.slack.com/client/<スペースのID>/<チャンネルのID>
ってなってるので、最後のスラッシュ以降をコピペすればOK。他にもっと良い取得方法があるのかもしれないけど - payloadでSlackのレイアウトを指定する。結構複雑なこともできるけど、今回は極めてシンプルに結果とActionsへのリンクだけ埋め込んでいる
- bot tokenをSlackのコンソールで生成する。READMEにも説明があるので、参考スクショだけ貼っておく…↓*2
ここまで設定するとこんな感じで結果が送られてきます!
画像にはないけどチャンネル振り分けもできました。
結論
Notify workflows only on errors · Issue #1563 · integrations/slack · GitHub が実装されれば面倒なことしなくてもすべて解決や・・・🙏
御礼
twitter.comマージのたび実行されるのに加えて定期実行もしてるGitHub Actionsちゃん、定期実行の方にだけ特定の後続処理入れるみたいなことできるかな…1ファイルで…
— よこな / Ayana (@ihcomega) 2022年12月7日
こちらで相談乗ってくださったよしことしろやまさんありがとうございましたー!