💰

[WordPress] GitHubでテーマをビルドし、リリース経由で更新させるワークフロー

2023/04/03に公開

WordPress界隈においては 「テーマだけGitHubで管理したいが、FTPやSSHを使えない」 というニッチ需要があり、「WP Pusher」なるプラグインが販売されている。「普通にCIでSSHしてクローンしろや」という話だが、テーマだけ委託された場合にSSHを渡せない場合もままあるんだよ。

だが、WP Pusherは正直高すぎ。 プライベートリポジトリの使用に年額99ドル請求するという強気の価格設定になっている。

代わりを探していたら、「GitUpdater」というめちゃくちゃググりにくい名前のプラグインを見つけた。今回は、GitHub Actionsと組み合わせることで、GitHubトークンだけを使ったテーマの更新をしてみる。

この記事でやること

GitHubでリリース時にWebhookを発行し、GitUpdaterのAPIを叩くことで、テーマを自動更新する。ただ、プラグインの仕様が独特なので、詳しく解説していく。

ステップ1. 事前準備

テーマのstyle.cssに情報を追加

style.css
/**
(...前略)
+ GitHub Theme URI: https://github.com/ユーザー名/リポジトリ
+ Primary Branch: main
+ Release Asset: true
 */

ドキュメントによると、GitUpdaterプラグインを動作させるため、テーマに上記の情報が必要。

https://zenn.dev/temasaguru/articles/a2ebd6a6fde5a1

なお、リポジトリURL等の挿入は上記の方法で自動化できる。

上記の情報を書かないと、REST APIにテーマが認識されない。

GitUpdaterのインストール

https://git-updater.com/git-updater/

WP Pusher同様zip配布されている。インストール、有効化、ライセンスを購入してアクティベート。支払いはFreemiusという業者が仲介するので、あまり見掛けない画面で戸惑うかもしれない。

GitHubトークンの取得

特定のリポジトリのみの権限を付与するため、Fine-Grainedトークンを使う。

https://github.com/settings/tokens?type=beta

リポジトリを選択し、Repository Permissionsのうち以下の権限を付ければ良い。

なお、Classic Tokensと違って有効期限が必須なので注意。

一度しか見れないのでパスワード管理ツール等への保存を推奨する。

GitUpdaterにトークンを設定

サイドバー → GitUpDater → GitHubからトークンを設定する。

その後、style.cssを更新したテーマを、手動で追加してみてほしい。 プラグインがテーマを認識するか確認して、もし認識しなければstyle.cssを修正すること。

リモート用APIキーの保存

このプラグインは、REST APIで操作が行えるようになっている。

APIキーの取得

「Remote Management」から、GitUpdaterのAPIキー を取得できる。これは後で使う。

ステップ2. リリース時にWebhookを飛ばす設定

リポジトリのWebhook設定で、以下のようなURLを設定する。

https://example.com/wp-json/git-updater/v1/update/?key=<GitUpdaterのAPIキー>&theme=<テーマ名>&override=true
  • key: GitUpdaterのAPIキー。ヘッダに持たせる仕様ではないため、GitHub側が用意したシークレット欄は使わない。
  • theme: テーマ名。
  • override=true: Webhook以外でテーマを更新したりすると、次回更新時に「現在のブランチ指定と違う」とか言われる。これを付けることで、確実にテーマを更新する。


プッシュを外すのを忘れずに
プッシュを外すのを忘れるな!

Let me select individual events.にチェックし、Pushesを外してReleasesを選ぶ。 なぜプッシュではいけないかというと、アセットをビルドする前提で作っているから。

自分でAPIを叩くな

GitHubのWebhookでないと、どのリリースをダウンロードするか伝わらない。 その結果、リポジトリをクローンしてしまい、CSSが欠損してしまう。 WordPressで「壊れたテーマ」として扱われないよう、絶対にAPIを自分で叩かないこと。

ステップ3. GitHub Actionsでリリースを作りテーマを更新

上記の流れを実装する。リリースの作成も自動化するのがポイント。

謝辞

https://kunoichiwp.com/faq/1621

タグがついている場合にリリースを作成するCIについて、当初は上記の記事を参考にさせていただきました。しかしアクションがメンテされていなかったり、当時と違ってvariable機能があることなどから、大幅に変えています。

ワークフロー用変数の設定

Repository variablesに以下を設定する。

  • THEME_NAME: テーマ名。

また、リリースを作成するために、Workflow permissionsにRead and write権限が必要

ワークフローの作成

そして、以下のようなワークフローを用意する。

例として、yarn buildでCSSが書き出されるとし、必要な手順を踏んでいる。実際はComposerの用意やPHPのテストとかも必要になってくるだろう。

.github/workflows/publish.yml
on:
  push:
    branches:
      - 'main'
    tags:
      - 'v*'
    # 以下のifと二重チェックしないと多重起動してしまう
jobs:
  # タグが付いているならリリースする
  release:
    name: テーマのビルドとリリース
    if: contains(github.ref, 'tags/') # タグがついている場合のみ
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0 # 差分取得のため全履歴が必要

      # composer installやPHPのテスト等も適宜設定する。長くなるので今回は省略
      # - name: Setup PHP
      #   uses: shivammathur/setup-php@v2
      #   with:
      #     php-version: 7.2
      #     tools: composer
      #   env:
      #     GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Nodeセットアップ
        uses: actions/setup-node@v3
        with:
          node-version: '16'
          cache: 'yarn'

      - name: Node依存インストール
        id: node_install
        run: yarn --check-files --frozen-lockfile --non-interactive

      - name: CSSビルド
        id: build
        run: yarn build

      - name: 不要ファイル削除
        id: cleanup
        # 以下は全てテーマの動作に不要なファイル。適宜変更するか別スクリプトに書いたほうが良さげ
        run: |
          rm -rf .git
          rm -rf .github
          rm -rf ./node_modules

      - name: zip作成
        # テーマ名-タグ名.zipというファイル名が必須 https://git-updater.com/knowledge-base/required-headers/
        run: zip -r ${{vars.THEME_NAME}}-${{github.ref_name}}.zip ./

      - name: リリース作成
        id: create_release
        uses: softprops/action-gh-release@v1
        with:
          body: |
            `.github/workflows/publish.yml` により自動更新
          files: |
            ${{vars.THEME_NAME}}*.zip
          draft: false
          prerelease: false
          append_body: true

上記のようなジョブを設定する。

注意として、タグをプッシュしなければ動作しない。

これは、GitUpdaterのリリースファイル検知機能が、テーマ名-タグ名.zip というファイル名しか受け付けないからである。(ソース)

リリース

タグ付きでプッシュすると、softprops/action-gh-releaseにより、上記のようなリリースが自動で作成される。

{
  "action": "published",
  "release": {
    "url": "https://api.github.com/repos/temasaguru/theme-hoge/releases/XXXXXXXX",
    // 中略
    "assets": [
      {
        "url": "https://api.github.com/repos/temasaguru/theme-hoge/releases/assets/XXXXXXXX",
        "id": XXXXXXXX,
        "node_id": "RA_kwDOJJgDic4GGzU8",
        "name": "theme-hoge-v4.7.8.zip",
        // 後略

するとREST APIへ上記のようなWebhookが飛び、

{
  "success": true,
  "data": {
    "messages": [
      "Downloading update from <span class=\"code\">https://objects.githubusercontent.com/github-production-release-asset-XXXresponse-content-disposition=attachment%3B%20filename%3Dtheme-hoge-v4.7.8.zip&amp;response-content-type=application%2Foctet-stream</span>&#8230;",
      "Unpacking the update&#8230;",
      "Installing the latest version&#8230;",
      "Removing the old version of the theme&#8230;",
      "Theme updated successfully."
    ],
    "webhook": {
      "key": "APIキー",
      "theme": "theme-hoge",
      "override": "true",
      "webhook_source": "GitHub webhook"
    },
    "elapsed_time": "2959.99 ms",
    "deprecated": false
  }
}

リリースのzipがダウンロードされ、テーマが更新される。

テーマのstyle.cssをignoreしていると、リリースがガン無視される。 先述したが、GitHub上のファイルを設定に使う仕様のため。

Discussion