資料公開ピクシブ百科事典に静的解析のCIを導入した話こんにちは、4月からピクシブでアルバイトをしているmdanです。今回はピクシブ百科事典に静的解析のCIを導入した話を書きます。これまでピクシブ百科事典には解析ツールが導入されていませんでした。いってもピクシブ百科事典のリリース頻度はそこまで多くなく、PhpStormが静的解析してくれるので大きな問題はありませんでした。社内では様々なエディタが使われているので万全ではありませんし、リリースの際は本当にエラーがないのか不安が残ります。このような理由から静的解析のCIを導入することにしました。静的解析ツールとは、コードを実行せずにプログラムの性質を解析するツールのことです。コードを実行しない解析なのでテストコードを書く必要がなく、比較的簡単に使うことができます。ピクシブ百科事典はPHPで開発されており、PHPの変数やメソッド、構文などをチェックする静的解析ツールとしてはPHPStanとPhanがあります。PHPStanはautoloadなどの実行時情報も考慮して解析してくれるため、解析の度に全てのコードを読み込むPhanと比較して高速に動作します。今回はマージリクエストごとに変更箇所だけチェックしたかったので、PHPStanを導入しました。ピクシブ百科事典は専任の開発チームがいるわけではなく、社内の多くのエンジニアがコミットする可能性があります。ピクシブではすでに多くのサービスの開発でPHPStanのCIを導入しており、他のサービスと開発体験を揃えたいというのもPHPStanを選んだ理由です。PHPStanとPhanについては以下の資料に詳しく書いてあります。niconarePHPStanはcomposerで簡単にインストールができて、以下のコマンドで実行できます。/path/to/directory_or_filePHPStanではどのレベルまで解析するのかを0~7の8段階まで設定できます。それぞれのレベルがどこまで解析するのかは、リポジトリ内のconfを見るとなんとなく掴めると思います。https://github.com/phpstan/phpstan/tree/master/confもちろんレベルを上げるほど厳格にチェックしてくれるのですが、今回は現状のコードのエラー数を考慮してレベル3に設定しました。ロードしておくか、クラスをオートロードできるようにしておく必要があります。composer以外でautoloadしている場合は明示的に記述が必要です。いうファイルがあれば設定ファイルとして読み込んでくれます。いうファイルにオートロードできないファイルの読み込みを集めています。%currentWorkingDirectory%/autoloader_for_static_analysis.phpこれでPHPStanで静的解析ができるようになりました。次はPHPStanをマージリクエストごとに実行するために、CIツールを導入します。Integration)ツールとしてJenkinsを使用しました。CIツールを使うことで、リポジトリへのプッシュやマージリクエストの作成など任意のタイミングで、タスクを実行することができます。Jenkinsを選んだのは、静的解析ツールと同様で他サービスと開発体験を揃えたいという理由からです。Pluginを使うと、マージリクエストのターゲットブランチやソースブランチを取得することができます。マージリクエストのブランチ名が取得できるというのが、今回重要な部分になります。PHPStanで静的解析の対象を絞り込むには、対象ディレクトリ・ファイルを指定する必要があります。diffで変更箇所のファイル名のみを抽出することにしました。--diff-filterは追加や削除などの条件で差分を絞り込むオプション、--name-onlyは差分があるファイル名を表示するオプションです。このファイル名をxargsでPHPStanに引数として渡すことで、変更箇所のみを静的解析することができます。phpstan.neon.distまた、メソッド名やメソッドの引数に変更があった場合、メソッドの呼び出し箇所でエラーが出る可能性があります。そこで変更箇所のメソッド名を抽出し、そのメソッドが呼び出されているファイルもPHPStanで解析することにしました。diffの出力結果から変更箇所のシグネチャ(メソッド名と引数)を抽出します。以下のような出力があった場合、old_function($arg)とnew_function($arg)がシグネチャになります。new_function($arg)変更前のシグネチャ(行頭が-)と変更後のシグネチャ(行頭が+)を比較して、同じシグネチャがあればメソッド移動等の変更なので除外します。残りのシグネチャに含まれるold_functionやnew_functionといったメソッド名を抽出します。メソッド名が抽出できたら、git-grepを使ってそのメソッドを使用しているファイルを抽出します。git-grepはgit管理されているファイルのみをgrepするコマンドで、-lオプションを付けることで該当箇所のファイル名のみを出力することができます。これで変更箇所のメソッドが呼び出されているファイルを解析することができます。異なるメソッドが同じファイルで呼び出されている可能性があるため、uniqコマンドで重複を除外しています。php.neon.dist出力結果の絞り込みここまでで解析対象のファイルを絞り込むことができました。動いているサービスに静的解析を導入する場合、多くのエラーが出ることが予想されます。そのため、エラーの中から自分の変更箇所を探すのが困難になります。ピクシブでは変更箇所のエラーにハイライトを付けることでこの問題を解消しています。diffで得られる変更箇所の行番号を比較することで、変更箇所のエラーを絞り込むことができます。最後にJenkins管理画面からジョブを作成します。先ほど作成したスクリプトを登録し、トリガにマージリクエストを登録したら完成です!おわりにピクシブ百科事典への静的解析CIの導入を紹介しました。CIに静的解析を導入することで開発者は環境に依らず安心してリリースができるようになりました。ちなみにpixivでは静的解析の他にリンターや動的解析のCIも導入されています。ピクシブ百科事典でもより良い開発体験のため、引き続き改善をしていきたいと思います!ピクシブでは現在、長期インターン、アルバイトを募集中です。興味ある方は是非ご応募ください!長期インターンアルバイトmdan2019年4月からアルバイトしてます。PHPでサーバサイド開発を担当。趣味はGAS、インフラ、卓球。MEETUP2024-10-30pixivというシステムはどんな形をしているのか、それはなぜか。insideは、ピクシブ株式会社が運営するオウンドメディアです。Reserved.引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。