PHPStan + PHP_CodeSniffer + reviewdog + GitHub Actionsを導入する

PHPStan+PHP_CodeSniffer+reviewdog+GitHub Actionsを導入する Laravel
記事内に広告が含まれています。

この記事では、GitHubでPR(プルリクエスト)を作成した時に、静的解析と構文チェックを自動実行して、エラー内容をレビューコメントとして吐き出す方法について紹介しています!

PHPStan + PHP_CodeSniffer + reviewdog + GitHub Actionsを導入する

今回使用するライブラリ・ツールの説明

今回使用するライブラリ・ツールは下記になります。

  • PHPStan:静的解析用ライブラリ
  • ide_helper:IDE補完用のヘルパーファイルを生成してくれるライブラリ
  • PHP_CodeSniffer:構文チェック等を行ってくれるライブラリ
  • reviewdog:ソースコードレビューを行ってくれるライブラリ
  • GitHub Actions:pushやPR作成などのイベントをトリガーに、対応するアクションを組み合わせてワークフローの自動化を行うことができる

Laravel環境では、Laravel用のPHPStanとしてlarastanもあるのですが、対応しているバージョンが割と高いので、この記事では、汎用的に使えるPHPStanを用いた紹介をします。

リポジトリ:nunomaduro/larastan

PHPStanを導入する

phpstan/phpstanをinstallする

composer経由で、phpstanをinstallします。

$ composer require --dev phpstan/phpstan

リポジトリ:phpstan/phpstan

メモリが足りない場合は、COMPOSER_MEMORY_LIMITをつけて実行してあげます。

$ COMPOSER_MEMORY_LIMIT=-1 composer require --dev phpstan/phpstan

phpstanのバージョンに関しては、以下のコマンドで確認することができます!

$ ./vendor/bin/phpstan -V

PHPStanの設定ファイルを作成する

PHPStanの設定ファイルとして、phpstan.neonをプロジェクト直下に作成します。

parameters:
    paths: # 検出対象のディレクトリを指定
        - app # 今回はLaravelを使っているということもあり、app配下だけを検出対象に指定
    level: 0 # 適用するLevel。0〜9まであり、0が最も緩い
参考
  • PHPStanの設定ファイルのドキュメントページ:Config Reference
  • PHPStanのLevelについてのドキュメントページ:Rule Levels

PHPStanを実行してみる

PHPStanの設定ファイルである、phpstan.neonファイルを作成・設定したところで、PHPStanを一度実行してみます。

実行コマンドは以下(analyseは省略可能です)。

$ ./vendor/bin/phpstan analyse

メモリ不足で落ちてしまう場合は、下記のようにオプションをつけてあげます。

$ ./vendor/bin/phpstan analyse --memory-limit=1G

全く新しいシステムに対して、PHPStanを導入する場合は、エラーは発生しないかと思いますが、既存のシステムに対して、PHPStanを導入する場合は何かしらエラーが出るかと思います。

ここで、致命的なエラーが出ている場合は、後ほど作成するbaselineファイルを作成できなくなるので、修正してあげる必要があります。

致命的なエラーが出ていない場合は、一旦次のide_helperの導入に進みます。

ide_helperを導入する

Laravelを使っている場合は、ide_helperを導入してあげましょう!

ide_helperを導入せずに、PHPStanを実行すると、ファサードを使用している箇所などでエラーが発生してしまいます。

ide_helperはLaravelのIDE補完を可能にするためのものですが、今回ide_helperをインストールして、_ide_helper.phpファイルなどを用意することで、ファサード等のエラーが出なくなります。

barryvdh/laravel-ide-helperをinstallする

composer経由で、ide_helperをinstallします。

$ composer require --dev barryvdh/laravel-ide-helper

リポジトリ:barryvdh/laravel-ide-helper

使用しているLaravelのバージョンによっては、インストールに失敗するので、以下のようにバージョンを指定してあげる必要があります。

$ composer require --dev barryvdh/laravel-ide-helper:"2.8.2"

バージョン詳細:barryvdh/laravel-ide-helper/releases

config/app.phpのprovidersにIdeHelperServiceProviderクラスを追加する

barryvdh/laravel-ide-helperリポジトリのREADME.mdに記載があるように、config/app.phpのprovidersに下記を追加してあげます。

Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class,

_ide_helper.phpファイルを生成する

IDE補完用のヘルパーファイルを生成します。

$ php artisan ide-helper:generate

プロジェクト直下に、_ide_helper.phpファイルが生成されるので、このファイルをphpstan.neonファイル内で読み取るように指定してあげます。

parameters:
    paths:
        - app
    level: 0
    scanFiles:
        - _ide_helper.php # _ide_helper.phpファイルを読み取る

phpstan.neonファイルで、_ide_helper.phpファイルを読み取るように指定してあげたところで、改めてphpstanを実行してみましょう。

$ ./vendor/bin/phpstan analyse

致命的なエラーが出た場合は、その部分を修正して、致命的なエラーが出なくなるようにします。

致命的なエラーが出なければ、次に既出のエラーを無視するためのbaselineファイルを作っていきます!

baselineファイルを生成する

baselineファイルを作成することで、PHPStanを実行した際に吐かれているエラーを無視することができるようになります。

baselineファイルの作り方は以下。

$ ./vendor/bin/phpstan analyse --generate-baseline

上記を実施してあげると、プロジェクト直下にphpstan-baseline.neonファイルが作成され、このファイルに無視するエラー内容が記載されています。

これを、phpstan.neonで読み込むように設定。

includes:
    - phpstan-baseline.neon # phpstan-baseline.neonファイルを読み込む

parameters:
    paths:
        - app
    level: 0
    reportUnmatchedIgnoredErrors: false # baselineファイルのエラーが発生していない場合の通知をオフにする
    scanFiles:
        - _ide_helper.php

この状態で、phpstanを実行すると、現時点でのエラーは起きなくなります。

仮に、baselineファイルで指定したエラー箇所を修正した場合には、エラーが発生するので、その場合は、該当箇所をbaselineファイルから削除してあげることで解消します。

PHP_CodeSnifferを導入する

続いて、構文のチェック等を行なってくれるPHP_CodeSnifferを導入していきます!

squizlabs/php_codesnifferをinstallする

composer経由で、squizlabs/php_codesnifferをinstallします。

$ composer require --dev squizlabs/php_codesniffer

リポジトリ:squizlabs/php_codesniffer

phpcsのiオプションで使用できるコーディング規約を確認する

以下のコマンドで、使用できるコーディング規約を確認することができます。

$ ./vendor/bin/phpcs -i
The installed coding standards are PEAR, Zend, PSR2, MySource, Squiz, PSR1 and PSR12

今回は、コーディング規約としてPSR-2を適用していきたいと思います

phpcs.xmlファイルを作成する

プロジェクト直下にphpcs.xmlファイルを作成して、基本となるコーディングルール等を定義していきます。

<?xml version="1.0"?>

<ruleset name="PSR2">
    <description>PSR-2 coding standard</description>

    <!-- 適用コーディング規約の指定 -->
    <rule ref="PSR2">
        <!-- 除外したい項目を列挙 -->
    </rule>

    <!-- 出力に色を適用 -->
    <arg name="colors" />

    <!-- 除外ディレクトリ -->
    <exclude-pattern>./bootstrap/*</exclude-pattern>
    <exclude-pattern>./database/*</exclude-pattern>
    <exclude-pattern>./node_modules/*</exclude-pattern>
    <exclude-pattern>./public/*</exclude-pattern>
    <exclude-pattern>./storage/*</exclude-pattern>
    <exclude-pattern>./tests/*</exclude-pattern>
    <exclude-pattern>./vendor/*</exclude-pattern>
</ruleset>

除外ディレクトリに指定したディレクトリ以外がチェック対象となります。除外したいコーディングルールがある場合は、ruleタグ内に列挙していけばOK。

参考:squizlabs/PHP_CodeSniffer/blob/master/src/Standards/PSR2/ruleset.xml

除外したい項目については、下記のコマンドを実行することでエラー項目を列挙してくれます。

$ ./vendor/bin/phpcs -s --report=source --standard=phpcs.xml ./

書き方は以下のような感じ。

<rule ref="PSR2">
    <exclude name="Squiz.WhiteSpace.SuperfluousWhitespace.EndLine"/>
</rule>

PHP_CodeSnifferを実行する

phpcs.xmlファイルにてコーディングルール等の設定を行ったので、PHP_CodeSnifferを実行してみます。

$ ./vendor/bin/phpcs --standard=phpcs.xml ./

エラーが少ない場合は、さっと修正しても良いですし、エラーが多くて修正に手間がかかる場合は一旦放置しても大丈夫です(後ほどPR単位で構文チェックしてエラーをレビューコメントとして吐くことができる方法を解説するので)。

reviewdogとGitHub Actionsを導入する

最後に、reviewdogとGitHub Actionsを導入していきます。

.github/workflows/reviewdog.ymlファイルを作成して、以下を記載します。

name: reviewdog

on: pull_request

jobs:
  # 構文チェック用ジョブ(PHP_CodeSniffer + reviewdog)
  lint:
    runs-on: ubuntu-latest
    steps:
      # リポジトリからチェックアウト
      - uses: actions/checkout@v2
      # reviewdogをセットアップ
      - uses: reviewdog/action-setup@v1
        with:
          reviewdog_version: latest
      # PHP環境をセットアップ
      - name: Setup PHP
        uses: shivammathur/setup-php@v2 
        with:
          php-version: '8.0' # 環境に合わせて変更してください
          tools: composer:v2
      # composer install
      - name: Resolve dependencies
        run: composer install --no-progress --prefer-dist --optimize-autoloader
      # 構文チェックを実行し、実行結果をreviewdogに渡す
      - name: lint
        env:
          REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} # secrets.GITHUB_TOKENは発行せずに呼び出せる
        run: ./vendor/bin/phpcs --report=emacs --standard=phpcs.xml ./ | reviewdog -reporter=github-pr-review -efm='%f:%l:%c:%m'

  # 静的解析用ジョブ(PHPStan + reviewdog)
  analyse:
    runs-on: ubuntu-latest
    steps:
      # リポジトリからチェックアウト
      - uses: actions/checkout@v2
      # reviewdogをセットアップ
      - uses: reviewdog/action-setup@v1
        with:
          reviewdog_version: latest
      # PHP環境をセットアップ
      - name: Setup PHP
        uses: shivammathur/setup-php@v2 
        with:
          php-version: '8.0' # 環境に合わせて変更してください
          tools: composer:v2
      # composer install
      - name: Resolve dependencies
        run: composer install --no-progress --prefer-dist --optimize-autoloader
      # PHPStanを実行し、実行結果をreviewdogに渡す
      - name: Run PHPstan
        env:
          REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: ./vendor/bin/phpstan analyse --error-format=raw --no-progress --memory-limit=1G | reviewdog -reporter=github-pr-review -f=phpstan # PHPStan側の出力がデフォルトの--error-format=githubでは読み取れないので、--error-format=rawを指定しています

これをpushしてPRを作成すれば、reviewdog.ymlファイルに記載した、lintジョブとanalyseジョブが走ります!

仮にエラーが見つかった場合は、PRのレビューコメントとして出力されるので、確認してみてください。

下記に今回のサンプルコードを用意しています(Laravelプロジェクトはsrc配下に配置しているので、今回のものとは若干違う構成になっています)

まとめ|PHPStan+PHP_CodeSniffer+reviewdog+GitHub Actions導入

ここまで、「GitHubでPR(プルリクエスト)を作成した時に、静的解析と構文チェックを自動実行して、エラー内容をレビューコメントとして吐き出す方法」について紹介してきました。

具体的には、

  • 静的解析ツールとして「PHPStan
  • 構文チェック等のツールとして「PHP_CodeSniffer
  • ソースコードレビューを行ってくれる補助ツールとして「reviewdog
  • pushやPR作成などのイベントをトリガーに、対応するアクションを組み合わせてワークフローの自動化が行える「GitHub Actions

の設定方法について詳しく説明してきました。

まだ、これらを導入していないという方はぜひ導入してみてください!

コメント

タイトルとURLをコピーしました