WordPressテーマのCI/CDをGitHub Actionsで構築する
はじめに
この記事では、GitHub Actionsを活用したWordPressテーマのCI/CD構築について解説する。安全かつ効率的な運用を実現するための方法を紹介する。
背景:WordPress運用における課題
WordPressは手軽にブログやWebサイトを始められる便利なCMSだが、DevOpsの観点からはいくつかの課題がある。
- 開発環境、ステージング環境、本番環境の運用が煩雑になりがち。
- テーマファイルの管理が難しい。
- ファイルを直接編集するとバージョン管理ができない。
- etckeeperを使っても、ステージング環境と本番環境のファイルを同期するきれいな方法がない。
- バージョン管理ができない。
- 更新するたびにzipファイルを作成してアップロードするのは手間がかかる。
- DB内のデータ(記事、ページ)とファイル(プラグイン、テーマ、アセット)が密接に連携しているため、コードレベルでのスナップショットが取りづらい。
解決策:GitHub ActionsによるCI/CD
これらの課題を解決するために、GitHub Actionsを活用してWordPressテーマのCI/CDを構築する。
- テーマファイルをGitHubリポジトリで管理する
- GitHub Actionsで、developブランチへのpushをトリガーにステージング環境へデプロイする
- GitHub Actionsで、mainブランチへのpushをトリガーに本番環境へデプロイする
- CIでPHPの構文チェックを行い、本番環境でのエラーを未然に防ぐ
システム設計
このシステムでは、以下の要素を組み合わせてWordPressテーマのCI/CDを実現します。
- GitHubリポジトリ:テーマファイルのソースコードを管理する。
- GitHub Actions:CI/CDのワークフローを定義し、実行する。
- SSH:GitHub ActionsからWordPressサーバーへ安全にファイルを転送する。
- rsync:効率的にファイルを同期する。
設定手順
1. GitHubリポジトリの準備
まず、WordPressテーマのファイルをGitHubリポジトリに登録する。
2. GitHub Actionsのワークフロー設定
次に、GitHub Actionsのワークフローを設定する。
ステージング環境へのデプロイ
.github/workflows/deploy-staging.yml
name: Deploy to Staging
on:
push:
branches: [ develop ]
workflow_dispatch:
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: PHP Syntax Check
uses: ./.github/actions/php-syntax-check
deploy:
needs: test
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up SSH
uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY_STAGING }}
# known_hosts: ${{ secrets.KNOWN_HOSTS_STAGING }} # よりセキュアにする場合は有効化
- name: Ensure target theme directory exists on remote
run: |
SSH_HOST="${{ secrets.STAGING_SERVER_HOST }}"
SSH_USER="${{ secrets.STAGING_SERVER_USER }}"
THEME_PATH="${{ secrets.STAGING_THEME_PATH }}"
ssh -o StrictHostKeyChecking=no "${SSH_USER}"@"${SSH_HOST}" "mkdir -p \"${THEME_PATH}\""
- name: Rsync theme files to Staging
run: |
SSH_HOST="${{ secrets.STAGING_SERVER_HOST }}"
SSH_USER="${{ secrets.STAGING_SERVER_USER }}"
THEME_PATH="${{ secrets.STAGING_THEME_PATH }}"
rsync -avzc --delete --exclude='.*' --exclude README.md -e "ssh -o StrictHostKeyChecking=no" ./ "${SSH_USER}"@"${SSH_HOST}":"${THEME_PATH}"
このワークフローは、develop
ブランチへのpushをトリガーに、以下の処理を行う。
- コードをチェックアウトする
- PHPの構文チェックを行う
- SSHでWordPressサーバーに接続し、テーマファイルをrsyncで同期する
このrsyncを実行する際のオプションは重要である。特に重要なオプションを以下に示す。
-c
オプション:ファイルのチェックサムで比較を行い、同一ファイルであれば変更しない。GitHub Actionsでコピー元のファイルが準備される際、タイムスタンプがcheckout時のものになるため、更新日時がサーバと異なることを避けるために使用する。
-u
オプション:サーバに新しいファイルが存在する場合、上書きしない。今回はすべてのファイルを上書きするため、このオプションは使用しない。
--exclude
:機密情報を含まないように、ドキュメントやgit関連ファイルを除外する。
本番環境へのデプロイ
.github/workflows/deploy-production.yml
name: Deploy to Production
on:
push:
branches: [ main ]
workflow_dispatch:
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: PHP Syntax Check
uses: ./.github/actions/php-syntax-check
deploy:
needs: test
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up SSH
uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY_PRODUCTION }}
# known_hosts: ${{ secrets.KNOWN_HOSTS_PRODUCTION }} # よりセキュアにする場合は有効化
- name: Ensure target theme directory exists on remote
run: |
SSH_HOST="${{ secrets.PRODUCTION_SERVER_HOST }}"
SSH_USER="${{ secrets.PRODUCTION_SERVER_USER }}"
THEME_PATH="${{ secrets.PRODUCTION_THEME_PATH }}"
ssh -o StrictHostKeyChecking=no "${SSH_USER}"@"${SSH_HOST}" "mkdir -p \"${THEME_PATH}\""
- name: Rsync theme files to PRODUCTION
run: |
SSH_HOST="${{ secrets.PRODUCTION_SERVER_HOST }}"
SSH_USER="${{ secrets.PRODUCTION_SERVER_USER }}"
THEME_PATH="${{ secrets.PRODUCTION_THEME_PATH }}"
rsync -avzc --delete --exclude='.*' --exclude README.md -e "ssh -o StrictHostKeyChecking=no" ./ "${SSH_USER}"@"${SSH_HOST}":"${THEME_PATH}"
- name: Clear WordPress Cache
run: |
SSH_HOST="${{ secrets.PRODUCTION_SERVER_HOST }}"
SSH_USER="${{ secrets.PRODUCTION_SERVER_USER }}"
ssh -o StrictHostKeyChecking=no "${SSH_USER}"@"${SSH_HOST}" "wp w3-total-cache flush all"
release:
needs: deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Release Drafter
uses: release-drafter/release-drafter@v6
with:
publish: true
version: ${{ steps.version.outputs.version-without-v }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
このワークフローは、main
ブランチへのpushをトリガーに、以下の処理を行う。
- コードをチェックアウトする
- PHPの構文チェックを行う
- SSHでWordPressサーバーに接続し、テーマファイルをrsyncで同期する
- WordPressのキャッシュをクリアする
- リリースノートを自動生成する
PHP構文チェック
.github/actions/php-syntax-check/action.yml
name: PHP Syntax Check
description: Checks PHP syntax for errors.
runs:
using: "composite"
steps:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '7.4'
- name: Run PHP Syntax Check
shell: bash
run: |
find . -name "*.php" -print0 | xargs -0 -n1 php -l
このアクションは、PHPの構文チェックを行います。
リリースノート自動生成
.github/release-drafter.yml
name-template: 'v$RESOLVED_VERSION 🌈'
tag-template: 'v$RESOLVED_VERSION'
categories:
- title: '🚀 Features'
labels:
- 'feature'
- 'enhancement'
- title: '🐛 Bug Fixes'
labels:
- 'fix'
- 'bugfix'
- title: '🧰 Maintenance'
label: 'chore'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
version-resolver:
major:
labels:
- 'major'
minor:
labels:
- 'minor'
patch:
labels:
- 'patch'
default: patch
template: |
## Changes
$CHANGES
このファイルは、リリースノートの自動生成に関する設定を記述します。
3. GitHub Secretsの設定
GitHub ActionsからWordPressサーバーへSSH接続するために、GitHub Secretsを設定します。
-
SSH_PRIVATE_KEY_STAGING
: ステージング環境へのSSH接続に使用する秘密鍵 -
SSH_PRIVATE_KEY_PRODUCTION
: 本番環境へのSSH接続に使用する秘密鍵 -
STAGING_SERVER_HOST
: ステージング環境のホスト名 -
STAGING_SERVER_USER
: ステージング環境のユーザー名 -
STAGING_THEME_PATH
: ステージング環境のテーマファイルのパス -
PRODUCTION_SERVER_HOST
: 本番環境のホスト名 -
PRODUCTION_SERVER_USER
: 本番環境のユーザー名 -
PRODUCTION_THEME_PATH
: 本番環境のテーマファイルのパス
4. WordPressサーバーの設定
WordPressサーバーに、GitHub ActionsからWordPressサーバーへSSH接続できるように設定します。
- Wordpressを運用しているホストにはGithub Actionsからsshで接続できるようにしておく必要があります。
- Github actionsのIPアドレスの空間が膨大なのでligthsailだと制限をかけるのが不可能です。
- Github actionsのsource IP addressはAPIで公開されています。
sshキーペアの作り方はこんな感じです。生成された秘密鍵をGithub Actionsのsecretsに登録し、公開鍵をwordpressの.ssh/authorized_keysに追加します。
% ssh-keygen -t ed25519 -C "github-actions-staging@example.com" -f ~/.ssh/github_actions_deploy_key_staging
% ssh-keygen -t ed25519 -C "github-actions-production@example.com" -f ~/.ssh/github_actions_deploy_key_production
実行結果
GitHub Actionsのワークフローを実行すると、ステージング環境と本番環境へテーマファイルが自動的にデプロイされます。
ステージングは1分程度で完了します。
本番も1分程度で完了します。
今後の展望
- WordPressをSSG(Static Site Generator)に移行することで、より高速かつ安全なWebサイトを構築できる可能性があります。
- カオスになりやすいWordPressの運用に少しでも秩序を導入できたのでこれでしばらくは延命できます。
まとめ
GitHub Actionsを活用することで、WordPressテーマのCI/CDを簡単に構築できます。
これにより、開発効率が向上し、安全な運用を実現できます。
Discussion