CircleCI 2.0 でCakePHPアプリのユニットテストを実行する
土曜日にPHPカンファレンス関西2017に参加(3回目)してきます。tanakaです。
さて、アプリケーションをビルドするサービスのCircleCI 2.0 が2017/7/11に正式リリースされました。
以前に【5 Stepでわかる】CircleCIで始める、CakePHP3アプリの継続的インテグレーション でCircleCIでCakePHP3アプリをビルドする方法を紹介しました。 今回、CircleCI 2.0でビルドする方法を調べていたのでリリースに合わせてまとめました。
CircleCI 2.0 について
CircleCI 2.0以前のバージョン(区別のため1.0という名前になっています)は、あらかじめいろいろなミドルウェアがインストールされたUbuntu仮想マシンを使ってビルドするのが基本でした。 PHPも組み込まれていますが、マイナーバージョンは結構飛び飛びのものしかインストールされておらず、それ以外のバージョンを使いたいときは別途準備が必要です。 CircleCI 2.0では最初からDockerイメージを指定することができるので、PHPやMySQLのバージョンを自由に選択したり、カスタマイズしたDockerイメージを使うことができるようになりました。
その他、手順の中で git checkout
したりキャッシュの保存・リストアするタイミングを指定することができるようになってます。
CakePHP3アプリ ビルドのサンプル
phpunit
, eslint
を実行するサンプルは以下の通りです。
こちら解説していきます。
まず、いままで circle.yml
というファイルに設定を書いていましたが2.0では.circleci/config.yml
というファイルに移動します。
次に見ていただきたいのが一番下のworkflows:
の部分です。Workflowsを使うと
ビルド~デプロイまでの依存関係を定義できるようですが、ここでは複数定義したjobをまとめるために定義しています。
GitHub の Pull Request で分割したjobのステータスを確認できて便利です。
workflows:
version: 2
build-all:
jobs:
- build_php
- build_javascript
PHPアプリのビルド設定をbuild_php:
に書いており、最初に使うDockerイメージの設定を書いています。
docker:
- image: tenkoma/php:7.1-apache-sample
environment:
DEBUG: true
DATABASE_URL: "mysql://root:password@127.0.0.1/cisample?encoding=utf8mb4&timezone=UTC&cacheMetadata=true"
DATABASE_TEST_URL: "mysql://root:password@127.0.0.1/cisample?encoding=utf8mb4&timezone=UTC& cacheMetadata=true"
- image: circleci/mysql:8.0
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
environment:
MYSQL_DATABASE: cisample
MYSQL_ROOT_PASSWORD: password
config/app.php
では既定で DATABASE_URL
, DATABASE_TEST_URL
といった環境変数を使うようになっているため、それにそってミドルウェアを設定し、MySQL DB接続のための環境変数をセットしました。
steps:
で実際のビルド手順を定義します。
steps:
- restore_cache:
key: cakephp3-circleci-example-{{ .Branch }}
- checkout
- run: composer install --dev --no-interaction
- save_cache:
key: cakephp3-circleci-example-{{ .Branch }}
paths:
- "/home/ubuntu/.composer/cache"
- run:
name: create test repot dir
command: mkdir -p $CIRCLE_TEST_REPORTS/phpunit
- run:
name: Wait for MySQL DB
command: dockerize -wait tcp://localhost:3306 -timeout 1m
- run:
name: Initialize Database
command: bin/cake migrations migrate
- run: vendor/bin/phpunit --configuration phpunit.xml.dist --log-junit $CIRCLE_TEST_REPORTS/phpunit/junit.xml
いくつかのrun:
に混じって checkout
, restore_cache:
, save_cache:
が追加されています。コードのチェックアウト、キャッシュの保存/リストアのタイミングを設定できるようになりました。
またDBマイグレーションまでにMySQL DBサーバーが準備できているとは限りませんので、dockerizeというツールで待機しています。
それ以外のビルド手順はMySQL DBを用いたテストまでと同じなので省略します。
ビルド結果は以下のようになります。
(CircleCI上のワークフロー結果ページにリンクしたかったのですが404 Not Found になるため画像で紹介します。)
カスタマイズしたDockerイメージを使う
上記の設定ファイルでは用意済みのDockerイメージではなく、私がカスタマイズしたDockerイメージを使ってます。 PHP公式のイメージだと、ビルドステップで、依存パッケージやPHP拡張、composerをインストールする必要があり、 ビルド毎に90秒ほどの時間がかかりますが、あらかじめインストール済みのイメージを用意して短縮することができます。 今回のサンプルでも2分かかっていたビルドが30秒で済むようになりました。
以下のDockerfile
でビルドしてtenkoma/php - Docker Hubにpushしました。
FROM php:7.1-apache
RUN apt-get update && apt-get -y install git unzip zlib1g-dev libicu-dev wget
RUN docker-php-ext-install pdo pdo_mysql zip intl
# Setup the Composer installer
RUN curl -o /tmp/composer-setup.php https://getcomposer.org/installer \
&& curl -o /tmp/composer-setup.sig https://composer.github.io/installer.sig \
&& php -r "if (hash('SHA384', file_get_contents('/tmp/composer-setup.php')) !== trim(file_get_contents ('/tmp/composer-setup.sig'))) { unlink('/tmp/composer-setup.php'); echo 'Invalid installer' . PHP_EOL; exit(1); }"
# Install Dockerize
ENV DOCKERIZE_VERSION v0.5.0
RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz
# Install Composer
RUN php /tmp/composer-setup.php --no-ansi --install-dir=/usr/local/bin --filename=composer && rm -rf /tmp/composer-setup.php
まとめ
- CircleCI 2.0でCakePHPアプリのビルドできました
- ミドルウェアのバージョンが自由に選べるようになった
- Dockerイメージをカスタマイズしてビルド時間を短縮できるようになった
- workflow機能が便利そう