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

- リンク: https://torounit.com/blog/github-%e3%81%8b%e3%82%89-wordpress-%e3%81%ae%e3%83%86%e3%83%bc%e3%83%9e%e3%82%92%e8%87%aa%e5%8b%95%e6%9b%b4%e6%96%b0%e3%81%99%e3%82%8b%e3%81%a8%e3%82%81%e3%81%a1%e3%82%83%e3%81%8f%e3%81%a1%e3%82%83/
- 公開日: 2016-01-20T20:25:10+09:00
- 作成者: Toro\_Unit

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

レポジトリ: [torounit/torounit2015](https://github.com/torounit/torounit2015)

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

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

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

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

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

## 完成図

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

![gethub-deploy-theme](https://torounit.com/wp-content/uploads/2016/01/gethub-deploy-
theme.png)

処理の流れとしては、

 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 の中にコンパイルされるものとします。
ここら辺は環境や好みで書き換えてください。

    ```decode:true
    '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 が グローバルにインストールされ
ていなくても

    ```decode:true
    $npm run dist
    ```

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

    ```decode:true
    {
      "scripts": {
        "dist": "gulp dist"
      }
    }
    ```

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

### Travis CI とは

![travis-ci-logo-light-bg](https://torounit.com/wp-content/uploads/2016/01/travis-
ci-logo-light-bg.png)

[Travis CI](https://travis-ci.org/) の CI は Continuous Integration の略で、和訳
すると、継続的インテグレーションといいます。

> **継続的インテグレーション**、**CI**（[英](https://ja.wikipedia.org/wiki/%E8%8B%B1%E8%AA%9E):
> _continuous integration_）とは、主に[プログラマー](https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E)
> の[アプリケーション](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2)
> 作成時の品質改善や納期の短縮のための習慣のことである。
> —[継続的インテグレーション – Wikipedia](https://ja.wikipedia.org/wiki/%E7%B6%99%E7%B6%9A%E7%9A%84%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)

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

Travis CI はそれをサポートするサービスです。似たようなサービスに [Circle CI](https://circleci.com/)
とか [Magnum CI](https://magnum-ci.com/) なんかがあります。

インストール型だと、[Jenkins](https://jenkins-ci.org/) がめちゃくちゃ有名ですね。

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

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

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

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

![travic-ci-accounts](https://torounit.com/wp-content/uploads/2016/01/travic-ci-
accounts.png)

 

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

    ```decode:true
    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](https://travis-ci.org/torounit/torounit2015)
で僕のレポジトリは確認できます。

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

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

### dist ブランチの作成

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

    ```decode:true
    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](https://help.github.com/articles/creating-project-pages-manually/)

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

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

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

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

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

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

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

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

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

### トークンの暗号化

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

    ```decode:true
    gem install travis
    ```

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

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

実行すると、

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

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

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

    ```decode:true
    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
    ```

また、

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

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

### Githubにコミットする

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

    ```decode:true
    after_success:
      - bash ./bin/deploy.sh
    ```

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

    ```decode:true
    #!/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 ブランチ以外へのコミットの場合を除外
します。

    ```decode:true
    #!/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](https://wppusher.com/) というプラグインを使います。ちなみに 
[Giploy](http://takahashifumiki.com/web/programing/3075/) というプラグインでも同じ
ようなことは出来るはず。

### WP Pusherの設定

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

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

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

![screencapture-torounit-com-wp-admin-admin-php](https://torounit.com/wp-content/
uploads/2016/01/screencapture-torounit-com-wp-admin-admin-php.png)

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

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

### Web Hookの設定

![screencapture-torounit-com-wp-admin-admin-php-1453287725198](https://torounit.
com/wp-content/uploads/2016/01/screencapture-torounit-com-wp-admin-admin-php-1453287725198.
png)

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](
https://torounit.com/wp-content/uploads/2016/01/screencapture-github-com-torounit-
torounit2015-settings-hooks-new-1453288236465.png)

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

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

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

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

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