2026年7月22日

2026年7月22日

GitHub ActionsでWordPressのCI/CDパイプラインを構築する方法

はじめに

GitHub Actionsを使えば、プルリクエストのたびにコーディング規約チェック・テスト・自動デプロイが走るCI/CDパイプラインを構築できます。手動デプロイによるミスをなくし、コードレビューの品質を高め、チーム全体の開発速度を向上させましょう。

症状・原因

  • コードをpushするたびに手動でFTPアップロードやSSHでデプロイしており、ミスが多い
  • コーディング規約の統一ができておらずコードレビューに時間がかかる
  • テストが自動化されておらず、バグが本番環境まで入り込んでしまう
  • デプロイの成否をSlackやメールで自動通知したい

解決手順

ステップ1:GitHub Actionsワークフローファイルの作成

.github/workflows/ディレクトリにYAMLファイルを配置することでワークフローを定義します。

# ディレクトリ構造
mkdir -p .github/workflows
# .github/workflows/ci.yml
name: WordPress CI

on:
  push:
    branches: [main, develop, 'feature/**']
  pull_request:
    branches: [main, develop]

env:
  PHP_VERSION: '8.2'
  WP_VERSION: 'latest'

jobs:
  lint:
    name: PHP Lint
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ env.PHP_VERSION }}
          tools: composer:v2
          coverage: none
      
      - name: Get Composer cache directory
        id: composer-cache
        run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
      
      - name: Cache Composer packages
        uses: actions/cache@v4
        with:
          path: ${{ steps.composer-cache.outputs.dir }}
          key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
          restore-keys: ${{ runner.os }}-composer-
      
      - name: Install Composer dependencies
        run: composer install --no-progress --prefer-dist --no-interaction
      
      - name: Check PHP syntax
        run: find . -name "*.php" -not -path "./vendor/*" | xargs -P4 php -l

ステップ2:PHP CodeSniffer(PHPCS)でコーディング規約チェック

WordPressコーディング規約(WPCS)に準拠しているかを自動チェックします。

# ローカル環境でのセットアップ
composer require --dev \
    squizlabs/php_codesniffer:"^3.9" \
    wp-coding-standards/wpcs:"^3.1" \
    phpcompatibility/phpcompatibility-wp:"*"

# WPCSのインストール確認
./vendor/bin/phpcs -i
<!-- phpcs.xml.dist -->
<?xml version="1.0"?>
<ruleset name="My Plugin Coding Standards">
    <description>WordPress Coding Standards for My Plugin</description>

    <!-- チェック対象のファイル -->
    <file>./src</file>
    <file>./my-plugin.php</file>
    
    <!-- 除外するディレクトリ -->
    <exclude-pattern>./vendor/*</exclude-pattern>
    <exclude-pattern>./node_modules/*</exclude-pattern>
    <exclude-pattern>./tests/*</exclude-pattern>

    <!-- WordPressコーディング規約を使用 -->
    <rule ref="WordPress">
        <!-- 許容するルール違反 -->
        <exclude name="WordPress.Files.FileName.InvalidClassFileName"/>
        <exclude name="WordPress.Files.FileName.NotHyphenatedLowercase"/>
    </rule>
    
    <!-- PHP互換性チェック -->
    <rule ref="PHPCompatibilityWP"/>
    
    <!-- PHPバージョンの指定 -->
    <config name="minimum_supported_wp_version" value="6.0"/>
    <config name="testVersion" value="8.1-"/>
    
    <!-- エラー表示設定 -->
    <arg name="basepath" value="."/>
    <arg name="colors"/>
    <arg value="sp"/>
</ruleset>
# .github/workflows/ci.yml に追加
  phpcs:
    name: PHP CodeSniffer
    runs-on: ubuntu-latest
    needs: lint
    
    steps:
      - uses: actions/checkout@v4
      
      - uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ env.PHP_VERSION }}
          tools: composer:v2, cs2pr
          coverage: none
      
      - run: composer install --no-progress --prefer-dist
      
      - name: Run PHPCS
        run: ./vendor/bin/phpcs --report=checkstyle | cs2pr

ステップ3:PHPUnitテストの自動実行

CIパイプラインでPHPUnitテストを自動実行します。

# .github/workflows/ci.yml に追加
  phpunit:
    name: PHPUnit Tests
    runs-on: ubuntu-latest
    needs: lint
    
    services:
      mysql:
        image: mysql:8.0
        env:
          MYSQL_ROOT_PASSWORD: root
          MYSQL_DATABASE: wordpress_test
          MYSQL_USER: wp_user
          MYSQL_PASSWORD: wp_password
        ports:
          - 3306:3306
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=5
    
    strategy:
      fail-fast: false
      matrix:
        php: ['8.1', '8.2', '8.3']
        wp: ['6.4', '6.5', 'latest']
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup PHP ${{ matrix.php }}
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php }}
          extensions: mysqli, pdo_mysql
          tools: composer:v2
          coverage: xdebug
      
      - name: Install dependencies
        run: composer install --no-progress --prefer-dist
      
      - name: Install WordPress test suite
        run: |
          bash bin/install-wp-tests.sh \
            wordpress_test root root 127.0.0.1 ${{ matrix.wp }}
      
      - name: Run PHPUnit
        run: |
          ./vendor/bin/phpunit \
            --coverage-clover coverage.xml \
            --log-junit test-results.xml
      
      - name: Upload test results
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: test-results-php${{ matrix.php }}-wp${{ matrix.wp }}
          path: test-results.xml
      
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v4
        with:
          file: ./coverage.xml
          flags: php${{ matrix.php }}

ステップ4:SSH/rsyncを使った自動デプロイ

mainブランチへのマージ時に本番環境へ自動デプロイします。

# .github/workflows/deploy.yml
name: Deploy to Production

on:
  push:
    branches: [main]

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    needs: [phpcs, phpunit]
    
    environment:
      name: production
      url: https://example.com
    
    steps:
      - uses: actions/checkout@v4
      
      - uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'
          tools: composer:v2
          coverage: none
      
      - name: Install production dependencies
        run: |
          composer install \
            --no-dev \
            --no-progress \
            --optimize-autoloader \
            --prefer-dist
      
      # rsync でファイルをデプロイ
      - name: Deploy via rsync
        uses: burnett01/rsync-deployments@7.0.1
        with:
          switches: -avzr --delete --exclude='.git' --exclude='.env'
          path: ./
          remote_path: ${{ secrets.DEPLOY_PATH }}
          remote_host: ${{ secrets.DEPLOY_HOST }}
          remote_user: ${{ secrets.DEPLOY_USER }}
          remote_key: ${{ secrets.DEPLOY_KEY }}
      
      # SSH でデプロイ後処理
      - name: Post-deploy tasks via SSH
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.DEPLOY_HOST }}
          username: ${{ secrets.DEPLOY_USER }}
          key: ${{ secrets.DEPLOY_KEY }}
          script: |
            cd ${{ secrets.DEPLOY_PATH }}
            wp cache flush --allow-root
            wp core update-db --allow-root
            wp rewrite flush --hard --allow-root
            echo "デプロイ完了: $(date)"

GitHubのリポジトリ設定でSecretsを登録します:

  • DEPLOY_HOST:サーバーのIPアドレスまたはドメイン
  • DEPLOY_USER:SSHユーザー名
  • DEPLOY_KEY:SSH秘密鍵
  • DEPLOY_PATH:デプロイ先のパス

ステップ5:Slack/Discord通知の設定

デプロイの成否を通知することでチームの状況共有を自動化します。

# deploy.yml に追加(deployジョブのstepsの末尾)
      - name: Notify Slack on success
        if: success()
        uses: slackapi/slack-github-action@v1.27.0
        with:
          payload: |
            {
              "text": "✅ デプロイ成功",
              "blocks": [
                {
                  "type": "section",
                  "text": {
                    "type": "mrkdwn",
                    "text": "*✅ 本番デプロイ成功*\n*コミット:* ${{ github.sha }}\n*ブランチ:* ${{ github.ref_name }}\n*実行者:* ${{ github.actor }}\n*URL:* https://example.com"
                  }
                }
              ]
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
          SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
      
      - name: Notify Slack on failure
        if: failure()
        uses: slackapi/slack-github-action@v1.27.0
        with:
          payload: |
            {
              "text": "❌ デプロイ失敗",
              "blocks": [
                {
                  "type": "section",
                  "text": {
                    "type": "mrkdwn",
                    "text": "*❌ 本番デプロイ失敗*\n*コミット:* ${{ github.sha }}\n*ログ:* ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
                  }
                }
              ]
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
          SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
# GitHub CLIでシークレットを登録
gh secret set DEPLOY_HOST --body "your-server-ip"
gh secret set DEPLOY_USER --body "deploy-user"
gh secret set DEPLOY_KEY < ~/.ssh/deploy_key
gh secret set SLACK_WEBHOOK_URL --body "https://hooks.slack.com/..."

# ワークフローの状態を確認
gh run list --workflow=deploy.yml
gh run view --log

注意事項

  • SSH秘密鍵はGitHubのSecrets(暗号化された環境変数)に登録してください。絶対にコードに直接記述しないでください。デプロイ専用の鍵ペアを生成し、サーバーの~/.ssh/authorized_keysに公開鍵のみを登録します
  • rsync --deleteオプションはデプロイ先にのみ存在するファイルを削除します。wp-content/uploads/など、ユーザーがアップロードしたディレクトリは--excludeで除外してください
  • GitHub Actionsは無料枠に制限(パブリックリポジトリは無制限、プライベートは月2000分)があります。マトリクステスト(PHP×WPバージョン)の組み合わせが多いとすぐに消費するため、PRでは単一バージョン、mainへのプッシュ時にフルマトリクスという分岐も有効です

まとめ

GitHub Actionsを使えば、プッシュのたびにコード品質チェック・テスト・デプロイが自動で走るCI/CDパイプラインを構築できます。手動デプロイのミスをゼロにし、コードレビューの効率を高め、チームの開発速度を大幅に向上させましょう。まずはPHPCSの自動チェックから始めるだけでも大きな効果があります。

関連記事:WordPressステージング環境の構築と本番環境への反映手順

お気軽にご相談ください

お見積りへ お問い合わせへ