name: plugin-checks # Plugin-agnostic: nothing below names this plugin. Name, version and paths come from composer.json. # shopware-cli runs from its official Docker image, intentionally unpinned (latest); a red build # after a CLI release means fix the config. on: pull_request: branches: [main] permissions: contents: read # A new push to the PR cancels the superseded run. concurrency: group: plugin-checks-${{ github.ref }} cancel-in-progress: true jobs: # Every PR into main must bump the version and document it in CHANGELOG.md. version-changelog: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Check version bump and changelog entry run: | set -e PR_VERSION=$(grep -m1 '"version"' composer.json | sed -E 's/.*"version"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/') MAIN_VERSION=$(git show origin/main:composer.json | grep -m1 '"version"' | sed -E 's/.*"version"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/') echo "main version: $MAIN_VERSION" echo "PR version: $PR_VERSION" if [ "$MAIN_VERSION" = "$PR_VERSION" ]; then echo "::error::composer.json version ($PR_VERSION) was not bumped from main ($MAIN_VERSION)" exit 1 fi HIGHEST=$(printf '%s\n%s\n' "$MAIN_VERSION" "$PR_VERSION" | sort -V | tail -n1) if [ "$HIGHEST" != "$PR_VERSION" ]; then echo "::error::composer.json version ($PR_VERSION) is not greater than main's ($MAIN_VERSION)" exit 1 fi if ! grep -qF "## [$PR_VERSION]" CHANGELOG.md; then echo "::error::CHANGELOG.md is missing a '## [$PR_VERSION]' heading" exit 1 fi echo "OK: version bumped to $PR_VERSION and documented in CHANGELOG.md" # Packages the extension (builds admin/storefront assets) and validates the resulting zip, # which is the artifact that ships. A separate directory validate would only repeat these checks. package: runs-on: ubuntu-latest container: image: ghcr.io/shopware/shopware-cli:latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: ./.gitea/actions/package # The release workflow reuses this tested zip when main ends up with the same tree # (it falls back to packaging again otherwise). - name: Tree hash of the packaged commit id: tree run: echo "hash=$(git rev-parse "${GITHUB_SHA}^{tree}")" >> "$GITHUB_OUTPUT" - name: Save tested zip for the release uses: actions/cache/save@v4 with: path: .build/package.zip key: plugin-zip-${{ steps.tree.outputs.hash }} phpunit: runs-on: ubuntu-latest # Same image as above: it already ships PHP, Composer and Node, so no apt install. container: image: ghcr.io/shopware/shopware-cli:latest services: database: # Shopware 6.6 supports MariaDB 10.11 / MySQL 8; 11.4 broke Shopware's own migrations. image: mariadb:10.11 env: MARIADB_ROOT_PASSWORD: root env: # Already the *_test name: Shopware's TestBootstrapper would otherwise append _test and run every migration a second time. DATABASE_URL: mysql://root:root@database:3306/shopware_test APP_ENV: test APP_URL: http://localhost APP_SECRET: ci-secret-not-for-production INSTANCE_ID: ci COMPOSER_MEMORY_LIMIT: '-1' COMPOSER_ALLOW_SUPERUSER: '1' steps: - 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 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' run: | set -e composer create-project shopware/production:6.6.* 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: Wait for the database run: | for i in $(seq 60); do (echo > /dev/tcp/database/3306) 2>/dev/null && exit 0 sleep 2 done echo "::error::database service did not come up"; exit 1 - name: Relax database durability (throwaway CI database, speeds up the migrations) 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");' - name: Resolve plugin name and install the plugin sources run: | # plugin directory name = short class name of extra.shopware-plugin-class CLASS=$(php -r 'echo json_decode(file_get_contents("plugin-src/composer.json"), true)["extra"]["shopware-plugin-class"];') PLUGIN_NAME="${CLASS##*\\}" 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"