ランサーズ等のサービスを開発・運用する中で得た知識やノウハウを紹介しています。

Labels:  CI, CircleCI, Docker, PHP 投稿者:kanazawa

PHP5.6化に向けたCircleCIのアップデート

SREチームの金澤です。
CakePHP2.8移行が終了し、次のステップとしてPHP5.6化を進めています。

今回はPHP5.6化に向けて行ったCircleCI周りのアップデートについてお話させていただきます。

※実際のソースは公開したPHP、CakePHPバージョンアップのリポジトリで参照できるようにしています。

導入背景

以前の記事「PHPバージョンアップに向けて現状のソースの品質を担保・向上していく」で

  1. コーディング規約の遵守
  2. syntaxの先取り修正
  3. 複雑度悪化への歯止め
  4. UTの継続実施

の4つを継続的に実施するためにCircleCIを本格的に導入しました。

今回は、PHP5.6バージョンアップに向けて

  1. コーディング規約の遵守
  2. 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,
    ))
    ->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の書式で書いた箇所を通知してくれます。

※具体的なソースはこちらになります(Ruby製)

UTの継続実施

今回一番やりたかったことです。

CakePHP2.8移行完了の際に、旧CakePHP1.3のUTを思い切って全部捨てました。
旧CakePHP1.3のUTが以下の問題を抱えていたためです。

  1. CakePHP1.3のテストがSimpleTest製(CakePHP2.8はPHPUnit)
  2. テストに非常に時間がかかる(全実行に23時間)
  3. メンテナンスしきれていない(すべてのテストが正常終了していない)

そのため、今回のCircleCI化に向けてCakePHP2.8製のUTのみを残しました。
※旧CakePHP1.3のUTは別リポジトリに退避し、サルベージしながらCakePHP2.8用に復元させていく予定です。

UTの実施のためには、開発で利用している以下のDockerコンテナをCircleCIで起動する必要があります。

  1. Appコンテナ(PHP5.3)
  2. 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

UTが失敗したときも同様に通知します。

CIの実行時間について

今回の変更に伴い、今まで1分以内で終わっていたCIが、5分近くかかるようになりました。
そのうち2分半がDockerのセットアップに費やされています。
今後、コンテナ容量の削減や、CircleCI上にキャッシュする等、工夫していきたいところです。

UTは、今のところ全テストを実行しており、30秒程度で終わっていますが、今後旧CakePHP1.3のテストの復元や、新テストの追加が進むと、さらに実行時間が増加されることが予想されるので、差分実行(修正に関連するテストのみの実行)等の工夫が必要になってくると思います。

最後に

まだまだ改良の余地はあるものの、PHP-CS-FixerやPHPUnitを本格的にCircleCIで回すことができたのは大きな前進だと思います。
今後、PHP5.6やPHP7にコンテナ変更した際にもCIを回しながらチェックしていきたいと思います。

ランサーズではサービスを成長させてくれるエンジニア、デザイナーを募集しています!
ご興味がある方は、以下URLよりご応募ください。


【中途採用】
サービスリードエンジニア
テックリード(アーキテクト)
フロントエンドエンジニア
サーバーサイドエンジニア
業務エンジニア(社内システム基盤・基幹システム)

【インターン・学生バイト】
19新卒対象サマーインターン
エンジニアインターン

その他採用情報

関連記事

開発環境のDocker化 その後

インフラエンジニアの金澤です。 開発環境をDocker化してから1年経ちましたので、その後のアップデートについて書きたいと思います。 前提 ランサーズでは、Dockerを開発を以下の目的で導入しました PCリソース(HDD、メモリ)を削減 コンテナ単位でサーバ …

PHP、CakePHPバージョンアップの決断

インフラエンジニアの金澤です。 この度、ランサーズ稼働環境(PHP + CakePHP)のバージョンアップを決断しました。 まずは私から、その経緯と計画についてお話いたします。 バージョンアップ決断の理由 ランサーズは、2008年にサービスを開始しました。 現 …

ランサーズ開発ランチ(Lunchers#3)~ねこもり高橋さん PHPバージョンアップ編~

エンジニアのshinです。 ランサーズでは4月から、ゲストを招いてランチを食べながら話をするランサーズ開発ランチ(Lunchers)という取り組みを実施しています。 5/16に実施した第3回の内容をご紹介します。   第3回のゲスト紹介 合同会社ねこ …