GitHub Actions で失敗したテストをコメントで通知する Action の作成

こんにちは。 Web Engineer の a2ikm です。 先日、 GitHub Actions で失敗したテストをコメントで通知をしてくれる quipper/comment-failure-action という Action を作成し、公開しました。 今回はこの Action を作成するに至った経緯と使い方、そして Action 作成に関する Tips を紹介します。

なぜこの Action を作ったのか

スタディサプリは生徒向けサービス、教師向けサービスなどの複数のサービスから構成されていて、それらはひとつのリポジトリに集約して管理されています。 いわゆる monorepo というパターンで、リポジトリ名もそのまま monorepo です。

この monorepo に差分が push されると、 CircleCI と GitHub Actions でサービスごとのテストとデプロイが行われるようになっています。 もともとは CircleCI だけで構築していたのですが、依存性の記述やスケジュール実行などの設定の柔軟さから、サービスのテストを GitHub Actions に移行しつつあるというのが現状です。

この GitHub Actions を導入する過程で発生したのが、どのテストが失敗したのかひと目でわかりにくいという問題です。 多数のサービスが monorepo に集約されていること、また GitHub Actions では並列実行している単位で Check が表示されることから、 monorepo に Pull Request を作ると CircleCI も含めて百数十個の Check が表示されます。 そして、 CircleCI のみを利用していた頃には失敗した Check が上位に優先されて表示されていたのですが、 GitHub Actions ではそのような制御がなく、成功したものと失敗したものとが混在して表示されます。 結果として、下図のように、百数十個の Check をスクロールしてどこで失敗したか探すということを頻繁にやっていました。

この手間をなくすために、GitHub Actions でテストが失敗した Check の一覧を Pull Request にコメントする Action として、 comment-failure-action を作成しました。

使い方

comment-failure-action では workflow_run イベントでの起動を想定しています。 これは workflow の終了時に発生するイベントで、これを使うと、テストを実行する workflow が終了したタイミングで comment-failure-action 用の workflow を追加で起動するようなことができます。

実際の workflow の設定としては下記のようになります。 この on.workflow_run.workflows にテストを実行している workflow 名を列挙します。 ここでは例として test-1test-2 のふたつを対象としていますので、 test-1test-2 のそれぞれが終了したタイミングでこの workflow が起動することになります。

on:
  workflow_run:
    workflows:
      - test-1
      - test-2
    types: [ completed ]

jobs:
  comment-failure:
    runs-on: ubuntu-latest
    steps:
      - uses: quipper/comment-failure-action@v0.1.1

注意点として、 workflow_run を利用した workflow は、 main などの GitHub 上で設定しているデフォルトブランチ上の定義に基づいて実行されます。 つまり、 Pull Request を通して comment-failure-action を使った workflow を追加した際には、その Pull Request に対して comment-failure-action は起動しません。

実際にテストが失敗すると、下図のようにその workflow 名と、その workflow のなかで失敗した Check の一覧を列挙したコメントを作成します。 コメントはコミットハッシュごとに作成されて、同一のコミットハッシュに対して複数回 comment-failure-action が起動した場合には、そのコメントに逐次追記していきます。 テストが成功したときにはコメントしません。 一度テストが失敗し、その後 re-run によって成功した場合には、最初に作成したコメントを失敗しているテストがない旨のメッセージで上書きします。

Action を自作するときに便利な Tips

今回 Action を作成し、公開するまでの過程で便利だった Tips をいくつか紹介します。

typescript-action

これは TypeScript を使って Action を作成する際のテンプレートとなるリポジトリです。 Action を作成する方法としては、 Docker イメージを使って任意の言語で実装する Docker container action と、 Node.js を使って実装する JavaScript action 、そして既存の Action を組み合わせる Composite Run Steps action の3通りがあって、 comment-failure-action では JavaScript action を採用しています。 その実装言語として TypeScript を採用するにあたってこのテンプレートを利用しました。

この中には

  • action.yml のテンプレート
  • 単一の .js ファイルを生成するのに必要な npm-scripts の定義
  • Jest や ESLint 、 Prettier などの開発環境
  • 加えて、 @actions/core@actions/github など Action に必要になりそうなパッケージ

が用意されていて、 Action を作成するにあたって最初の手間を大きく減らしてくれました。

私はこれを使うまで @vercel/ncc で単一の .js ファイルにコンパイルできるということを知らなかったので、スタンダードなやり方に簡単に乗れるという意味でも役に立つリポジトリだと思いました。

利用方法としては、 README にあるように "Use this template" からリポジトリを自動的に作成するのが一番簡単です。 手動で git clone したのち .git を削除してからリポジトリを初期化することもできます。 なお MIT ライセンスのもとで配布されているので、公開の際にはオリジナルの著作権表記と権限表記を変更せずに同梱する必要がある点に注意してください。

GITHUB_TOKEN

今回 comment-failure-action では、 GitHub Actions の実行結果などを知るために GitHub API を利用しています。 API を利用するには、通常なら事前に発行したパーソナルアクセストークンが必要なのですが、今回のようなケースでは GITHUB_TOKEN で事足りました。

権限など詳しい情報はドキュメントを参照していただきたいのですが、GITHUB_TOKEN は

  • 毎回の workflow の実行ごとに自動的に生成・破棄される
  • workflow の定義されているリポジトリに関する API 呼び出しにのみ利用できる

という性質を持ったトークンです。

GitHub Actions では万が一ログに Secrets が出力されても自動でマスクされるので、パーソナルアクセストークンを利用したとしても漏洩の可能性は低いのですが、 GITHUB_TOKEN は自前での発行が不要ということもあり、手軽かつ安全に GitHub Actions を利用するうえではとても便利です。

この GITHUB_TOKEN は、 actions.yml 上では ${{ github.token }} として、また workflow の定義上では ${{ github.token }}${{ secrets.GITHUB_TOKEN }} として参照することができます。 comment-failure-action では前者の記法を使って actions.yml にトークンのデフォルト値として設定しているので、利用者側でのトークンの設定が不要となっています。

最後に

本記事では、 GitHub Actions の導入によって発生した「どのテストが失敗したか見分けづらい」という問題を解決するために作成した quipper/comment-failure-action という Action を紹介しました。 こちらは OSS として公開しているので実際に利用していただくことができます。 もし不具合などありましたら Issue / Pull Request などを通して報告していただけるとありがたいです。