こんにちは、エンジニアの上野です。
今回はソース例や実際のサンプルソースを交えながら 「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からも閲覧できます。参考になれば嬉しいです。
