From 4bc0f8a0af28f9f5c5299b7924df4c2f1a9c485b Mon Sep 17 00:00:00 2001 From: Hug0-Drelon Date: Mon, 15 Jun 2026 18:00:06 +0200 Subject: [PATCH 1/3] Create wp-env-config-path and playwright-cmd inputs for e2e action. --- e2e/action.yml | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/e2e/action.yml b/e2e/action.yml index 5c1cbf5..f3f12c9 100644 --- a/e2e/action.yml +++ b/e2e/action.yml @@ -8,6 +8,16 @@ inputs: required: false type: string default: 'no-external-cache-key' + wp-env-config-path: + description: Path to a custom wp-env config file passed to wp-env --config. Default is '' (wp-env default discovery). + required: false + type: string + default: '' + playwright-cmd: + description: CLI command to run playwright tests. Default is 'npm run test:e2e'. + required: false + type: string + default: 'npm run test:e2e' runs: using: 'composite' @@ -95,10 +105,12 @@ runs: - name: Install WordPress and start the server run: | - npm run wp-env start + if [ -n "${{ inputs.wp-env-config-path }}" ]; then + npm run wp-env start -- --config="${{ inputs.wp-env-config-path }}" + else + npm run wp-env start + fi shell: bash - env: - WP_ENV_PHP_VERSION: '8.0' - name: Save Docker image to cache if: steps.docker-cache.outputs.cache-hit != 'true' @@ -107,9 +119,8 @@ runs: docker save $(docker images --format '{{.Repository}}:{{.Tag}}') -o wp-env-image.tar shell: bash - - name: Run Playwright tests - run: | - npm run test:e2e + - name: Run Playwright tests with WordPress ${{ env.WP_VERSION }} + run: ${{ inputs.playwright-cmd }} shell: bash - name: Upload Playwright report From 1fe48f03540b472138a174a2527bddbab523c17e Mon Sep 17 00:00:00 2001 From: Hugo Drelon <69580439+Hug0-Drelon@users.noreply.github.com> Date: Fri, 17 Jul 2026 13:32:05 +0200 Subject: [PATCH 2/3] perf(e2e): improve node_modules, Playwright and wp-env home caching (#20) --- bin/get-playwright-version.js | 56 +++++++++++++++++++++++++++ e2e/action.yml | 73 +++++++++++++++++++++++------------ 2 files changed, 105 insertions(+), 24 deletions(-) create mode 100644 bin/get-playwright-version.js diff --git a/bin/get-playwright-version.js b/bin/get-playwright-version.js new file mode 100644 index 0000000..719239e --- /dev/null +++ b/bin/get-playwright-version.js @@ -0,0 +1,56 @@ +'use strict'; + +/** + * Resolves the installed @playwright/test version for CI caching. + * + * Used by polylang/actions/e2e to build the Playwright browser cache key. Must be + * run from the consumer repository root (where npm ci has installed dependencies). + * + * Resolution order: + * 1. node_modules/@playwright/test/package.json (preferred — matches installed binaries) + * 2. package-lock.json (npm lockfile v2/v3 packages path, or legacy dependencies) + * + * @example + * PLAYWRIGHT_VERSION=$(node "${{ github.action_path }}/../bin/get-playwright-version.js") + * + * Output: + * - Prints the semver string to stdout on success. + * - Exits with code 1 and writes an error message to stderr when the version cannot be determined. + */ + +const fs = require( 'fs' ); +const path = require( 'path' ); + +/** + * @param {string} filePath + * @return {Object|null} + */ +const tryReadJson = ( filePath ) => { + try { + return JSON.parse( fs.readFileSync( filePath, 'utf8' ) ); + } catch { + return null; + } +}; + +const root = process.cwd(); +const fromPackage = tryReadJson( + path.join( root, 'node_modules', '@playwright', 'test', 'package.json' ) +); + +if ( fromPackage?.version ) { + process.stdout.write( fromPackage.version ); + process.exit( 0 ); +} + +const lock = tryReadJson( path.join( root, 'package-lock.json' ) ); +const fromLock = lock?.packages?.['node_modules/@playwright/test']?.version + || lock?.dependencies?.['@playwright/test']?.version + || ''; + +if ( ! fromLock ) { + process.stderr.write( 'Could not determine @playwright/test version.' ); + process.exit( 1 ); +} + +process.stdout.write( fromLock ); diff --git a/e2e/action.yml b/e2e/action.yml index f3f12c9..0baf64b 100644 --- a/e2e/action.yml +++ b/e2e/action.yml @@ -3,11 +3,11 @@ name: Run Playwright e2e Tests description: Installs WordPress, starts the server, builds dependencies and run Playwright tests. Currently runs on PHP 8.0 with WordPress latest release. inputs: - container-cache-key: - description: Container cache key. Used to cache wp-env container. + wp-env-cache-key: + description: Extra cache key fragment for the wp-env home directory. Use for inputs not reflected in .wp-env.json (e.g. WooCommerce version, Polylang Pro commit). required: false type: string - default: 'no-external-cache-key' + default: 'default' wp-env-config-path: description: Path to a custom wp-env config file passed to wp-env --config. Default is '' (wp-env default discovery). required: false @@ -28,9 +28,17 @@ runs: with: node-version: 22 + - name: Get Node.js version + id: node-version + run: echo "NODE_VERSION=$(node -v)" >> "$GITHUB_OUTPUT" + shell: bash + + # Repos without a committed lockfile (e.g. Polylang) need one for npm ci / cache key. - name: Set up package-lock.json run: | - npm install --package-lock-only --no-audit + if [ ! -f package-lock.json ]; then + npm install --package-lock-only --no-audit + fi shell: bash - name: Cache node_modules @@ -38,12 +46,16 @@ runs: uses: actions/cache@v4 with: path: '**/node_modules' - key: node_modules-${{ runner.os }}-${{ runner.arch }}-${{ steps.node-version.outputs.NODE_VERSION }}-${{ hashFiles('package-lock.json') }} + key: node_modules-${{ runner.os }}-${{ runner.arch }}-${{ steps.node-version.outputs.NODE_VERSION }}-${{ hashFiles('package.json', 'package-lock.json') }} - name: Install dependencies if: ${{ steps.cache-node_modules.outputs.cache-hit != 'true' }} run: | + if [ -f package-lock.json ]; then npm ci + else + npm install --no-audit + fi shell: bash # Must install PHP deps before wp-env is running to prevent errors. @@ -66,7 +78,8 @@ runs: - name: Get installed Playwright version id: playwright-version run: | - echo "PLAYWRIGHT_VERSION=$(node -e "console.log(require('./package-lock.json').packages['node_modules/@playwright/test'].version)")" >> $GITHUB_ENV + PLAYWRIGHT_VERSION=$(node "${{ github.action_path }}/../bin/get-playwright-version.js") + echo "PLAYWRIGHT_VERSION=$PLAYWRIGHT_VERSION" >> "$GITHUB_ENV" shell: bash - name: Cache Playwright binaries @@ -76,6 +89,8 @@ runs: path: | ~/.cache/ms-playwright key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }} + restore-keys: | + ${{ runner.os }}-playwright- - name: Install Playwright binaries # Only Chromium for the moment. @@ -84,23 +99,40 @@ runs: shell: bash if: steps.playwright-cache.outputs.cache-hit != 'true' + # Pin home so CI does not depend on /snap detection (~/wp-env vs ~/.wp-env). + # Same WP_ENV_HOME behavior in @wordpress/env 10 and 11. + - name: Set wp-env home directory + run: echo "WP_ENV_HOME=${HOME}/.wp-env" >> "$GITHUB_ENV" + shell: bash + + - name: Get @wordpress/env version + id: wp-env-version + run: | + echo "WP_ENV_VERSION=$(node -e "console.log(require('@wordpress/env/package.json').version)")" >> "$GITHUB_OUTPUT" + shell: bash + + # When core is "latest" (null), bust the workdir cache when WordPress.org ships a new release. - name: Get WordPress latest version id: wp-version run: | - echo "WP_VERSION=$(node -e "fetch('https://api.wordpress.org/core/version-check/1.7/').then(r => r.json()).then(data => console.log(data.offers[0].current))")" >> $GITHUB_ENV + echo "WP_VERSION=$(node -e "fetch('https://api.wordpress.org/core/version-check/1.7/').then(r => r.json()).then(data => console.log(data.offers[0].current))")" >> "$GITHUB_ENV" shell: bash - - name: Cache wp-env Docker image - id: docker-cache + # Key: {os}-wp-env-home-{@wordpress/env}-{WP latest}-{hash(.wp-env.json)}-{hash(custom config)|no-custom-config}-{wp-env-cache-key} + - name: Cache wp-env home + id: wp-env-home-cache uses: actions/cache@v4 with: - path: wp-env-image.tar - key: ${{ runner.os }}-wp-env-${{ env.WP_VERSION }}-${{ inputs.container-cache-key }} - - - name: Load cached Docker image (if any) - if: steps.docker-cache.outputs.cache-hit == 'true' - run: | - docker load -i wp-env-image.tar + path: ${{ env.WP_ENV_HOME }} + key: ${{ runner.os }}-wp-env-home-${{ steps.wp-env-version.outputs.WP_ENV_VERSION }}-${{ env.WP_VERSION }}-${{ hashFiles('.wp-env.json') }}-${{ inputs.wp-env-config-path != '' && hashFiles(inputs.wp-env-config-path) || 'no-custom-config' }}-${{ inputs.wp-env-cache-key }} + + # WP_ENV_HOME holds WordPress sources + wp-env-cache.json, not MySQL volumes. + # On a cache hit the config checksum makes wp-env skip `wp core install` against + # empty DB volumes → REST API / rewrite failures. Drop the checksum so start + # reconfigures while still reusing downloaded sources (wp-env 10 and 11). + - name: Force wp-env reconfigure after home cache restore + if: steps.wp-env-home-cache.outputs.cache-hit == 'true' + run: find "${WP_ENV_HOME}" -name 'wp-env-cache.json' -delete shell: bash - name: Install WordPress and start the server @@ -112,14 +144,7 @@ runs: fi shell: bash - - name: Save Docker image to cache - if: steps.docker-cache.outputs.cache-hit != 'true' - run: | - docker image ls - docker save $(docker images --format '{{.Repository}}:{{.Tag}}') -o wp-env-image.tar - shell: bash - - - name: Run Playwright tests with WordPress ${{ env.WP_VERSION }} + - name: Run Playwright tests run: ${{ inputs.playwright-cmd }} shell: bash From a55bfd165c63c8369a538602bebd8bed3a775464 Mon Sep 17 00:00:00 2001 From: Hug0-Drelon Date: Fri, 17 Jul 2026 14:37:51 +0200 Subject: [PATCH 3/3] Revert "perf(e2e): improve node_modules, Playwright and wp-env home caching (#20)" This reverts commit 1fe48f03540b472138a174a2527bddbab523c17e. --- bin/get-playwright-version.js | 56 --------------------------- e2e/action.yml | 73 ++++++++++++----------------------- 2 files changed, 24 insertions(+), 105 deletions(-) delete mode 100644 bin/get-playwright-version.js diff --git a/bin/get-playwright-version.js b/bin/get-playwright-version.js deleted file mode 100644 index 719239e..0000000 --- a/bin/get-playwright-version.js +++ /dev/null @@ -1,56 +0,0 @@ -'use strict'; - -/** - * Resolves the installed @playwright/test version for CI caching. - * - * Used by polylang/actions/e2e to build the Playwright browser cache key. Must be - * run from the consumer repository root (where npm ci has installed dependencies). - * - * Resolution order: - * 1. node_modules/@playwright/test/package.json (preferred — matches installed binaries) - * 2. package-lock.json (npm lockfile v2/v3 packages path, or legacy dependencies) - * - * @example - * PLAYWRIGHT_VERSION=$(node "${{ github.action_path }}/../bin/get-playwright-version.js") - * - * Output: - * - Prints the semver string to stdout on success. - * - Exits with code 1 and writes an error message to stderr when the version cannot be determined. - */ - -const fs = require( 'fs' ); -const path = require( 'path' ); - -/** - * @param {string} filePath - * @return {Object|null} - */ -const tryReadJson = ( filePath ) => { - try { - return JSON.parse( fs.readFileSync( filePath, 'utf8' ) ); - } catch { - return null; - } -}; - -const root = process.cwd(); -const fromPackage = tryReadJson( - path.join( root, 'node_modules', '@playwright', 'test', 'package.json' ) -); - -if ( fromPackage?.version ) { - process.stdout.write( fromPackage.version ); - process.exit( 0 ); -} - -const lock = tryReadJson( path.join( root, 'package-lock.json' ) ); -const fromLock = lock?.packages?.['node_modules/@playwright/test']?.version - || lock?.dependencies?.['@playwright/test']?.version - || ''; - -if ( ! fromLock ) { - process.stderr.write( 'Could not determine @playwright/test version.' ); - process.exit( 1 ); -} - -process.stdout.write( fromLock ); diff --git a/e2e/action.yml b/e2e/action.yml index 0baf64b..f3f12c9 100644 --- a/e2e/action.yml +++ b/e2e/action.yml @@ -3,11 +3,11 @@ name: Run Playwright e2e Tests description: Installs WordPress, starts the server, builds dependencies and run Playwright tests. Currently runs on PHP 8.0 with WordPress latest release. inputs: - wp-env-cache-key: - description: Extra cache key fragment for the wp-env home directory. Use for inputs not reflected in .wp-env.json (e.g. WooCommerce version, Polylang Pro commit). + container-cache-key: + description: Container cache key. Used to cache wp-env container. required: false type: string - default: 'default' + default: 'no-external-cache-key' wp-env-config-path: description: Path to a custom wp-env config file passed to wp-env --config. Default is '' (wp-env default discovery). required: false @@ -28,17 +28,9 @@ runs: with: node-version: 22 - - name: Get Node.js version - id: node-version - run: echo "NODE_VERSION=$(node -v)" >> "$GITHUB_OUTPUT" - shell: bash - - # Repos without a committed lockfile (e.g. Polylang) need one for npm ci / cache key. - name: Set up package-lock.json run: | - if [ ! -f package-lock.json ]; then - npm install --package-lock-only --no-audit - fi + npm install --package-lock-only --no-audit shell: bash - name: Cache node_modules @@ -46,16 +38,12 @@ runs: uses: actions/cache@v4 with: path: '**/node_modules' - key: node_modules-${{ runner.os }}-${{ runner.arch }}-${{ steps.node-version.outputs.NODE_VERSION }}-${{ hashFiles('package.json', 'package-lock.json') }} + key: node_modules-${{ runner.os }}-${{ runner.arch }}-${{ steps.node-version.outputs.NODE_VERSION }}-${{ hashFiles('package-lock.json') }} - name: Install dependencies if: ${{ steps.cache-node_modules.outputs.cache-hit != 'true' }} run: | - if [ -f package-lock.json ]; then npm ci - else - npm install --no-audit - fi shell: bash # Must install PHP deps before wp-env is running to prevent errors. @@ -78,8 +66,7 @@ runs: - name: Get installed Playwright version id: playwright-version run: | - PLAYWRIGHT_VERSION=$(node "${{ github.action_path }}/../bin/get-playwright-version.js") - echo "PLAYWRIGHT_VERSION=$PLAYWRIGHT_VERSION" >> "$GITHUB_ENV" + echo "PLAYWRIGHT_VERSION=$(node -e "console.log(require('./package-lock.json').packages['node_modules/@playwright/test'].version)")" >> $GITHUB_ENV shell: bash - name: Cache Playwright binaries @@ -89,8 +76,6 @@ runs: path: | ~/.cache/ms-playwright key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }} - restore-keys: | - ${{ runner.os }}-playwright- - name: Install Playwright binaries # Only Chromium for the moment. @@ -99,40 +84,23 @@ runs: shell: bash if: steps.playwright-cache.outputs.cache-hit != 'true' - # Pin home so CI does not depend on /snap detection (~/wp-env vs ~/.wp-env). - # Same WP_ENV_HOME behavior in @wordpress/env 10 and 11. - - name: Set wp-env home directory - run: echo "WP_ENV_HOME=${HOME}/.wp-env" >> "$GITHUB_ENV" - shell: bash - - - name: Get @wordpress/env version - id: wp-env-version - run: | - echo "WP_ENV_VERSION=$(node -e "console.log(require('@wordpress/env/package.json').version)")" >> "$GITHUB_OUTPUT" - shell: bash - - # When core is "latest" (null), bust the workdir cache when WordPress.org ships a new release. - name: Get WordPress latest version id: wp-version run: | - echo "WP_VERSION=$(node -e "fetch('https://api.wordpress.org/core/version-check/1.7/').then(r => r.json()).then(data => console.log(data.offers[0].current))")" >> "$GITHUB_ENV" + echo "WP_VERSION=$(node -e "fetch('https://api.wordpress.org/core/version-check/1.7/').then(r => r.json()).then(data => console.log(data.offers[0].current))")" >> $GITHUB_ENV shell: bash - # Key: {os}-wp-env-home-{@wordpress/env}-{WP latest}-{hash(.wp-env.json)}-{hash(custom config)|no-custom-config}-{wp-env-cache-key} - - name: Cache wp-env home - id: wp-env-home-cache + - name: Cache wp-env Docker image + id: docker-cache uses: actions/cache@v4 with: - path: ${{ env.WP_ENV_HOME }} - key: ${{ runner.os }}-wp-env-home-${{ steps.wp-env-version.outputs.WP_ENV_VERSION }}-${{ env.WP_VERSION }}-${{ hashFiles('.wp-env.json') }}-${{ inputs.wp-env-config-path != '' && hashFiles(inputs.wp-env-config-path) || 'no-custom-config' }}-${{ inputs.wp-env-cache-key }} - - # WP_ENV_HOME holds WordPress sources + wp-env-cache.json, not MySQL volumes. - # On a cache hit the config checksum makes wp-env skip `wp core install` against - # empty DB volumes → REST API / rewrite failures. Drop the checksum so start - # reconfigures while still reusing downloaded sources (wp-env 10 and 11). - - name: Force wp-env reconfigure after home cache restore - if: steps.wp-env-home-cache.outputs.cache-hit == 'true' - run: find "${WP_ENV_HOME}" -name 'wp-env-cache.json' -delete + path: wp-env-image.tar + key: ${{ runner.os }}-wp-env-${{ env.WP_VERSION }}-${{ inputs.container-cache-key }} + + - name: Load cached Docker image (if any) + if: steps.docker-cache.outputs.cache-hit == 'true' + run: | + docker load -i wp-env-image.tar shell: bash - name: Install WordPress and start the server @@ -144,7 +112,14 @@ runs: fi shell: bash - - name: Run Playwright tests + - name: Save Docker image to cache + if: steps.docker-cache.outputs.cache-hit != 'true' + run: | + docker image ls + docker save $(docker images --format '{{.Repository}}:{{.Tag}}') -o wp-env-image.tar + shell: bash + + - name: Run Playwright tests with WordPress ${{ env.WP_VERSION }} run: ${{ inputs.playwright-cmd }} shell: bash