CircleCI で WordPress テーマを CI・CD する手順
CircleCI は継続的インテグレーションを支援するサービスです。GitHub などと連携して動作します。この記事では、GitHub と CircleCI を使って継続的インテグレーションのセットアップを行う手順をまとめました。
前提
この記事では、以下の前提で解説を行います。
- GitHub でのアカウント登録が完了している
- PHP のパッケージ管理ツールの Composer が利用できる状態になっている
- PHPUnit で PHP のテストを作成して実行した経験がある
- 開発済みまたは開発中の架空の WordPress テーマ Kunoichi Theme (
kunoichi-theme
というスラッグを持っているものとします) を対象にする
CircleCI について
CircleCI は広く利用されている CI サービスの1つです。2019 年 10 月 17 日現在のところ、Free プランでは以下の範囲の利用ができます。
- 無料利用枠: 週あたり 2,500 クレジット相当分
- 同時実行できる並列ジョブ数の制限: 1
- 利用できるビルド環境: Linux・Windows
クレジットとは従量課金の単位で、は 1 分 x コンピューター 1 台あたり 10 クレジットが消費されます。CircleCI の動作環境になっている Docker レイヤーのキャッシュなどでもクレジットが消費されるようです。詳細は公式ドキュメントをご覧ください。
その他のプランの詳細については 公式サイト を参照してください。
CircleCI へのサインアップ
サインアップページ から GitHub の OAuth を使って CircleCI にサインアップできます。この際に CircleCI が必要とする GitHub 上の情報へのアクセスが列挙されますので、これらに問題がないと判断できたら CircleCI を認可してください。
テーマ開発環境のセットアップ
wp-cli のコマンドで、テーマのテストのセットアップと CI 連携に関係するファイルの追加ができます。
$ wp scaffold theme-tests kunoichi-theme --ci=circle
Success: Created test files.
コマンドが成功すると、テーマに以下のファイルが追加されます。
.circleci/config.yml
# CircleCI の設定ファイルbin/install-wp-tests.sh
# テストを行うために WordPress を現在の環境にインストールするスクリプトtests/bootstrap.php
# テスト実行に先立って WordPress 環境でテーマをテスト可能な状態にする PHP プログラムtests/test-sample.php
# テストファイルのサンプル.phpcs.xml.dist
# PHP コードの静的解析ツール PHP_CodeSniffer の設定ファイルphpunit.xml.dist
# PHP のテストフレームワーク PHPUnit の設定ファイル
これで、CircleCI 上でテストを実行する準備が整いました。
ローカルで WordPress テーマのテストを実行する
CircleCI でテストを実行する前にローカル開発環境でテストを実行しておきます。以下のコマンドを実行してテスト用の WordPress をインストールします。
$ bash bin/install-wp-tests.sh <データベース名> <MySQL ユーザー名> <MySQL パスワード名> 127.0.0.1 latest
例えば テストに使うデータベース名が wordpress_test
、MySQL のユーザー名とパスワードが root
wordpress
ならば、コマンドは以下になります。テスト用のデータベース名はテーマ開発に用いているものと別の物を使うように注意してください。同じデータベース名を指定すると、データベースが消去されます。
$ bash bin/install-wp-tests.sh wordpress_test root wordpress 127.0.0.1 latest
テストケースを作成する
サンプルのテストケースをコピー、またはリネームしてテストを作成します。 test-sample.php
については PHPUnit の設定で除外されているため、ここに書かれたテストは実行されませんので注意してください。具体的なテストの書き方(テスト対象の設定やテストの粒度の設計)については、この記事では割愛します。
$ mv ./tests/test-sample.php ./tests/test-kunoichi.php
テストを実行する
PHPUnit を使ってテストを実行します。デフォルトの設定のまま実行できます。
$ phpunit
Installing...
Running as single site... To run multisite, use -c tests/phpunit/multisite.xml
Not running ajax tests. To execute these, use --group ajax.
Not running ms-files tests. To execute these, use --group ms-files.
Not running external-http tests. To execute these, use --group external-http.
PHPUnit 5.6.0 by Sebastian Bergmann and contributors.
. 1 / 1 (100%)
Time: 3.35 seconds, Memory: 30.00MB
OK (1 test, 1 assertion)
テストが実行されました。
CI との連携設定を行う
テーマを GitHub にプッシュしておきます。
$ git add .
$ git commit -m"Add CI integration."
$ git push origin master
CircleCI のダッシュボードに移動し、ADD PROJECTS
のタブに移動します。
Kunoichi Theme が正しく GitHub にアップロードされている場合、そのリポジトリ名を検索して見つけることができるはずです。
Kunoichi Theme を選択すると詳細な設定画面に遷移します。今回は wp-cli を使って CI の設定を行ったため、このダッシュボード上での設定は不要です。
START BUILD
のボタンを押すとビルドが始まります。
ジョブのキューに入ったものから順に実行されているのがわかります。各ジョブをクリックするとログを確認することができます。緑色になったらテスト成功です。
CD 設定を行う
CI でのテストが成功した後に、ファイルの転送などの処理を行いたい場合があります。プロダクション環境などの特定のサーバーや、GitHub の特定のブランチ (例えば release
など)へのテーマのアップロードができればとても便利です。そのための方法について解説します。このようなデプロイの方法を CD (継続的デリバリ)などと呼ぶことがあります。GitHub のデプロイキーや、プロダクションサーバーにアクセスできる秘密鍵を CircleCI に埋め込むことでファイルをサーバーに転送することができます。
この項では、GitHub のデプロイキーを CircleCI に渡して GitHub に書き込みアクセスをする例を示します。
GitHub のデプロイキーを作成する
PEM 形式でデプロイキーを作成します。パスワードは無しで設定します。
$ ssh-keygen -t rsa -b 4096 -m pem -f circle_deploy
秘密鍵 circle_deploy
と公開鍵 circle_deploy.pub
という鍵ペアが生成されました。
重要 特に秘密鍵の circle_deploy
は当該リポジトリに無制限に書き込みを行うことができる権限があるため、取り扱いに注意してください。プライベートリポジトリ出会ってもコミットしないほうがいいでしょう。
秘密鍵を CircleCI に登録する
秘密鍵は CircleCI の PERMISSIONS
-> SSH Permissions
から埋め込むことができます。Hostname
には github.com
を指定します。また、Private Key
に秘密鍵を転写します。ここで表示される Fingerprint
(aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99
のような値)は後で利用しますので控えておいてください。
公開鍵を GitHub に登録する
公開鍵は、 GitHub のリポジトリの settings
-> deploy keys
から追加できます。Key
に秘密鍵を転写し、Allow write access
にチェックを入れて Add key
をクリックします。
CircleCI から GitHub にアクセスする
.circleci/config.yml
に以下の記述を追加します。
# 以下の設定を workflows.main.jobs に追加
- deploy:
requires:
- php56-build
# master へのコミットに対してのみ発火させる
filters:
branches:
only: master
# jobs['php-56'].steps の最後に追加
# インデントに注意
- persist_to_workspace:
root: .
paths:
- .
# jobs にデプロイ用のジョブを追加
# <username> <fingerpring> は各自の環境に合わせて書き換えてください
deploy:
docker:
- image: circleci/php:5.6
steps:
- attach_workspace:
at: .
# 以下は GitHub の当該リポジトリに release というブランチを作ってプッシュするコマンド
- run: rm -rf .git .circleci bin tests .phpcs.xml.dist phpunit.xml.dist
- run: git config --global user.name "circleci"
- run: git config --global user.email "<username>@users.noreply.github.com"
- run: git init
- run: git add .
- run: git commit -m"Circle deploy"
- run: git checkout -b release
- run: git remote add origin git@github.com:<username>/kunoichi-theme.git
# SSH鍵を使う直前に add_ssk_keys というステップでどの SSH 鍵を使うかを指定してください
- add_ssh_keys:
fingerprints:
- "<fingerprint>"
- run: git push -f origin release
以上を踏まえた .circleci/config.yml
の全体は次のようになります。必要に応じて書き換えてください。
workflows:
version: 2
main:
jobs:
- php56-build
# - php70-build
# - php71-build
# - php72-build
- deploy:
requires:
- php56-build
filters:
branches:
only: master
version: 2
job-references:
mysql_image: &mysql_image circleci/mysql:5.6
setup_environment: &setup_environment
name: "Setup Environment Variables"
command: |
echo "export PATH=$HOME/.composer/vendor/bin:$PATH" >> $BASH_ENV
source /home/circleci/.bashrc
install_dependencies: &install_dependencies
name: "Install Dependencies"
command: |
sudo apt-get update && sudo apt-get install subversion
sudo -E docker-php-ext-install mysqli
sudo sh -c "printf '\ndeb http://ftp.us.debian.org/debian sid main\n' >> /etc/apt/sources.list"
sudo apt-get update && sudo apt-get install mysql-client-5.7
php_job: &php_job
environment:
- WP_TESTS_DIR: "/tmp/wordpress-tests-lib"
- WP_CORE_DIR: "/tmp/wordpress/"
steps:
- checkout
- run: *setup_environment
- run: *install_dependencies
- run:
name: "Run Tests"
command: |
composer global require "phpunit/phpunit=5.7.*"
composer global require wp-coding-standards/wpcs
phpcs --config-set installed_paths $HOME/.composer/vendor/wp-coding-standards/wpcs
phpcs
rm -rf $WP_TESTS_DIR $WP_CORE_DIR
bash bin/install-wp-tests.sh wordpress_test root '' 127.0.0.1 latest
phpunit
WP_MULTISITE=1 phpunit
jobs:
php56-build:
<<: *php_job
docker:
- image: circleci/php:5.6
- image: *mysql_image
steps:
- checkout
- run: *setup_environment
- run: *install_dependencies
- run:
name: "Run Tests"
command: |
composer global require "phpunit/phpunit=5.7.*"
composer global require wp-coding-standards/wpcs
phpcs --config-set installed_paths $HOME/.composer/vendor/wp-coding-standards/wpcs
phpcs
SKIP_DB_CREATE=false
rm -rf $WP_TESTS_DIR $WP_CORE_DIR
bash bin/install-wp-tests.sh wordpress_test root '' 127.0.0.1 latest $SKIP_DB_CREATE
phpunit
WP_MULTISITE=1 phpunit
SKIP_DB_CREATE=true
rm -rf $WP_TESTS_DIR $WP_CORE_DIR
bash bin/install-wp-tests.sh wordpress_test root '' 127.0.0.1 trunk $SKIP_DB_CREATE
phpunit
WP_MULTISITE=1 phpunit
SKIP_DB_CREATE=true
- persist_to_workspace:
root: .
paths:
- .
php70-build:
<<: *php_job
docker:
- image: circleci/php:7.0
- image: *mysql_image
php71-build:
<<: *php_job
docker:
- image: circleci/php:7.1
- image: *mysql_image
php72-build:
<<: *php_job
docker:
- image: circleci/php:7.2
- image: *mysql_image
deploy:
docker:
- image: circleci/php:5.6
steps:
- attach_workspace:
at: .
- run: mkdir -p ~/.ssh
- run: echo -e "Host github.com\n\tStrictHostKeyChecking no\n" > ~/.ssh/config
- run: rm -rf .git .circleci bin tests .phpcs.xml.dist phpunit.xml.dist
- run: git config --global user.name "circleci"
- run: git config --global user.email "<username>@users.noreply.github.com"
- run: git init
- run: git add .
- run: git commit -m"Circle deploy"
- run: git checkout -b release
- run: git remote add origin git@github.com:<username>/kunoichi-theme.git
- add_ssh_keys:
fingerprints:
- "<fingerprint>"
- run: git push -f origin release
PHP5.6 でのテストが成功した際に GitHub の release ブランチにコードをプッシュする設定になっています。また、プッシュに先立って本番環境での動作には不要なファイルを削除しています。この処理は別のものに置き換えたり追加したりすることが可能です。例えば次のような処理です。
-
npm run build
のようなコマンドを使って Gulp でアセットファイルをビルドする scp
やrsync
などのコマンドを使って特定のサーバーにファイルを転送する
このような CI の設定変更を含むコミットを master にプッシュすると、追加された Workflow が以下のように発火します。
deploy
のジョブが成功すると、GitHub に release というブランチが作成され、release ブランチへのコミットが GitHub プッシュされます。
これで GitHub の release ブランチを使ったリリースができました。
終わりに
今回は master ブランチへのコミットに対してCDを行う設定を試しました。CircleCI は柔軟なワークフローの制御を設定することができ、例えば v1.2.3
のような Git のタグに対してデプロイを発火させるような設定も可能です。詳細は CircleCI のドキュメントをご覧ください。