プラグイン(拡張アプリ)の CI と複数バージョン検証


プラグインのテストを CI(継続的インテグレーション)で自動実行し、さらに複数の PHP・a-blog cms バージョンにまたがって検証する方法です。テストコードの書き方は プラグイン(拡張アプリ)のテストの書き方 を参照してください。

CI(継続的インテグレーション)とは

CI(継続的インテグレーション)とは、プログラムのテストやビルド等といった作業を自動化する仕組みのことを言います。

CI を実現するための主なサービスとして、Github ActionsBitbucket PipelinesCircle CI などが挙げられます。

全体像

CI では、a-blog cms 本体を同梱した開発用 Docker イメージ appleple/acms:<バージョン>-php<PHP> の中でテストを実行します。本体は Docker イメージから来るので、プラグインリポジトリに本体ソースを入れる必要はありません

複数バージョンで検証したいときに切り替えるのは、次の 2 つだけです。どちらも 1 つのバージョン文字列から決まります。

  • Docker イメージのタグ(例 3.2-php8.4)… PHP と a-blog cms バージョンを選ぶ

  • ablogcms/testing-framework の composer 制約(例 3.2.*)… テスト対象のマイナーバージョンに合わせる

appleple/acms は開発・CI 用途のイメージです。本番運用には使わないでください。利用可能なタグは Docker Hub の Tags タブが最新です。

composer 制約の注意(重要)

テスト基盤のバージョンは a-blog cms のマイナーバージョンに固定します。^ は使いません。

書き方

解決範囲

可否

"3.2.*"

>=3.2.0 <3.3.0

✅ 3.2 ラインに固定

"~3.2.0"

>=3.2.0 <3.3.0

✅ 同上

"^3.2"

>=3.2.0 <4.0.0

❌ 3.3 系まで拾い、CMS 3.2 と framework 3.3 が組む事故になる

CI では「CMS マイナー文字列 + .*」で組みます(例 ablogcms/testing-framework:3.2.*)。イメージタグのマイナーと framework の制約を必ず一致させてください。

バージョン対応表

テスト基盤・CMS・PHP の対応は次のとおりです。1 つの CMS マイナーに 1 本のテスト基盤ラインが対応します。

a-blog cms

テスト基盤(composer 制約)

Docker イメージ

PHP

3.2 系

ablogcms/testing-framework:3.2.*

appleple/acms:3.2-php<PHP>

8.1 / 8.2 / 8.3 / 8.4 / 8.5

3.3 系

ablogcms/testing-framework:3.3.*

appleple/acms:3.3-php<PHP>

リリース時に確定

CI マトリクスは、この表の 1 行(CMS マイナー)× PHP を展開したものです。イメージタグのマイナーと testing-framework の制約は必ず一致させます(不一致は「CMS 3.2 に framework 3.3」のような組み合わせ事故になります)。利用可能なタグの最新一覧は Docker Hub の Tags タブが一次情報です。

ローカル / compose の基本形

プラグインを本体イメージの extension/plugins/ 配下に bind mount して起動します。

# docker-compose.yml
services:
  acms:
    image: appleple/acms:3.2-php8.4
    ports: ["8080:80"]
    environment:
      ACMS_DB_HOST: db
      ACMS_DB_NAME: acms
      ACMS_DB_USER: root
      ACMS_DB_PASS: root
    volumes:
      - ./src:/var/www/html/extension/plugins/my-plugin
    depends_on:
      db:
        condition: service_healthy

  db:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: acms
      MYSQL_ROOT_PASSWORD: root
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-proot"]
      interval: 5s
      timeout: 5s
      retries: 12

GitHub Actions

ネイティブの matrix 機能があるので最も簡潔です。PHP を軸に回し、a-blog cms マイナーバージョンが増えたら acms に足すだけです。

jobs:
  phpunit:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        acms: ["3.2"]                              # 3.3 が出たら "3.3" を足す
        php:  ["8.1", "8.2", "8.3", "8.4", "8.5"]
    env:
      ACMS_IMAGE_TAG: "${{ matrix.acms }}-php${{ matrix.php }}"   # compose の image タグへ反映
    steps:
      - uses: actions/checkout@v4
      - run: docker compose up -d --wait
      - run: |
          docker compose exec -T acms bash -lc '
            cd /var/www/html/extension/plugins/my-plugin
            composer require --dev "ablogcms/testing-framework:${{ matrix.acms }}.*" --no-update
            composer update
            vendor/bin/acms-create-database
            vendor/bin/phpunit'

複数の DB エンジン(MySQL と互換 DB など)でも検証したい場合は、matrix に DB 軸を足し、db サービスのイメージを切り替えます。まずは PHP 軸だけで始め、必要になってから広げれば十分です。

Bitbucket Pipelines

ネイティブ matrix 機能が無いので、YAML アンカー + parallel で PHP を並べます。image: のタグ(<バージョン>-php<PHP>)で PHP と a-blog cms を選びます。

definitions:
  steps:
    - step: &phpunit-32                       # a-blog cms 3.2 ライン(framework も 3.2.*)
        script:
          - composer require --dev "ablogcms/testing-framework:3.2.*" --no-update
          - composer update
          - vendor/bin/acms-create-database
          - vendor/bin/phpunit
pipelines:
  default:
    # 3.3 が出たら &phpunit-33(framework:3.3.*)を足し、3.3-php* の parallel を追加するだけ
    - parallel:
        - step: { <<: *phpunit-32, name: php8.1, image: appleple/acms:3.2-php8.1 }
        - step: { <<: *phpunit-32, name: php8.2, image: appleple/acms:3.2-php8.2 }
        - step: { <<: *phpunit-32, name: php8.3, image: appleple/acms:3.2-php8.3 }
        - step: { <<: *phpunit-32, name: php8.4, image: appleple/acms:3.2-php8.4 }
        - step: { <<: *phpunit-32, name: php8.5, image: appleple/acms:3.2-php8.5 }

Bitbucket Pipelines は 1 パイプライン合計 100 ステップの上限があります。マイナー × PHP を広げるときは総ステップ数に注意してください。

静的解析(phpcs / phpstan)は 1 回だけ

phpcs / phpstan は実行時の PHP に依存せず、対応範囲全体を対象にします。PHP ごとに回さず、1 回だけ実行すれば十分です(PHPStan の設定phpVersion の範囲を指定済みのため)。PHPUnit だけを PHP マトリクスで回し、静的解析は独立した 1 ジョブに分けるのがおすすめです。

コードカバレッジ

カバレッジ計測には Xdebug か PCOV が必要で、計測はテスト実行を大きく遅くします。CI では既定でカバレッジを取らず--coverage-* を付けず)、必要なときだけ計測するのがおすすめです。ローカルで見たいときは次のように生成します。

vendor/bin/phpunit --coverage-html coverage/

同梱イメージ appleple/acms には計測ドライバ(Xdebug / PCOV)が入っています。CI で常時計測したい場合は、PHP マトリクスの 1 つだけで計測して結果をアップロードする形にすると、全レグを遅くせずに済みます。

依存の下限も検証する(任意)

composer.json に書いた依存の下限バージョンでも動くことを確かめると、「新しめの環境でしか動かない」退行を早期に捕まえられます。CI の 1 レグで composer update --prefer-lowest を使うと確認できます。

応用: 案件で複数プラグインをまとめてテストする

1 つの案件で複数プラグインを作る場合、プラグインごとに環境を用意する必要はありません。案件リポジトリに 1 つのテスト環境(composer.json / phpunit.xml.dist / phpstan.neon)を置き、各プラグインの src/extension/plugins/{Name} へ シンボリックリンクすることで、全プラグインをまとめて回せます。詳しい構成はテスト基盤(ablogcms/testing-framework)の README を参照してください。

関連ドキュメント