SREチームの金澤です。
CakePHP2.8移行が終了し、次のステップとしてPHP5.6化を進めています。
今回はPHP5.6化に向けて行ったCircleCI周りのアップデートについてお話させていただきます。
※実際のソースは公開したPHP、CakePHPバージョンアップのリポジトリで参照できるようにしています。
導入背景
以前の記事「PHPバージョンアップに向けて現状のソースの品質を担保・向上していく」で
- コーディング規約の遵守
- syntaxの先取り修正
- 複雑度悪化への歯止め
- UTの継続実施
の4つを継続的に実施するためにCircleCIを本格的に導入しました。
今回は、PHP5.6バージョンアップに向けて
- コーディング規約の遵守
- UTの継続実施
のアップデートを行いました。
現在のCircleCIの設定
現在はCircleCIをパスしないとソースをマージできないようにしています。
それに合わせて極端に厳しい設定はしないよう変更しています。
例えば、複雑度やphpmdで指摘されるような内容は、すぐに修正することは難しいため、CIでは回さないようにしています。
差分実行
CircleCIでチェックするソースコードは、原則、修正したもののみを対象にしています。
修正したソースコードを抽出するスクリプトが以下になります。
#!/bin/bash set -e branch=${1} declare -a tmps=( /tmp/diff.log ) for file in ${tmps}; do if [ -f "${file}" ]; then rm -rf ${file} fi done echo "branch: ${branch}" set +e git diff -p --name-only --reverse --format="" origin/master...origin/${branch} | sort | uniq > /tmp/diff.log set -e echo "--------------------------------------------------" echo "diff files:" echo "`cat /tmp/diff.log`" exit 0
以下のコマンドで、派生元のMasterブランチと現在のブランチのソース差分を比較します。
git diff -p --name-only --reverse --format="" origin/master...origin/${branch} | sort | uniq > /tmp/diff.log
「…」で派生元Masterブランチとの比較となります。
※「..」だと現在のMasterブランチとの比較になってしまい、時間が経つほど余計な差分が出るようになります。
抽出した結果を/tmp/diff.logに保存しておき、後のチェックで利用します。
コーディング規約の遵守
PHP5.6に向けて設定更新しました。
PHP-CS-Fixerを以下のように設定しました。
<?php $finder = PhpCsFixer\Finder::create() ->notName('.php_cs') ->notName('*.html') ->notName('*.md') ->notName('*.rb') ->notName('*.sh') ->notName('*.xml') ->exclude('tmp') ->in(__DIR__); return PhpCsFixer\Config::create() ->setRules(array( '@PSR2' => true, '@PHP56Migration' => true, // 'cast_spaces' => array('space' => 'none'), // PHP CS Fixer 2.2.20 では設定不可 // 'combine_consecutive_issets' => true, // PHP CS Fixer 2.2.20 では設定不可 'combine_consecutive_unsets' => true, // 'ereg_to_preg' => true, // PHP 5.6対応後に設定 'no_empty_comment' => true, 'no_empty_phpdoc' => true, 'no_whitespace_before_comma_in_array' => true, 'whitespace_after_comma_in_array' => true, 'braces' => array() )) ->setUsingCache(false) ->setFinder($finder);
@PSR2と@PHP56Migrationを設定し、PHP5.6に対応するようにしました。
コメントアウトしている箇所については、PHP5.6バージョンアップ後に設定する予定です。
(PHP5.3ではPHP CS Fixerは 2.1までしか対応していない)
CircleCIでこのPHP CS Fixerを実行し、NGだった場合にSlackに以下のように通知します。
修正はPHP-CS-Fixerのコマンドで1発でできるようになっています。
このタイミングで、ショートタグ<?からロングタグ<?phpへの変換も行われます。
CakePHP2.8チェック
これは、CakePHP2.8移行時に作成したもので移行作業時に重宝しました。
CakePHP2.8移行が完了した現在も稼働中で、Cake1.3の書式で書いた箇所を通知してくれます。
UTの継続実施
今回一番やりたかったことです。
CakePHP2.8移行完了の際に、旧CakePHP1.3のUTを思い切って全部捨てました。
旧CakePHP1.3のUTが以下の問題を抱えていたためです。
- CakePHP1.3のテストがSimpleTest製(CakePHP2.8はPHPUnit)
- テストに非常に時間がかかる(全実行に23時間)
- メンテナンスしきれていない(すべてのテストが正常終了していない)
そのため、今回のCircleCI化に向けてCakePHP2.8製のUTのみを残しました。
※旧CakePHP1.3のUTは別リポジトリに退避し、サルベージしながらCakePHP2.8用に復元させていく予定です。
UTの実施のためには、開発で利用している以下のDockerコンテナをCircleCIで起動する必要があります。
- Appコンテナ(PHP5.3)
- MySQLコンテナ(データ入り)
この2つのコンテナを起動するために、CircleCIで以下の設定を行っています。
(Docker ExecuterでAWS ECRからコンテナをダウンロード)
docker: - image: xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/lancers_app:latest aws_auth: aws_access_key_id: $AWS_ACCESS_KEY_ID aws_secret_access_key: $AWS_SECRET_ACCESS_KEY environment: TZ: /usr/share/zoneinfo/Asia/Tokyo DB_HOST: 127.0.0.1 - image: xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/mysql:latest aws_auth: aws_access_key_id: $AWS_ACCESS_KEY_ID aws_secret_access_key: $AWS_SECRET_ACCESS_KEY environment: TZ: /usr/share/zoneinfo/Asia/Tokyo
CIの実行時間について
今回の変更に伴い、今まで1分以内で終わっていたCIが、5分近くかかるようになりました。
そのうち2分半がDockerのセットアップに費やされています。
今後、コンテナ容量の削減や、CircleCI上にキャッシュする等、工夫していきたいところです。
UTは、今のところ全テストを実行しており、30秒程度で終わっていますが、今後旧CakePHP1.3のテストの復元や、新テストの追加が進むと、さらに実行時間が増加されることが予想されるので、差分実行(修正に関連するテストのみの実行)等の工夫が必要になってくると思います。
最後に
まだまだ改良の余地はあるものの、PHP-CS-FixerやPHPUnitを本格的にCircleCIで回すことができたのは大きな前進だと思います。
今後、PHP5.6やPHP7にコンテナ変更した際にもCIを回しながらチェックしていきたいと思います。