TL;DR (概要)
GitHub の Webhook を用いて、PullRequest が merge されたときに、WordPress の テーマを自動更新する設定です。
この設定をすることで、デザイナーが WordPressテーマを修正した際の、本番への反映の手間を大幅に削減でき、LPO等のサイトの改善がぐんぐん進むようになります。
背景
広報や採用担当でWebサイトを更新しやすくするために WordPress で、サイトを構築することがあります。この場合、サイトのデザインは、WordPress の テーマ を自作することで行います。 スタメンでは、テーマは、社内のWebデザイナーが作り Github で管理していますが、WordPress への 反映は、WordPress のファイル管理のプラグインである File Managerを用いいて、更新したファイルを手動でアップデートしていました。 この方法は、手間もかかるし、ミスも起きやすく、スマートではありません。 WordPress と Github との連携は、WP Pusher のようなサービスで実現できますが、テーマを Github の Private repository で管理していることもあり、それなりに費用がかかることもあり、Github Webhook を用いて自作してみることにしました。
Github で PulLRequest が Merge されたときに、WordPress に反映する手順
Git pull するための設定
まず、WordPress が稼働しているサーバーにて、Github リポジトリから git pull して、WordPress テーマを取得できるようにする必要があります。 Wordpress が稼働するサーバーにて、 OpenSSH の 鍵をつくります。
$ ssh-keygen -t rsa -f id_rsa_wordpress
生成された公開鍵を Github の Deploy Keys に設定します。
次に、httpd サーバー の実行権限で、git pull できるようにします。 これは、Github Webhook で WordPress が動作する PHP関数を呼び出しますが、WordPress は、apache ユーザーで動作しているため、apache ユーザーで git pull できないと テーマを更新することができないからです。 今回は、以下の内容の /home/apache/bin/git-ssh.sh をつくり、git pull 時に GIT_SSH 環境変数にて指定するようにしています。
#!/bin/sh ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -i /home/<user_name>/.ssh/id_rsa "$@"
git-ssh.sh では、下記の傾向メッセージが表示されて、git pull が失敗しないように、StrictHostKeyChecking を off にするなどのオプションをつけています。
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
以下のように、wordpress theme が存在する git repository で、git pull できれば準備は完了です。
$ sudo -u apache GIT_SSH=/home/apache/bin/git-ssh.sh git pull origin master From github.com:<theme repository> * branch master -> FETCH_HEAD Already up-to-date.
WordPress に action を追加
WordPress の wp_ajax_nopriv を利用することで、Github hook から任意のPHP関数を実行することができます。 wp_ajax_nopriv{$REQUEST[‘action’]} | Hook | WordPress Developer Resources 今回は、下記の関数を theme ディレクトリの functions.php に追加することで、https://your-wordpress-site/wp-admin/admin-ajax.php?action=wp_ajax_nopriv_update_theme にアクセスすれば、git pull されるようにします。
/** * Add deploy hook endpoint */ add_action('wp_ajax_nopriv_update_theme', 'update_theme_from_github'); function update_theme_from_github() { $secret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX"; $posted = file_get_contents('php://input'); if (empty($posted)) { return; } $signature = 'sha1='.hash_hmac('sha1', $posted, $secret); if ($_SERVER['HTTP_X_HUB_SIGNATURE'] !== $signature) { header('HTTP/1.1 403 Forbidden'); error_log('Signatures didn\'t match... '); return; } $json = json_decode($posted); error_log(__FUNCTION__.": \n".var_export($json, true)); if ($json->ref === 'refs/heads/master') { $git_root = dirname(__FILE__); exec("cd ${git_root} && GIT_SSH=/home/apache/bin/git-ssh.sh git pull origin master 2>&1", $out); error_log(join("\n", $out)); echo join("\n", $out); } else { error_log(__FUNCTION__.": nothing for ".$json->ref); } }
このとき、GitHub の Webhook の Secret 機能 を利用することで、GitHub の Webhook からのアクセス時のみ git pull するようにしています。 デバッグしやすいにように、 error_log で、webhook の payload を出力していますが、不要だったら消してください。
GitHub に Webhook を追加
あとは、テーマのリポジトリにて、Webhook を設定すれば、完成です。
まとめ
これまで、更新の際は、ファイルを一つ一つアップロードしていたのが、GitHub WebHook によって、git pull することで、PullRequest を Merge することで、WordPress に反映されるようになりました。 これによって、WordPress の更新の手間が大幅に減ったため、LPO などの細かい改善がより進むようになりました。また、GitHub Flow で WordPress テーマを更新するフローが確立したことで、個々の修正に対して、チームレビューが定着し、ノウハウの共有やミスの低減を達成することができました。 ほんと、嬉しいことだらけです! ただし、httpd が動作する権限で、git pull をするため、レンタルサーバーなどの社外含めた複数のアカウントが共存する環境では、セキュリティと Webhook による git pull は、共存できないかもしれません。その場合は、WP Pusher などのプラグインを入れましょう。
参考にしたサイト
WordPress テーマを Git 管理して自動デプロイする - Qiita GitHubのWebhookをPHPで受け取る練習 - tanaka's Programming Memo GitHubのWebhookをPHPで自作する時に書く検証コード - Qiita WordPress Git deployments with WP Pusher