Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions .github/actions/e2e-suite/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
name: Run e2e suite
description: >-
Build the plugin, boot wp-env against a given WordPress core, and run the
Playwright suite. Shared by the blocking and experimental matrix jobs so
the two cannot drift apart.

inputs:
label:
description: Short lane name, used in artifact names (e.g. "7.1").
required: true
core:
description: wp-env core source for this lane (e.g. WordPress/WordPress#7.1).
required: true
unpinned_plugins:
description: >-
When "true", ignore the Advanced Query Loop version pinned in
.wp-env.json and use its latest release.
required: false
default: 'false'
comment_on_pr:
description: Whether to leave a sticky Playwright report comment on the PR.
required: false
default: 'false'

outputs:
outcome:
description: '"success" or "failure" — whether the Playwright run passed.'
value: ${{ steps.tests.outputs.outcome }}

runs:
using: composite
steps:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 24
cache: 'npm'

- name: Install dependencies
shell: bash
run: npm i

- name: Build plugin
shell: bash
run: npm run build

- name: Install Playwright Browsers
shell: bash
run: npx playwright install --with-deps chromium

# .wp-env.json pins Advanced Query Loop so that re-running an old green
# commit stays green. This override deliberately un-pins it for the
# scheduled early-warning run. Core is not touched here — it comes from
# WP_ENV_CORE below.
- name: Un-pin Advanced Query Loop
if: inputs.unpinned_plugins == 'true'
shell: bash
run: |
cat > .wp-env.override.json <<'JSON'
{
"plugins": [
".",
"https://downloads.wordpress.org/plugin/advanced-query-loop.zip"
]
}
JSON
cat .wp-env.override.json

- name: Start WordPress environment
shell: bash
env:
WP_ENV_CORE: ${{ inputs.core }}
run: npm run wp-env start

- name: Wait for WordPress to be ready
shell: bash
run: |
timeout 60 bash -c 'until curl -sSf http://localhost:8889 > /dev/null 2>&1; do sleep 2; done' || echo "WordPress may not be fully ready"
sleep 5

- name: Debug - Check WordPress status
shell: bash
run: |
curl -I http://localhost:8889 || echo "WordPress not responding"
docker ps
# Confirms the lane really is running the core it claims to,
# rather than every lane silently testing the same version.
npx wp-env run tests-cli wp core version || true

# continue-on-error is not available to composite steps, so record the
# outcome by hand and let the caller decide whether it is fatal.
- name: Run Playwright tests
id: tests
shell: bash
env:
CI: true
run: |
if npm run test:e2e; then
echo "outcome=success" >> "$GITHUB_OUTPUT"
else
echo "outcome=failure" >> "$GITHUB_OUTPUT"
fi

- name: Stop WordPress environment
if: always()
shell: bash
run: npm run wp-env stop || true

- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report-wp-${{ inputs.label }}
path: test-results/
retention-days: 30
if-no-files-found: ignore

- name: Comment PR with test results
uses: daun/playwright-report-comment@v3
if: always() && github.event_name == 'pull_request'
continue-on-error: true
with:
report-file: test-results/results.json
report-tag: wp-${{ inputs.label }}
comment-title: 'Playwright test results — WP ${{ inputs.label }}'
create-comment: ${{ inputs.comment_on_pr }}
job-summary: true
78 changes: 78 additions & 0 deletions .github/workflows/e2e-latest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: E2E (latest AQL)

# Early warning for third-party plugin drift.
#
# .wp-env.json pins Advanced Query Loop to an exact release so that PR CI is
# reproducible and re-running an old green commit stays green. The trade-off is
# that a breaking AQL release is invisible until someone bumps the pin — which
# is exactly how AQL 5.0.0 broke the suite. This runs the suite against AQL's
# latest release on a schedule, so we find out on our own time.
#
# The WordPress core axis is not covered here: the main Playwright matrix
# already runs a non-blocking `nightly` lane against core trunk on every push.
# So this pins core to current stable and varies only the plugin.
#
# It never runs on pull requests, so a failure here cannot block a merge.

on:
schedule:
# 05:00 UTC every Monday.
- cron: '0 5 * * 1'
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true

jobs:
e2e:
name: Playwright
permissions:
contents: read
pull-requests: write
uses: ./.github/workflows/playwright-tests.yml
with:
# Pinned to the lane that is green, so a failure here means an AQL
# regression and nothing else. Pointing this at 7.0/7.1 would fail
# every week on the known WordPress 7.x gaps and bury the signal.
core_matrix: '[{ "label": "6.9", "core": "WordPress/WordPress#6.9.7", "comment": false }]'
# Core trunk is already covered by the nightly lane on every push.
experimental_matrix: '[]'
unpinned_plugins: true

report:
name: Report drift
needs: e2e
if: failure() && github.event_name == 'schedule'
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
steps:
- name: Open or update the drift issue
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
set -euo pipefail

title='E2E suite fails against the latest Advanced Query Loop'
body=$(printf '%s\n' \
'The scheduled `E2E (latest AQL)` run failed.' \
'' \
'The suite passes against the Advanced Query Loop version pinned in' \
'`.wp-env.json` but fails against its latest release, so bumping that pin' \
'will break PR CI until the suite is updated.' \
'' \
"Failing run: ${RUN_URL}")

# One rolling issue rather than one per week.
existing=$(gh issue list --state open --search "$title in:title" \
--json number --jq '.[0].number // empty')

if [ -n "$existing" ]; then
gh issue comment "$existing" --body "$body"
else
gh issue create --title "$title" --body "$body"
fi
Loading
Loading