こんにちは、エンジニアの上野です。
今回はソース例や実際のサンプルソースを交えながら 「PHPバージョンアップに向けてCIで品質を担保・向上していく」と題してlancers.jp本体に導入しているCircleCIでの取り組みについてご紹介します。
導入背景
PHPバージョンアップに向けて現状のソースの品質を担保・向上していく目的で
- コーディング規約の遵守
- syntaxの先取り修正
- 複雑度悪化への歯止め
- UTの継続実施
の4つを継続的に実施していこうとなったためCircleCIを用いて順次整えていっています。
UTについては、テスト量が多く(なんと10000超!!)継続的に実施するためには時間的な制約が残っているためCIではなく毎日一回のチェックを行っています
それぞれの設定について
1. コーディング規約の遵守
cakephpのバージョンを上げていくとPSRへの適用が徐々に行われています。(直近のCakePHP3.4でもPSR-7への準拠が行われました)
そのため自分たちのソースもできるだけそこに近づけていくためにPHP-CS-Fixerを用いて規約のチェックと自動修正をできるようにしました
cd CAKE # composer.jsonにPHP-CS-Fixerの記述を追加 vi composer.json # .php_csを追加(幾つか方法はありますがランサーズではapp配下においています) vi app/.php_cs
{ "require-dev": { "phpmd/phpmd" : "^2.4", "friendsofphp/php-cs-fixer": "^2.1" } }
<?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を取って差分実行させています
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ソースに手をいれるとなると必ずエラーになります)
machine: php: version: 7.0.4
git diff --name-status origin/master -- | grep -E '^[AUM].*\.php$'| cut -c3- | xargs -n1 php -l
3. 複雑度悪化への歯止め
PHPの静的解析ツールであるPHPMDの差分実行シェルを作りました。
また、レガシーなソースも多くあるのでPHPMDでの警告は参考に出力してリファクタ対象としてCircleCIの終了ステータスには影響を及ぼさないようにexitは0で返しています
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フェーズで実行
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からも閲覧できます。参考になれば嬉しいです。