こんにちは、エンジニアの上野です。
今回はソース例や実際のサンプルソースを交えながら 「PHPバージョンアップに向けてCIで品質を担保・向上していく」と題してlancers.jp本体に導入しているCircleCIでの取り組みについてご紹介します。
導入背景
PHPバージョンアップに向けて現状のソースの品質を担保・向上していく目的で
- コーディング規約の遵守
- syntaxの先取り修正
- 複雑度悪化への歯止め
- UTの継続実施
の4つを継続的に実施していこうとなったためCircleCIを用いて順次整えていっています。
UTについては、テスト量が多く(なんと10000超!!)継続的に実施するためには時間的な制約が残っているためCIではなく毎日一回のチェックを行っています
それぞれの設定について
1. コーディング規約の遵守
cakephpのバージョンを上げていくとPSRへの適用が徐々に行われています。(直近のCakePHP3.4でもPSR-7への準拠が行われました)
そのため自分たちのソースもできるだけそこに近づけていくためにPHP-CS-Fixerを用いて規約のチェックと自動修正をできるようにしました
1 2 3 4 5 6 7 | cd CAKE # composer.jsonにPHP-CS-Fixerの記述を追加 vi composer.json # .php_csを追加(幾つか方法はありますがランサーズではapp配下においています) vi app/.php_cs |
1 2 3 4 5 6 | { "require-dev": { "phpmd/phpmd" : "^2.4", "friendsofphp/php-cs-fixer": "^2.1" } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?php // on cakephp1.3 APP_DIR $finder = PhpCsFixer\Finder::create() ->notName( 'README.md' ) ->notName( '.php_cs' ) ->notName( 'composer.*' ) ->notName( 'phpunit.xml*' ) ->notName( '*.xml' ) ->exclude( 'vendor' ) ->exclude( 'plugin' ) ->exclude( 'tmp' ) ->in(__DIR__); return PhpCsFixer\Config::create() ->setRules([ '@PSR2' => true]) ->setUsingCache(false) ->setFinder( $finder ); |
php_cs_fixerを起動するshellを作成
ちょっとワンライナーが細かいですが、commitのdiffを取って差分実行させています
1 2 | IFS=$ '\n' ; COMMIT_SCA_FILES=($(git diff --name-only -- diff -filter=ACMRTUXB origin /master )); unset IFS . /app/vendors/composers/friendsofphp/php-cs-fixer/php-cs-fixer fix --config=app/.php_cs - v --dry-run -- diff --path-mode=intersection "${COMMIT_SCA_FILES[@]}" |
2. syntaxの先取り修正
circle.ci を7.0環境でビルドしてsyntaxチェッカーを回すことで、非推奨関数を使った場合などエラーになるようにしています。
ここでも差分実行させています。(coreのソースは準拠していないものが多いので、万が一coreソースに手をいれるとなると必ずエラーになります)
1 2 3 | machine: php: version: 7.0.4 |
1 | git diff --name-status origin /master -- | grep -E '^[AUM].*\.php$' | cut -c3- | xargs -n1 php -l |
3. 複雑度悪化への歯止め
PHPの静的解析ツールであるPHPMDの差分実行シェルを作りました。
また、レガシーなソースも多くあるのでPHPMDでの警告は参考に出力してリファクタ対象としてCircleCIの終了ステータスには影響を及ぼさないようにexitは0で返しています
1 2 3 4 5 6 | FILESTRING=`git diff --name-status origin /master -- | grep -E '^[AUM].*\.php$' | cut -c3- | tr '\n' ',' | sed -e 's/,$//g' ` if test "${FILESTRING}" ; then vendor /bin/phpmd $FILESTRING text codesize,controversial,design,naming,unusedcode fi exit 0 |
3つのチェッカーをtestフェーズで実行
1 2 3 4 5 6 7 8 | machine: php: version: 7.0.4 test : orverride: - app /tests/php_cs_fixcer .sh - app /tests/php_syntax_checker .sh - app /tests/phpmd_checker .sh |
ランサーズでは今回作成したスクリプトを流用して、app配下全ファイルに対して適用して、数日で
- 修正が必要な数十個程度の記述を洗い出し
- 主に改行や空白、アクセス修飾子などソースには影響しない6万行程を自動修正
を行うことができました。改善したソースを日々CircleCIがチェックしてくれています。
特にコーディング規約はルールの統一ができ余分なレビュー時間の削減にもつながっていておすすめです。
この他、pre-commitで事前にソースを自動修正させたり、新しくCakePHP3.4で作っているプロジェクトではphpunitの自動実行なども実施しています。
それらはまた追ってお伝えできればいいなと思っています。
ソースのサンプルはgithubからも閲覧できます。参考になれば嬉しいです。