Github から WordPress のテーマを自動更新するとめちゃくちゃ快適だった。

今更ですが、このブログのテーマはGithubに公開されています。

レポジトリ: torounit/torounit2015

当然、開発とかも GitHub 上で行っているのですが、とにかくデプロイが面倒くさいんです。

正直 Typo の修正程度で、FTPとか、rsync とか VCCW を立ち上げて WordMove とかってしたくないんですよね。FTP とかをアプリからやったりすると、たまに間違ったサーバーにつないでるのに気づかないで別の環境を上書きするなんて事故も起きかねない。

というわけで、デプロイ自動化というのは人類共通の課題だったりするわけです。

Sass を使ったり、ES6 でバベったりしていたりもするので、単純に GitHub で Webhookして git pull すれば良いということでもない。。。。サーバー側で node.js とか gulp とかインストールするのも面倒ですし。

というわけで、Travis CI と WP Pusher を使って、テーマの自動ビルド・自動デプロイ環境を構築しました!

完成図

図にするとこんな感じです。

gethub-deploy-theme

処理の流れとしては、

  1. 開発マシンから GitHub 上の レポジトリの master ブランチへ push
  2. Github が Travis CI に通知
  3. Travis CI がビルドを行い、dist ブランチへ push
  4. Github が WordPress サイトへ通知
  5. WordPress が dist ブランチからテーマを取得、更新

となります。

設定さえしてしまえば、GitHub 上のレポジトリに push するだけで、テーマの更新が反映されます。とても楽ちん。便利。

ビルドタスクで、サーバーに展開するテーマファイルをつくる

何はともあれ、まずは gulp でテーマをビルドするタスクを作成します。テーマファイルの直下に、dist という名前のディレクトリにビルド済みのテーマファイル一式が展開されるようにします。

bulid:dist タスクで、CSS とか JS は assets/dist の中にコンパイルされるものとします。ここら辺は環境や好みで書き換えてください。

'use strict';

var gulp = require('gulp');
var runSequence = require('run-sequence');

gulp.task('copy', function() {
    return gulp.src(
            [
                './**/*.php',
                './assets/dist/**',
                './style.css',
                "!./dist/**",
                "!./node_modules/**/*.*"
            ],
            { base: './' }
        )
        .pipe( gulp.dest( 'dist' ) );
} );
gulp.task('build:dist',function(){
    /* ここで、CSS とか JS をコンパイルする */
});

gulp.task('dist', function(cb){
    return runSequence( 'build:dist', 'copy', cb );
});

これで、 dist ディレクトリにテーマの一式がコピーされました。

また、これを、package.json に指定しておくと、gulp が グローバルにインストールされていなくても

$npm run dist

で実行できるようになります。便利。

{
  "scripts": {
    "dist": "gulp dist"
  }
}

Travis CI で自動的にビルドタスクを実行してみる

Travis CI とは

travis-ci-logo-light-bg

Travis CI の CI は Continuous Integration の略で、和訳すると、継続的インテグレーションといいます。

継続的インテグレーションCI: continuous integration)とは、主にプログラマーアプリケーション作成時の品質改善や納期の短縮のための習慣のことである。

継続的インテグレーション – Wikipedia

自動ビルドとかテスト自動化などはこの取り組みの一つです。

Travis CI はそれをサポートするサービスです。似たようなサービスに Circle CI とか Magnum CI なんかがあります。

インストール型だと、Jenkins がめちゃくちゃ有名ですね。

これを使うと、GitHub のコミットを監視して、指定したコマンドを自動的に実行することができます。めちゃくちゃ便利。

Travis CI とレポジトリの連携の設定

https://travis-ci.org にアクセスして、Sign Up をクリックして、その後は手順に従っていけばサインインできます。

サインインできたら、右上のユーザーメニューのなかに Accounts という画面がでてきますので、そこで、レポジトリと Travis CI の連携をセットアップします。といっても1クリックで終わります。レポジトリを選択してボタンを押すだけです。

travic-ci-accounts

 

その後、レポジトリ直下に .travis.yml というファイルを作ってください。そこに以下のような内容を記述すると、コミット時にタスクが実行されます。

language: php

sudo: false

php:
  - "5.6"

before_script:
  - nvm install 4.2
  - npm install

script:
  # Search for PHP syntax errors.
  - find . \( -name '*.php' \) -exec php -lf {} \;


after_success:
  # Run npm build task.
  - run npm dist

実行状況は、https://travis-ci.org/ユーザー名/レポジトリ名 で確認できます。要は、GitHub のレポジトリのURLのドメインが、travis-ci.org になったやつです。

torounit/torounit2015 – Travis CI で僕のレポジトリは確認できます。

Travis CI からレポジトリにアップロード用のテーマを作成する

Travis CI でビルドタスクが自動実行されるようになりましたが、実行後にデータが破棄されてしまうので、これをどこかに保存する必要があります。今回は、GitHub Pages みたいに、空のブランチを作成して、そこに push するようにします。

dist ブランチの作成

レポジトリのあるディレクトリに移動して以下のコマンド実行してください。

git checkout --orphan dist
git rm -rf .
touch .gitkeep
git add .
git commit -a -m "dist branch init"
git push origin dist

参考:Creating Project Pages manually – User Documentation

その後、GitHub でレポジトリを確認すると、dist ブランチが作成されているはずです。

GitHubへのアクセストークンの取得

GitHub のレポジトリへのコミットをするのですが、当然ながら認証が必要です。なのでアクセストークンを使って認証します。

Github の Personal Access Tokens にアクセスして、「Generate access token」をクリックしてください。 適当な名前をつけて、「Generate token」をクリックすると、トークンが表示されますので、とりあえずどこかにコピーでもしておいてください。

ページ遷移したり、更新したりすると、2度と表示されないので気をつけてください。また、外部に漏れないように厳重に管理してください。

僕は管理するのが面倒なので、アプリケーションごとに生成しています。

このアクセストークンを使うと、

git push "https://${トークン}@github.com/${オーナ名/レポジトリ名}" dist

みたいな感じで push がデキるようになります。

トークンの暗号化

トークンを厳重に管理しろと言いましたが、これだと平文で .travis.yml に記述することになって大変まずいことになります。そこで、travis には、変数を暗号化する仕組みがあるのでそれを使います。公式の gem がありますのでそれをインストールしてください。Ruby が入ってない Windows の人は頑張ってRuby を入れましょう。

gem install travis

それができたら、以下のコマンドを適宜読み替えて、暗号化して下さい。

travis encrypt -r オーナ名/レポジトリ名 "GH_TOKEN=トークン"

実行すると、

secure: "なんか文字列いっぱい"

みたいな格好でこれを .travis.yml に記述してくださいと言われるので、以下のような感じで記述します。

ついでに Git で使うパラメーターも追記します。

language: php

sudo: false

php:
  - "5.6"

env:
  global:
    - GIT_COMMITTER_NAME=travis-ci
    - GIT_COMMITTER_EMAIL=Githubに出るメールアドレス
    - GIT_AUTHOR_NAME=travis-ci
    - GIT_AUTHOR_EMAIL=Githubに出るメールアドレス
    - secure: "なんか文字列いっぱい"

before_script:
  - nvm install 4.2
  - npm install

script:
  # Search for PHP syntax errors.
  - find . \( -name '*.php' \) -exec php -lf {} \;

after_success:
  # Run npm build task.
  - run npm dist

また、

travis encrypt -r オーナ名/レポジトリ名 "GH_TOKEN=トークン" --add

のように –add オプションをつけると勝手に .travis.yml に追加してくれます。

Githubにコミットする

このまま、after_success にコマンドを追記していくと面倒なので、bin/deploy.sh というファイルを作成して、そこで コミットをするようにします。

after_success:
  - bash ./bin/deploy.sh

bin/deploy.sh の中身はこんな感じ。

#!/usr/bin/env bash

set -e

git clone -b dist --quiet "https://github.com/${TRAVIS_REPO_SLUG}.git" dist
npm run dist
cd dist
git add -A
git commit -m "Update from travis $TRAVIS_COMMIT"
git push --quiet "https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git" dist 2> /dev/null

$TRAVIS_REPO_SLUG で オーナー名/レポジトリ名 が取得できます。https://github.com/torounit/torounit2015.git であれば、torounit/torounit2015 が取得できると言うことですね。また、最後の 2> /dev/null とかを忘れると、見えちゃいけないものが公開されたりで偉いことになります。

これで完成!と言いたいところですが、このままだと、開発中の機能のブランチも勝手に反映されたり、プルリクエストも反映されてしまったりといろいろ地獄です。

そんなわけで、プルリクエストの場合と、master ブランチ以外へのコミットの場合を除外します。

#!/usr/bin/env bash

set -e

if [[ "false" != "$TRAVIS_PULL_REQUEST" ]]; then
    echo "Not deploying pull requests."
    exit
fi

if [[ "master" != "$TRAVIS_BRANCH" ]]; then
    echo "Not on the 'master' branch."
    exit
fi

git clone -b dist --quiet "https://github.com/${TRAVIS_REPO_SLUG}.git" dist
npm run dist
cd dist
git add -A
git commit -m "Update from travis $TRAVIS_COMMIT"
git push --quiet "https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git" dist 2> /dev/null

これで自動ビルドの完成!

WordPress に自動デプロイする

自動ビルドの設定が終わったので後はもう一息! GitHub の WebHookを利用して、dist ブランチに変更があったときに、WordPressのテーマを更新させましょう。

今回は、WP Pusher というプラグインを使います。ちなみに Giploy というプラグインでも同じようなことは出来るはず。

WP Pusherの設定

WP Pusher のページに飛んで、Try WP Pusher のボタンをたたいて、Download のボタンを押すと、メールアドレスを聞かれるので、おとなしく入力するとダウンロードリンクがメールで飛んできます。

それをダウンロードしてインストールしてください。

すると、サイドバーにWP Pusher というメニューが出来ます。レポジトリ名とブランチを正しく入力すればOKです。Push-to Deploy にチェックを入れると自動デプロイ機能が有効になります。

screencapture-torounit-com-wp-admin-admin-php

こんな感じです。その後 Install theme をクリックすると、テーマがインストールされます。

このままでも、管理画面からテーマが更新できるようになります。

Web Hookの設定

screencapture-torounit-com-wp-admin-admin-php-1453287725198

WP Pusher の Themes メニューを開くと、現在このプラグインが管理しているテーマが表示されます。そこの、 Push-to-Deploy URL に表示されている URL をコピーしてください。

そして、GitHub の レポジトリの Settings 内にある Webhooks & Services から Add Webhook してください。

そしたら、Payload URL という項目があるので、先ほどの Push-to-Deploy URL を入力して、保存して下さい。

screencapture-github-com-torounit-torounit2015-settings-hooks-new-1453288236465

以上で、自動デプロイの設定は完了です。お疲れ様でした。

プラグインとかも同じ流れでデプロイできるので、これでよりよい CI 環境がWordPressでも簡単に構築できます!

テーマの自動デプロイなどが出来ると FTP などのアップロード作業から解放されるので、かなり快適に開発を進めることが出来ますよー。Typo とかは GitHub 上から直したり出来るので、スマホから直したりとかもできて非常に便利。

ただ、面倒なのは WP Pusher が公式ディレクトリにないのでそれがちょっと面倒です。

プライベートレポジトリとかの機能を削ったバージョンを上げてくれないかなぁ。。。。