diff --git a/.gitea/workflows/plugin-checks.yml b/.gitea/workflows/plugin-checks.yml index a7888a9..5eac50e 100644 --- a/.gitea/workflows/plugin-checks.yml +++ b/.gitea/workflows/plugin-checks.yml @@ -1,7 +1,8 @@ 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. +# 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: @@ -11,15 +12,8 @@ permissions: contents: read jobs: - validate: - runs-on: ubuntu-latest - container: - image: ghcr.io/shopware/shopware-cli:latest - steps: - - uses: actions/checkout@v4 - - name: Validate extension - run: shopware-cli extension validate . - + # 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: @@ -28,33 +22,29 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 + - uses: actions/cache@v4 + with: + path: | + ~/.npm + ~/.cache/shopware-cli + key: swcli-${{ runner.os }}-${{ hashFiles('composer.json', 'src/Resources/app/**/package*.json') }} + restore-keys: swcli-${{ runner.os }}- - name: Package extension run: shopware-cli extension package . --output-directory .build --filename package.zip --git-commit "$GITHUB_SHA" - name: Validate packaged zip run: shopware-cli extension validate .build/package.zip - - name: Ensure helper tools (jq, curl, unzip) - run: | - command -v jq >/dev/null && command -v curl >/dev/null && command -v unzip >/dev/null && exit 0 - (apt-get update -q && apt-get install -y -q --no-install-recommends jq curl unzip) || apk add --no-cache jq curl unzip - name: Assert built JS is in the zip - run: | - set -e - LIST=$(unzip -Z1 .build/package.zip) - if [ -f src/Resources/app/administration/src/main.js ] || [ -f src/Resources/app/administration/src/main.ts ]; then - echo "$LIST" | grep -q 'Resources/public/administration/js/' || { echo "::error::admin entry exists but the zip has no built admin JS"; exit 1; } - fi - if [ -f src/Resources/app/storefront/src/main.js ] || [ -f src/Resources/app/storefront/src/main.ts ]; then - echo "$LIST" | grep -q 'Resources/app/storefront/dist/' || { echo "::error::storefront entry exists but the zip has no built storefront JS"; exit 1; } - fi + run: scripts/ci/assert-built-assets.sh .build/package.zip phpunit: runs-on: ubuntu-latest - # shivammathur/setup-php hangs on this runner, so PHP comes from Debian bookworm (8.2) via apt. + # Same image as above: it already ships PHP, Composer and Node, so no apt install. container: - image: node:20-bookworm + image: ghcr.io/shopware/shopware-cli:latest services: database: - image: mariadb:11.4 + # 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: @@ -67,10 +57,15 @@ jobs: - uses: actions/checkout@v4 with: path: plugin-src - - name: Install PHP and tools - run: | - apt-get update -q - apt-get install -y -q --no-install-recommends php-cli php-gd php-intl php-mysql php-zip php-curl php-mbstring php-xml php-bcmath composer unzip jq git ca-certificates + - uses: actions/cache@v4 + with: + path: | + ~/.cache/composer + ~/.composer/cache + key: composer-${{ runner.os }}-shopware-6.6-${{ hashFiles('plugin-src/composer.json') }} + restore-keys: composer-${{ runner.os }}-shopware-6.6- + - name: Toolchain + run: php -v && composer --version && php -m | tr '\n' ' ' - name: Wait for the database run: | for i in $(seq 60); do @@ -81,7 +76,7 @@ jobs: - name: Resolve plugin name run: | # plugin directory name = short class name of extra.shopware-plugin-class - CLASS=$(jq -r '.extra["shopware-plugin-class"]' plugin-src/composer.json) + CLASS=$(php -r 'echo json_decode(file_get_contents("plugin-src/composer.json"), true)["extra"]["shopware-plugin-class"];') echo "PLUGIN_NAME=${CLASS##*\\}" >> "$GITHUB_ENV" - name: Create Shopware 6.6 project run: composer create-project shopware/production:6.6.* shopware --no-interaction --no-scripts diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 312ab37..c7f1001 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -49,9 +49,14 @@ jobs: echo "skip=false" >> "$GITHUB_OUTPUT" fi - - name: Validate extension + - uses: actions/cache@v4 if: steps.meta.outputs.skip == 'false' - run: shopware-cli extension validate . + with: + path: | + ~/.npm + ~/.cache/shopware-cli + key: swcli-${{ runner.os }}-${{ hashFiles('composer.json', 'src/Resources/app/**/package*.json') }} + restore-keys: swcli-${{ runner.os }}- - name: Package extension (prebuilt admin/storefront assets) if: steps.meta.outputs.skip == 'false' @@ -63,6 +68,10 @@ jobs: if: steps.meta.outputs.skip == 'false' run: shopware-cli extension validate ".build/${{ steps.meta.outputs.zip }}" + - name: Assert built JS is in the zip + if: steps.meta.outputs.skip == 'false' + run: scripts/ci/assert-built-assets.sh ".build/${{ steps.meta.outputs.zip }}" + - name: Extract changelog section if: steps.meta.outputs.skip == 'false' run: | diff --git a/docs/spec/shopware-guideline-compliance.md b/docs/spec/shopware-guideline-compliance.md index 0e731c2..3603f38 100644 --- a/docs/spec/shopware-guideline-compliance.md +++ b/docs/spec/shopware-guideline-compliance.md @@ -36,14 +36,13 @@ on branches `research/shopware-guideline-checklist`, `research/shopware-cli-ci-b Jobs (all required checks on `main`): `pr-version-check.yml` (job `version-changelog`) is unchanged apart from `permissions:`; its name keeps the existing required context. New `plugin-checks.yml`: -1. `validate` - install `shopware-cli`, `extension validate .` (hard gate, no `|| true`). -2. `package` - `extension package` with `--git-commit "$GITHUB_SHA"`, then assert the zip contains built admin JS (`Resources/public/administration/js`) when an admin entry exists. -3. `phpunit` - `composer create-project shopware/production` (6.6.x) + MariaDB service, copy the plugin into `custom/plugins`, install/activate, run phpunit. PHP from the Debian bookworm container (8.2), because `shivammathur/setup-php` hangs on this runner. +1. `package` - `extension package` with `--git-commit "$GITHUB_SHA"`, `extension validate` on the resulting zip (hard gate; replaces a separate directory validate, which only repeats those checks), then `scripts/ci/assert-built-assets.sh` (built admin/storefront JS present when sources exist). All shopware-cli jobs run in `ghcr.io/shopware/shopware-cli:latest`; npm and shopware-cli caches via `actions/cache`. +2. `phpunit` - `composer create-project shopware/production` (6.6.x) + MariaDB service, copy the plugin into `custom/plugins`, install/activate, run phpunit. Runs in the same `shopware-cli` image (PHP and Composer included; `shivammathur/setup-php` hangs on this runner and apt installs cost ~4.5 min). MariaDB 10.11, because 11.4 broke Shopware's own migrations. ### Release workflow (`.gitea/workflows/release.yml`) On push to `main`, guarded against re-release by an existing tag: -validate -> `extension package --git-commit "$GITHUB_SHA"` -> **validate the zip** -> create the Gitea +`extension package --git-commit "$GITHUB_SHA"` -> **validate the zip** -> assert built assets -> create the Gitea release via API (`POST /repos/{owner}/{repo}/releases`, creates the tag) with the zip as asset -> upload the same zip to the Composer registry -> link package to repository. Removes the manual `git tag` step, the `akkuman` action and the `git archive` zip. Packaging happens diff --git a/scripts/ci/assert-built-assets.sh b/scripts/ci/assert-built-assets.sh new file mode 100644 index 0000000..888a5d9 --- /dev/null +++ b/scripts/ci/assert-built-assets.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# Assert that a packaged extension zip contains the built admin/storefront JS when the sources exist. +# Usage: scripts/ci/assert-built-assets.sh (run from the repo root; BusyBox-safe: uses unzip -l) +set -euo pipefail +ZIP="${1:?usage: assert-built-assets.sh }" +LIST=$(unzip -l "$ZIP") + +check() { #