あるGitHubリポジトリのmaster(や最近はmain)ブランチで確率的に落ちるテストは間違いなく不安定なテスト*1であるという考えのもと、不安定なテストを見つけたときに自動でSlackに通知するGitHub Actionsワークフローの書きかたについて説明する*2。
なお、この記事ではテスト自体の書きかたの良し悪しについては言及しない。
方法
- 不安定なテストを通知するジョブは、テストを実行するジョブの実行結果に依存する
- 現在のブランチがmaster、かつテストの終了ステータスが正常でないとき通知する
- 今回はテストが1件でも失敗したなら、テストのコマンドは終了ステータスとして1を返すとする
これをYAMLに落とし込むとこうなる*3。
test: # リポジトリのテストを実行 flaky-test-notification: needs: - test runs-on: ubuntu-latest if: always() steps: - name: Notify flaky tests if: github.ref == 'refs/heads/master' && needs.test.result == 'failure' uses: tokorom/action-slack-incoming-webhook@main env: INCOMING_WEBHOOK_URL: {{ secrets.WEBHOOK_URL }} with: text: 'Flaky tests found: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}'
まず、test
ジョブの結果に依存するのでneeds
にtest
を指定する。しかし、needs
に指定したtest
ジョブはテストに失敗したとき終了ステータスが1なので失敗とみなされる。このときneeds
を持つジョブはデフォルトでスキップされてしまう*4。この場合もflaky-test-notification
は実行したいので、ステップ自体はつねに実行されるようにif: always()
を指定する。
通知用のステップで現在mainブランチかつテストが失敗しているか(すなわち不安定なテストが見つかったか)をgithub.ref
とneeds.test.result
で判定する。判定がtrueならSlackへ通知する。GitHubフローで開発しているなら、masterブランチへはpull requestのマージでコミットが追加されるはずであり、それはpushと見なされるので、flaky-test-notification
はpull requestマージ時に1回だけ実行される。
Slackへ通知する既存のActionはいくつか存在するので何かを使えばいいが、ここではtokorom/action-slack-incoming-webhookを使わせていただく。といっても、リポジトリのActions用シークレット*5にSlackのIncoming Webhook URLを登録しておき、送信するテキストを設定すれば終わり。ここではgithub.repository
とgithub.run_id
からGitHub Actionsの実行画面のURLを作成して、Slackからすぐに結果を確認しに行けるようにしている。
不安定なテストが見つかると次のようにSlackに通知が来る。
このあとは粛々とテストを直しましょう。
*1:flaky testsともいう https://docs.gitlab.com/ee/development/testing_guide/flaky_tests.html
*2:業務で必要に駆られて作成しチームメンバーにレビューしてもらった
*3:本当はGitHub Enterprise Serverで作ったものをgithub.com風に書き換えた
*4:"If a job fails, all jobs that need it are skipped unless the jobs use a conditional expression that causes the job to continue"
*5:リポジトリ配下の/settings/secrets/actionsから設定できる