From 18844718d26d58accbc490ff01ab1690e25dd934 Mon Sep 17 00:00:00 2001 From: ArthurErlich Date: Sun, 4 Oct 2026 01:01:21 +0200 Subject: [PATCH] ci(phpunit): cache the installed database, key the cache on the Shopware version - resolve the latest 6.6.x from Packagist; cache key shopware--installed-v1 - cache the project plus a SQL dump of the installed shopware_test database; on a hit restore the dump instead of running system:install (~4.6 min) - rename the step 'Install Shopware (once)' to 'Install Shopware' Co-Authored-By: Claude Sonnet 5.5 --- .gitea/workflows/plugin-checks.yml | 84 ++++++++++++++++++++++-------- CLAUDE.md | 8 +-- 2 files changed, 66 insertions(+), 26 deletions(-) diff --git a/.gitea/workflows/plugin-checks.yml b/.gitea/workflows/plugin-checks.yml index e437554..e495819 100644 --- a/.gitea/workflows/plugin-checks.yml +++ b/.gitea/workflows/plugin-checks.yml @@ -98,28 +98,41 @@ jobs: - uses: actions/checkout@v4 with: path: plugin-src - - name: Month stamp (refreshes the cached project monthly) - id: stamp - run: echo "month=$(date +%Y-%m)" >> "$GITHUB_OUTPUT" - # The project (incl. vendor/ and phpunit) does not depend on the plugin, so it is cached on its own. - - name: Restore prepared Shopware project - id: project + # The cache key follows the Shopware version: a new 6.6.x release changes the key, so the old + # project + database are never reused. Bump -v1 to force a refresh by hand. + - name: Resolve the latest Shopware 6.6 version + id: sw + run: | + VERSION=$(php -r ' + $all = json_decode(file_get_contents("https://repo.packagist.org/p2/shopware/production.json"), true)["packages"]["shopware/production"]; + $v = []; + foreach ($all as $p) { if (preg_match("/^6\.6\.\d+(\.\d+)*$/", $p["version"])) { $v[] = $p["version"]; } } + usort($v, "version_compare"); + echo end($v);') + test -n "$VERSION" || { echo "::error::could not resolve the Shopware 6.6 version"; exit 1; } + echo "Shopware ${VERSION}" + echo "version=${VERSION}" >> "$GITHUB_OUTPUT" + # Project (vendor/, phpunit, config) and the installed database as a SQL dump. Neither depends on the plugin. + - name: Restore Shopware project and database + id: shopware uses: actions/cache/restore@v4 with: - path: shopware - key: shopware-6.6-prepared-${{ steps.stamp.outputs.month }} - - name: Create Shopware 6.6 project - if: steps.project.outputs.cache-hit != 'true' + path: | + shopware + !shopware/var/cache + !shopware/var/log + shopware-db.sql.gz + key: shopware-${{ steps.sw.outputs.version }}-installed-v1 + - name: Create Shopware project + if: steps.shopware.outputs.cache-hit != 'true' run: | set -e - composer create-project shopware/production:6.6.* shopware --no-interaction --no-scripts + composer create-project "shopware/production:${{ steps.sw.outputs.version }}" shopware --no-interaction --no-scripts composer require --dev phpunit/phpunit:^10 --no-interaction --no-scripts -d shopware - - name: Save prepared Shopware project - if: steps.project.outputs.cache-hit != 'true' - uses: actions/cache/save@v4 - with: - path: shopware - key: shopware-6.6-prepared-${{ steps.stamp.outputs.month }} + - name: Ensure the MariaDB client + run: | + command -v mariadb-dump >/dev/null || command -v mysqldump >/dev/null && exit 0 + (apt-get update -q && apt-get install -y -q --no-install-recommends mariadb-client) || apk add --no-cache mariadb-client - name: Wait for the database run: | for i in $(seq 60); do @@ -127,9 +140,39 @@ jobs: sleep 2 done echo "::error::database service did not come up"; exit 1 - - name: Relax database durability (throwaway CI database, speeds up the migrations) + - name: Relax database durability (throwaway CI database, speeds up the install and the restore) run: | php -r '$p = new PDO("mysql:host=database;port=3306", "root", "root"); $p->exec("SET GLOBAL innodb_flush_log_at_trx_commit=0"); $p->exec("SET GLOBAL sync_binlog=0");' + # One install into shopware_test; the bootstrapper then sees an installed DB, skips its own install and + # only activates the plugin (tests/TestBootstrap.php forces plugin installation). + - name: Install Shopware + if: steps.shopware.outputs.cache-hit != 'true' + working-directory: shopware + run: bin/console system:install --basic-setup --create-database --force --no-interaction + - name: Dump the installed database + if: steps.shopware.outputs.cache-hit != 'true' + run: | + set -e + DUMP=$(command -v mariadb-dump || command -v mysqldump) + "$DUMP" -h database -P 3306 -u root -proot --skip-ssl --single-transaction --routines --triggers \ + --databases shopware_test | gzip > shopware-db.sql.gz + ls -l shopware-db.sql.gz + - name: Save Shopware project and database + if: steps.shopware.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + path: | + shopware + !shopware/var/cache + !shopware/var/log + shopware-db.sql.gz + key: shopware-${{ steps.sw.outputs.version }}-installed-v1 + - name: Restore the database from the cache + if: steps.shopware.outputs.cache-hit == 'true' + run: | + set -e + CLIENT=$(command -v mariadb || command -v mysql) + gunzip -c shopware-db.sql.gz | "$CLIENT" -h database -P 3306 -u root -proot --skip-ssl - name: Resolve plugin name and install the plugin sources run: | # plugin directory name = short class name of extra.shopware-plugin-class @@ -138,11 +181,6 @@ jobs: echo "PLUGIN_NAME=${PLUGIN_NAME}" >> "$GITHUB_ENV" rm -rf "shopware/custom/plugins/${PLUGIN_NAME}" cp -r plugin-src "shopware/custom/plugins/${PLUGIN_NAME}" - # One install into shopware_test; the bootstrapper sees an installed DB, skips its own install and - # only activates the plugin (tests/TestBootstrap.php forces plugin installation). - - name: Install Shopware (once) - working-directory: shopware - run: bin/console system:install --basic-setup --create-database --force --no-interaction - name: Run phpunit working-directory: shopware run: vendor/bin/phpunit -c "custom/plugins/${PLUGIN_NAME}/phpunit.xml" diff --git a/CLAUDE.md b/CLAUDE.md index b3e146a..7ffab58 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -53,9 +53,11 @@ activates this plugin inside a real Shopware kernel for the test run (`KERNEL_CL `Shopware\Core\Kernel` in `phpunit.xml`). This means tests require a working Shopware installation/DB to bootstrap against — they are not runnable as an isolated PHP package. -In CI (`phpunit` job) a Shopware 6.6 project is prepared once (`composer create-project` + phpunit, -cached monthly), the plugin is copied into `custom/plugins`, and `system:install` runs once into -`shopware_test` (MariaDB 10.11 service), so the bootstrapper only activates the plugin. +In CI (`phpunit` job) the latest Shopware 6.6 version is resolved from Packagist and the prepared project +(`composer create-project` + phpunit, then `system:install` into `shopware_test` on a MariaDB 10.11 service) +plus a SQL dump of the installed database are cached under a key that contains that version, so a new +Shopware release invalidates the cache. On a hit the dump is restored instead of reinstalling; the plugin +is then copied into `custom/plugins` and the bootstrapper only activates it. ```bash vendor/bin/phpunit # full suite