⏲ Nuxt.js + WP REST API のサイトで記事を保存したら、GitHub Actions経由で自動デプロイされるように設定する

2020-12-30 #Development

令和の世も引き続き WordPress のお世話になる事が多そうなので、そろそろ WP REST API や Jamstack にも触れておかないとと思って最近ちょこちょこと触ってみていたのですが、一段落したので、所感と合わせてメモ。

下記みたいな流れで記事の保存後のデプロイまでの処理を自動化します。

  1. WordPress で記事を保存すると、function.php が Github Actions を動かす
  2. Github Actions で Nuxt.js を動かして(1 で記事を保存した WordPress の WP REST API を参照して)静的なファイルをビルドする
  3. あとは dist のディレクトリを本番のサーバーと Rsync したり、Slack に通知したりする

Github Actions を作成する

まずは外から Github Actions を呼び出すために repository_dispatch を設定します。

name: After saving wordpress

on:
  repository_dispatch:
    type: after_saving_wordpress

env:
  BASE: "main"

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout "${{ env.BASE }}"
        uses: actions/checkout@v2
        with:
          ref: "${{ env.BASE }}"
      - name: Build Site
        run: |
          yarn
          yarn generate          
      - name: Rsync deployments
        id: deploy
        uses: Pendect/action-rsyncer@v1.1.0
        env:
          # https://github.com/[user]/[repo]/settings/secrets/actions に公開鍵を保存しておく
          DEPLOY_KEY: ${{ secrets.SSH_KEY }}
        with:
          flags: "-avzr --delete"
          ssh_options: "-p 2222"
          # nuxtからgenerateされたファイルが入っているディレクトリ
          src: "dist/"
          # 公開用のサーバーのディレクトリのパス
          dest: "xxx:web/xxx.xxx.com"
      - name: Slack Notification
        uses: rtCamp/action-slack-notify@v2.0.0
        env:
          # https://github.com/[user]/[repo]/settings/secrets/actions にSlackのWebhookのURLを保存しておく
          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
          SLACK_COLOR: "#9CDAF0"
          SLACK_TITLE: Production URL
          SLACK_MESSAGE: "https://xxx.xxx.com/ 🌏"

curl で一度動かしてみる

push したらちゃんと動いているかどうかを curl で叩いて動かしてみます。

<token>https://github.com/settings/tokens で作成 )

curl \
  -X POST \
  -H "Authorization: bearer <token>” \
  -H "Accept: application/vnd.github.v3+json" \
  -d '{"event_type": "after_saving_wordpress"}' \
  https://api.github.com/repos/[user]/[repo]/dispatches

投稿保存時に functions.php から Github Actions を動かす

webhook.php(functions.php に読み込む):

<?php

function after_saving_wordpress($post_id, $post)
{
  if ($post->post_status === 'publish') {
    $url = 'https://api.github.com/repos/[user]/[repo]/dispatches';
    $headers = [
      'Authorization: bearer <token>’,
      'Accept: application/vnd.github.v3+json',
      'User-Agent: after_saving_wordpress'
    ];
    $data = [
      'event_type' => 'after_saving_wordpress',
    ];

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $output = curl_exec($ch);
    curl_close($ch);
    return true;
  }
  return false;
}
add_action('publish_post', 'after_saving_wordpress', 10, 2);
add_action('delete_post', 'after_saving_wordpress', 10, 2);

?>

所感

カテゴリトップなんかを含めて全部で 50 ページくらいあるサイトを使用してみて、Github 上でビルドしてレンタルサーバー に Rsync するまでだいたい 3 分くらいかかりました。これは記事が増えていくと結構大変なのかもしれない…

また、プレビュー画面が使えなくなるので代わりにステージング環境を用意するとなると、本番公開のための別の仕組みを間に一つ入れなければならなくなりそうで(もはや自動デプロイとは言えなさそう)、なんとも悩ましいところです…

個人事業という立場上サイトを構築した後に自分の手を離れていく事もしばしばあるのですが、後々のお客さんの運用・管理面も含めた利便性も考えると、実際の案件で採用するのには(ケースによると思いますが)まだ慎重に考える必要がありそうな感じがしました。

Profile
😛

石原 悠 / Yu Ishihara

デザインとプログラミングとヨーグルト作りが好きです。