こんにちは。サーバーサイドエンジニアの@akane_256です。
今日は、PHP_CodeSniffer+GitHub+CircleCIを使って、PHPのコードレビュー(コーディングルールの徹底)を一部自動化したことについて書きたいと思います。
目次
- 興味を持った背景
- 今回やったこと
- 利用ツールについて
- 実装の流れ
- ハマったところ
- まとめ
興味を持った背景
開発が進むにつれて、他の人が書いたコードと自分が書いたコードで、統一感を保つのが難しくなってきたな、という実感があったのとコーディングルールにあっていないコードを自動で見つけられたら便利だよね、と同僚と話す機会があったので試してみました。その他にも、下記のようなメリットがあるのではないかと考えました。
- 少ない人数でコードレビュー時間を十分に取れない場合でもソースコードの品質を保てる。
- もし人が増えた時でも、ソースコードの書き方に統一感をもたせられる。
- 自分のコードのいけない部分がわかるのでレベルアップに繋がる。
今回やったこと
今回は下記のような流れで作成しました。
1. ソースコードをGitHubにpushする
2. CircleCIがpushをフックにテストを実行する。テストの中で、PHP_CodeSnifferのコマンドを叩いてソースコードの静的解析を実行する
3. 結果をPull Requestにコメントとして表示させる
4. テスト結果をSlackに通知する
完成イメージ。コーディングルールに合わない部分を指摘してコメントしてくれます。
利用ツールについて
PHP_CodeSnifferとは?
GitHub上にある、PHPのソースコード整形OSSです。
定義されたコーディングルールの違反を検出したり、自動整形してくれます。
コードをきれいにして一貫性を保つために使います。
CircleCIとは?
アプリケーション作成時の品質改善や納期の短縮のために使うツールです。今回は品質改善(=コーディングルールの統一)に使います。
CIツールはたくさんあって選ぶのが大変でしたが、主に下記の理由からCircleCIにしました。
- GitHubとの連携が簡単。GitHubのアカウントを作成すれば、CircleCIはGitHubのアカウントでログインすれば終わり。
- 設定は、WebのUIもしくはymlファイルで管理できる。
- 1ヶ月1500分(=25時間)までなら無料(1コンテナ)。※2018/2時点
- CircleCI 2.0がでたタイミングで、開発も盛んに行われている。
- meetupなど盛んに行われており盛り上がっている。
- UIが綺麗。
実装の流れ
- アカウント準備
- GitHubアカウント作成
- リポジトリをpush
- CircleCIのアカウント作成(GitHubアカウントでログイン)
- 利用ツールの連携準備
- GitHubとCircleCIの連携
- CirlcleCIとSlackの連携
- プロジェクトの設定準備
- composer.jsonの編集
- テストコマンドをまとめた
check_syntax.sh
をリポジトリに追加 - CircleCIの設定ファイル
circle.yml
をリポジトリに追加
1のアカウント準備は簡単だと思うので割愛します。利用ツールの連携準備から書いていきます。
利用ツールの連携準備
GitHubとCircleCIの連携
GitHubのPull Requestにコードの解析結果をコメントで書き込みするために、GitHubのアクセストークンをCircleCIに登録する必要があります。
これがないとCircleCIがGitHubにアクセスできず、若干ハマりました。。
GitHubのアクセストークンは、Setting
> Developer settings
> Personal access tokens
> Generate new token
から発行します。
発行したトークンの値はコピーしておきます。コピーし忘れると、また再度発行することになるので忘れずに。
名前はわかりやすく、 CircleCI
とかにしておくと良いと思います。
次は、CircleCI側の設定です。
CircleCIの画面を開き、プロジェクトのSetting
> Environment Variables
> Add variable
から、先ほどの値をペーストして保存します。
こちらの名前もわかりやすく、GITHUB_ACCESS_TOKEN
とかにしておくと良いと思います。
CircleCIとSlackの連携
CircleCIの画面から連携できるようになっています。
Setting
> Chat Notifications
から、SlackのWebhook URLを登録する部分があるので、こちらにSlackのWebhookのURLを登録します。
ちなみに、連携が完了すると、ビルド終了時に通知がきます。テスト失敗時は赤色、成功時は緑色で表示されます。
(一部文字を伏せています)
今回はPull Requestの量が多くないのですぐにビルドが終わったため、Slackへ通知するメリットはあまり感じられませんでしたがビルドが数分以上かかる場合は、チャットで通知してくれると便利です。
これで利用ツールの連携準備が整いました!
プロジェクトの設定準備
次は、実際にソースコードなどを管理しているプロジェクトの設定準備です。
前提条件として、今回の検証に使ったプロジェクトのディレクトリ構成はこのような形式です。
PHPのパッケージ管理には、composerを利用します。
├── application │ └── composer.json │ : ├── check_syntax.sh ├── circle.yml :
composer.jsonの編集
composer.jsonを編集して、 php_codesniffer
をインストールする記述を追加します。
こういった整形ツールは開発環境のみで使うので、require-dev
の部分に追記します。
application/composer.json
"require-dev": { "squizlabs/php_codesniffer": "^3.1" }
テストコマンドをまとめた check_syntax.sh
をリポジトリに追加
ここが今回の一番の肝の部分です。PHPの一般的なコーディング規約である PSR-2
にのっとって解析するようにしています。
#!/bin/bash set -v if [ "${CIRCLE_BRANCH}" != "develop" ]; then # GitHubのPull Requestにコメントをするために必要なgemのインストールをします echo gem install gem install --no-document checkstyle_filter-git saddler saddler-reporter-github # pull requestがないか確認します if [ -z "${CI_PULL_REQUEST}" ]; then # when not pull request REPORTER=Saddler::Reporter::Github::CommitReviewComment else REPORTER=Saddler::Reporter::Github::PullRequestReviewComment fi # git diffからphpファイルを取り出し、php_codesniferのコマンドを実行します echo saddler git diff --name-only origin/develop \ | grep -e '.php$' \ | xargs application/vendor/bin/phpcs -n --standard=PSR2 --report=checkstyle \ | checkstyle_filter-git diff origin/develop \ | saddler report --require saddler/reporter/github --reporter $REPORTER fi
CircleCIの設定ファイル circle.yml
をリポジトリに追加
コードの解析を実行するプログラムが用意できたので、そのプログラムをCircleCIから実行できるように設定します。
CircleCIの設定ファイル circle.yml
をプロジェクトルートディレクトリに追加します。CircleCIはこのymlファイルをみて、ビルドを実行します。
今回は、 test
部分をoverride(上書き)して、先ほど追加した.check_syntax.sh
を実行するように記載しました。
circle.yml
machine: timezone: Asia/Tokyo php: version: 5.6.17 test: override: - composer install --dev --no-interaction --working-dir=application - ./check_syntax.sh
これで完成です。GitHubのpushに応じて、CircleCIでテストが実行され、結果を通知してくれるようになります。
ハマったところ
- CircleCIはクラウドサービスなので、ちょっとしたプログラムの修正後の動作確認でも、pushしなければいけなかったのが辛かったです。(CircleCI2.0からローカルで実行できるようなので試してみたいです。)
- CircleCIとGitHubの連携。アクセストークンの登録ができていないのを気づかないまま実装を進めていたので、CircleCIが「Pull Requestないよ」とエラーになってしまい、少しハマりました。
まとめ
PHPは、標準ではコードを整形する機能が付いていないので、気をつけないと複数人でバラバラのコーディングスタイルになりがちです。こうして整形用のツールを使ってコードの一貫性を保つことは、自分以外のエンジニアのために大事なことだと思います。また、こうしてCIを使って自動で指摘がされるようにしておくと、新しい人が入っても一貫したルールを保つことができるので、ぜひ活用していきたいと思います。
また、実装にあたりこちらの記事をがっつり参考にさせていただきました。ありがとうございます。
Wedding Parkでは一緒に技術のウエディングパークを創っていくエンジニアを募集しています。
興味のある方はぜひ一度気軽にオフィスに遊びにきてください。