reviewdog で構文チェックや静的解析の結果をプルリクのレビューコメントとして出力する

こちらのブログは個人ブログと同じ内容です

www.ritolab.com


プルリクエストを作成した時に構文チェックや静的解析を走らせてソースコードのチェックを行っていた際に、検査に通らなかった場合は結果エラーと表示・通知されますが、その度に GithubActions / CircleCI / TravisCI などの結果画面へ遷移して検査に通らなかった箇所を確認するのって少しだけ面倒だったりします。

そんな時は、reviewdog を使って、検査結果をプルリクのレビューコメントに出力してあげると手間も減って少しだけ幸せになれます。

今回は、reviewdog で構文チェックや静的解析の結果をプルリクのレビューコメントとして出力してみます。

reviewdog

reviewdog は、レビューコメントを出力してくれるツールです。
https://github.com/reviewdog/reviewdog

検証環境

今回使用するツールは以下の通りです

  • reviewdog
  • Github Actions
  • PHP_CodeSniffer(構文チェック)
  • PHPStan(静的解析)

今回は Github Actions に reviewdog を導入して、プルリクエストで構文チェックと静的解析を走らせ、検査に通らないものがあった場合にその結果をレビューコメントとして出力したいと思います。

一部 PHP フレームワーク Laravel のセットアップが出てきますが、特に Laravel のコードは出てきません。プロジェクトルートで各検査を実行している事を明示するために残しているだけなので、他の FW やスクラッチでも設定としては問題ありません。

構文チェックのエラーをコメントに出力する

まずは、PHP_CodeSniffer にて構文チェックを行い、エラーがあればプルリクのコメントに出力するようにします。

reviewdog なしで通常の構文チェックを走らせる場合の Action は以下になっています。(以下すべて yml は該当部分のみ抜粋して表示しています)

.github/workflows/ci.yml

jobs:
  # 構文チェック
  lint:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: rito328/composite-run-steps-action-laravel-setup@v1 # Laravel setup
    - name: lint
      run: ./vendor/bin/phpcs --report=emacs --standard=phpcs.xml ./

(Laravel setup のところは、個人的に Laravel のセットアップをまとめている Composite Action なので、試す場合は削除して各々の定義を追加してください)

ここに reviewdog を導入してレビューコメントを出力するようにするので、以下のように変更します。

.github/workflows/ci.yml

jobs:
  # 構文チェック
  lint:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: rito328/composite-run-steps-action-laravel-setup@v1
    # 1. reviewdog の setup action を追加
    - uses: reviewdog/action-setup@v1
      with:
        reviewdog_version: latest
    - name: lint
      env:
        # 2. reviewdog が コメントを書き込めるように token をセットする
        REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      # 3. 構文チェックの結果を reviewdog へ渡す
      run: ./vendor/bin/phpcs --report=emacs --standard=phpcs.xml ./ | reviewdog -reporter=github-pr-review -efm='%f:%l:%c:%m'
  1. reviewdog の setup action を追加して reviewdog を導入しています
  2. reviewdog が コメントを書き込めるように GITHUB_TOKEN をセットしています
  3. 構文チェックの結果を reviewdog へ渡しています

ポイントとしては、コメントを書き込める用に環境変数 REVIEWDOG_GITHUB_API_TOKEN に GITHUB_TOKEN 渡してあげることがまず一つです。ただ結果を渡すだけでは、書き込みの権限がなくて失敗してしまいます。

2つ目は、lint 結果のフォーマットです。

通常のエラーレポートの出力フォーマットでは reviewdog 側で簡単に読み取ることができないので、--report=emacs を指定して、出力フォーマットを通常のものから変更しています。

その上で、コメントのフォーマットを reviewdog 側で指定しています。(-efm='%f:%l:%c:%m')

Reporting
https://github.com/squizlabs/PHP_CodeSniffer/wiki/Reporting

これで、構文チェックに引っかかったものが、プルリクのレビューコメントに出力されるようになります。

f:id:ro9rito:20200902095337p:plain

静的解析のエラーをコメントに出力する

次は、PHPStan にて静的解析を行い、エラーがあればプルリクのコメントに出力するようにします。

まず、reviewdog なしで通常の構文チェックを走らせる場合の Action は以下になっています。

.github/workflows/ci.yml

jobs:
  analyse:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: rito328/composite-run-steps-action-laravel-setup@v1
    - name: analyse
      run: ./vendor/bin/phpstan analyse

各々セットアップして、PHPStan を実行しているだけの、ベーシックな定義です。

これに、reviewdog を導入するために以下の記述に変更します。

.github/workflows/ci.yml

jobs:
  # 静的解析
  analyse:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: rito328/composite-run-steps-action-laravel-setup@v1
    # 1. reviewdog の setup action を追加
    - uses: reviewdog/action-setup@v1
      with:
        reviewdog_version: latest
    - name: analyse
      env:
        # 2. reviewdog が コメントを書き込めるように token をセットする
        REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      # 3. 静的解析の結果を reviewdog へ渡す
      run: ./vendor/bin/phpstan analyse --error-format=raw --no-progress | reviewdog -reporter=github-pr-review -f=phpstan

基本的な部分は構文チェックの時と変わりませんが、一つだけポイントがあります。

run: ./vendor/bin/phpstan analyse --error-format=raw --no-progress | reviewdog -reporter=github-pr-review -f=phpstan

reviewdog は PHPStan 用のメッセージフォーマットを既に持っているので、-f=phpstan とするだけで済むのですが、今回の書き方の場合、PHPStan 側のエラー出力がデフォルトでは読み取れないので、--error-format=raw を指定してエラーの出力フォーマットを変更してあげる必要があります。

PHPStan - Output Format
https://phpstan.org/user-guide/output-format

これで、静的解析に引っかかったものが、プルリクのレビューコメントに出力されるようになります。

f:id:ro9rito:20200902102925p:plain

補足

PHP_CodeSniffer と PHPStan のエラー出力のフォーマットをデフォルトから変更しましたが、基本的デフォルトでは検査結果は人が確認しやすいような書式で出力されるので、シンプルな出力に変更する事で reviewdog から読み取れるようにしています。

ただ、reviewdog 自体は checkstyle を読めるので、今回のように出力フォーマットを変更しなくても設定次第でいけるのかもというのは一応補足しておきます。(検証はしていません)

(とはいいつつ、-f=phpstan で使う場合、PHPStan の場合は raw フォーマット前提のようです)
https://github.com/reviewdog/errorformat/pull/22/files

まとめ

reviewdog を導入するとそのプルリクを出した際の検査結果がコメントが書き込まれるので、おそらく最も早くレビューのコメントがつく。という事を考えると、人が実際にレビューを行う前に基本的な部分が自動で指摘されるので、全体的なレビュー労力の削減にもなりそうですね。

本当はこういった類のものはプルリク出す前に全て潰してしまえたら最良ですが、漏れる時もありますし、reviewdog にかわいく(コメントに犬のアイコンが出てきます)指摘してもらうのも良いかもしれません。