1. 経緯
きっかけはWordCamp Tokyo 2019で以下のセッションを聞いたことと、スポンサーブースで「マネージドクラウド」や「静的サイトへの変換」のソリューションが印象に残ったことです。- セッション:
- スポンサー:
2. Ususamaについて
Ususamaについては以下を参照。 改めてざっくり説明すると「中小規模の静的サイト用にあれこれを準備するフレームワーク」というところです。主な機能として以下が挙げられます。- Gulpでejs, Scssをコンパイル+minify、JSはminify、画像圧縮
- Bootstrap4をテンプレートとして使用
- 標準で新着情報管理の仕組みをサポート
- 個別記事ページ: 1つのMarkdownファイルから1つのhtmlファイルを
news/articles/
下に生成 - 新着情報一覧ページ:
bin/config/config.yml
のparam.news.newscount
で指定した件数を1ページ当たりの件数として、news/
下に生成
3. 改修内容・連携の全体像
今回は上述の新着情報をWordPressに託し、Github Actionをキックすることで自動ビルド・デプロイを行う仕組みとしました。大まかな流れを以下に記します。- WordPressで記事を公開・更新する
- アクションフックを使って、プラグインに設定されたパラメータをGithub ActionsのAPIに投げ付け、
repository_dispatch
イベントを起こす - Github ActionsでUsusamaの
.github/workflows/build_deploy.yml
に記述されたワークフローが実行される(ビルドとFTPによるデプロイ) - 3.の結果、指定されたサーバにビルドされた静的サイトがアップロードされ、閲覧できる状態になる
repository_dispatch
イベントです。
なお、簡略化のためWordPressに対して以下の条件を設けました。
- 利用方法:
- 新着情報はWordPressの「投稿」を利用
- WordPress自体はどこかのサーバにインストールして、通常と同じように使用
- 「投稿」の1記事を1つのhtmlファイルとする
- 一覧ページは上述と同じ設定情報で生成
- 新着情報はWordPressの「投稿」を利用
- 条件:
- 連携できるのは「投稿」のみ
- 画像はCDNを利用してWPサーバ外に配置するものとする(記事内に埋め込まれている画像の取得が上手くできなかったため)
- サイト内リンクは置換しない(記事URLを上手く置換できなかったため)
- Github Actionsとの連携のため、自前プラグインを1つインストール
4. 実験手順
a. Ususama
Ususamaをローカルにクローンして、以下の2つの設定を行います。- WPサイトのWP REST APIのURL(例:
https://wpsite.example.com/wp-json/wp/v2/posts
)をbin/config/config.yml
に記述 bin/config/plugins.yml
のWordPress連携のフラグをtrue
にする
.github/workflows/build_deploy.yml
の内容は以下の通りです。
.github/workflows/build_deploy.yml
name: BuildandDeploy
on: [repository_dispatch]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x]
steps:
- uses: actions/checkout@v1
- name: Run builds and deploys with ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: npm install, build, and deploy
run: |
npm i -D
npm run build
npm run tankai ${{ SECRETS.ftp_user }} ${{ SECRETS.ftp_password }} ${{ SECRETS.ftp_host }} ${{ SECRETS.ftp_remoteroot }}
上述した通り、肝はrepository_dispatch
イベントでワークフローが実行されるようにon: [repository_dispatch]
を記述しておくこと。単発なのでon: repository_dispatch
でも良かったかもしれません。
このコードをGithubの公開リポジトリにプッシュします。
b. Github
次にGithubの設定。まずリポジトリに対してGithub Actionsを有効にし、次にシークレットの設定。「Settings」→「Secrets」と進み、上述のワークフローで使用する4つのキーを設定します(該当サーバのFTP情報)。 次にPersonal access tokensの設定をします。Githubログイン状態で、右上のアカウントアイコンからメニューを開き、「Settings」を選択。
左側のサイドバーから「Developer settings」を選択。
続いて「Personal access tokens」を選択。
新規でトークンを発行してみたいと思います。「Generate new token」を選択。
トークンの権限を設定します。今回必要なのは
repo
の権限なので、そこにチェックを入れて、下の方のボタンで保存。
新しくトークンが発行されたので、これを控えておきます。 次はWordPressに移りたいと思います。
c. WordPress
今回は実験のため、デモのWordPressを建てて適当なコンテンツ(最近のWeb、IT関係のニュースまとめ)を流し込んでおきました。デモのWordPressサイトのトップ画面はこのような感じ。Twenty Twentyです。
このWordPressに自作のプラグインをzipをアップロードする形でインストールし、有効化します。 名前は利用するのがUsusamaなので仏教関係で、火をイメージさせ、かつ一説に「飲み込む」の単語から名前が付けられたのではないかとも言われている迦楼羅から「迦楼羅焔」。
プラグインを有効化するとサイドバーにメニュー(「迦楼羅焔設定」)が表示されるので、そこを選択。設定画面で該当リポジトリの情報(アカウント、リポジトリ名)と先ほど設定したPersonal access tokensを入力し、保存します。 これでWordPress側の準備も完了です。
5. 実験
以上の設定や改修を終えて、WordPressで記事を更新します。すると、想定通りGithub Actionsのワークフローが実行されます。少し時間はかかりますが、暫く待っていると
?Complete job
で完了しました。
シークレットで指定したサーバを閲覧すると……無事、WordPressの投稿データを新着情報として静的サイトがデプロイされました!
6. まとめ
以上の改修・手順で、無事に「Github Actionsを使ってWordPressの記事を静的サイトにデプロイ」という目標は達成できました。課題
課題として以下の点が挙げられます。主にWordPress周りですね。- Githubリポジトリのデータは、
repository_dispatch
イベントの場合はブランチ指定ができない- 開発用ブランチ(
master
にGithubのワークフロー設定YAMLファイルがないリポジトリ)でワークフローを記述しても上手く動かなかった
- 開発用ブランチ(
- Github Actions自体がまだベータ的な機能らしいので、本格的なプロダクトに使用するのはもう少し後の方が良いと思われる
- WordPressに制約が多い
- 「投稿」のデータしか使えない
- 固定ページの場合、テンプレートをどうするか?
- カスタム投稿タイプまで踏み込むと複雑になりそう……
- 画像はCDNにあることを前提としている
- サムネイル画像は良いが、投稿内に埋め込まれた画像の取得が上手く行かなかった(
srcset
の縮小画像までダウンロードする?など)
- サムネイル画像は良いが、投稿内に埋め込まれた画像の取得が上手く行かなかった(
- サイト内リンクは非対応
- パーマリンクを「投稿名」にして日本語で入力されると、静的htmlファイルも日本語にせざるを得ない……
- 現状は投稿ID+日付という形で回避
- このため、サイト内リンクのURLとの対応付けを逐一行う必要がある
- カテゴリ別アーカイブなど、個別記事以外のURLの場合は?
- などなど、色々考えなければならない
- 「投稿」のデータしか使えない
7. 備考
上ではWordPressのプラグイン(「迦楼羅焔」)をさらっと流してしまいましたが、やっていることは以下の通り。- 必要なGithubの情報を保存
publish_post
、delete_post
のアクションフックを利用して、記事を更新したり削除したタイミングでGithub Actionsのrepository_dispatch
イベントをキック
file_get_contents
関数で上手く行かなかったのでHTTPクライアントライブラリのGuzzleを使いました。
guzzleという英単語も「暴飲する、がつがつ食べる」といった意味のようなので、偶然ですが「食べる、飲み込む」関係のそれっぽい単語でまとまることになりました。
そもそもUsusama自体Gulpを使っていることから「飲む」イメージでネーミングしていますし。
8. 参考
Github Actions, CI
- GitHub アクションでワークフローを自動化する – GitHub ヘルプ
- GitHub Actionsのワークフロー構文 – GitHub ヘルプ
- Repositories | GitHub Developer Guide
- GitHubActionsのrepository_dispatchを試す – Qiita
- 新 GitHub Actions 入門 – 生産性向上ブログ