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
96 changes: 96 additions & 0 deletions .github/workflows/lighthouse-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: lighthouse-ci

on:
pull_request:
branches: [main]
paths:
- "themes/**"
- "tests/lighthouse/**"
- "lighthouserc.json"
- ".github/workflows/lighthouse-ci.yml"
- "package.json"
- "pnpm-lock.yaml"
push:
branches: [main]
paths:
- "themes/**"
- "tests/lighthouse/**"
- "lighthouserc.json"

permissions:
contents: read
pull-requests: write
checks: write

concurrency:
group: lighthouse-ci-${{ github.ref }}
cancel-in-progress: true

jobs:
lighthouse:
name: Budgets + Core Web Vitals
runs-on: ubuntu-latest
# Soft-fail while baselines settle. Flip to `false` once the suite has
# produced stable results for ~2 weeks against `main`. The numbers in
# lighthouserc.json + tests/lighthouse/budgets.json are intentionally
# lenient at first — tighten them before flipping.
continue-on-error: true
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Node 20
uses: actions/setup-node@v4
with:
node-version: "20"

- name: Set up pnpm
uses: pnpm/action-setup@v4
with:
version: "9.15.0"
run_install: false

- name: Restore pnpm store
uses: actions/cache@v4
with:
path: ~/.local/share/pnpm/store
key: pnpm-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
pnpm-${{ runner.os }}-

- name: Install Node deps
run: pnpm install --frozen-lockfile

- name: Prepare .env for docker compose
run: cp .env.example .env

- name: Boot WordPress stack
run: |
docker compose up -d wordpress db
for i in $(seq 1 90); do
if curl --silent --fail --max-time 2 http://localhost:8080/ >/dev/null 2>&1; then
echo "WordPress responding."
break
fi
sleep 2
done

- name: Install WooCommerce (no sample data)
env:
WC_INSTALL_SAMPLE_DATA: "false"
run: docker compose --profile woocommerce up --exit-code-from woocommerce-installer woocommerce-installer

- name: Seed deterministic content
run: bash tests/visual/seed.sh

- name: Run Lighthouse CI
id: lhci
uses: treosh/lighthouse-ci-action@v12
with:
configPath: ./lighthouserc.json
uploadArtifacts: true
temporaryPublicStorage: true

- name: Annotate failing budgets
if: always()
run: node tests/lighthouse/annotate-report.mjs .lighthouseci/
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ yarn.lock
tests/visual/actual/
tests/visual/diffs/
tests/visual/report.json

# Lighthouse CI scratch — local report output
.lighthouseci/
composer.lock

# Environment & Config Files
Expand Down
21 changes: 21 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,27 @@ templates and fails if it diverges, so:
— the validation workflow's plugin matrix auto-discovers any directory
matching that glob.

### Performance budgets

PRs that touch `themes/**` are checked by Lighthouse CI against resource,
timing, and category-score budgets defined in
[`tests/lighthouse/budgets.json`](tests/lighthouse/budgets.json) and
[`lighthouserc.json`](lighthouserc.json). Failures appear as native PR
check annotations.

To debug locally:

```bash
pnpm lighthouse:run # boots Lighthouse, asserts against budgets
pnpm lighthouse:open # opens the HTML reports
```

If your change is intentionally heavier (e.g. you added a justified new
script or font), update the budget in the same PR and explain the bump in
the commit body. See
[tests/lighthouse/README.md](tests/lighthouse/README.md) for the full
workflow.

### Visual regression

PRs that touch `themes/**` automatically run the visual regression suite,
Expand Down
32 changes: 32 additions & 0 deletions lighthouserc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"$comment": "Lighthouse CI config. See https://github.com/GoogleChrome/lighthouse-ci/blob/main/docs/configuration.md. Mobile preset is the Lighthouse default — keeping it implicit. Resource budgets live in tests/lighthouse/budgets.json so they can be tuned without touching CI config.",
"ci": {
"collect": {
"url": [
"http://localhost:8080/",
"http://localhost:8080/shop/",
"http://localhost:8080/product/test-hoodie/",
"http://localhost:8080/cart/"
],
"numberOfRuns": 3,
"settings": {
"budgetsPath": "./tests/lighthouse/budgets.json",
"skipAudits": ["uses-http2"]
}
},
"assert": {
"assertions": {
"performance-budget": ["error", { "maxLength": 0 }],
"timing-budget": ["error", { "maxLength": 0 }],
"categories:performance": ["error", { "minScore": 0.70 }],
"categories:accessibility": ["error", { "minScore": 0.90 }],
"categories:best-practices": ["warn", { "minScore": 0.90 }],
"categories:seo": ["warn", { "minScore": 0.90 }],
"cumulative-layout-shift": ["error", { "maxNumericValue": 0.1 }]
}
},
"upload": {
"target": "temporary-public-storage"
}
}
}
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,20 @@
"visual:diff": "node scripts/visual-diff.js --batch tests/visual/actual tests/visual/baselines --output-dir tests/visual/diffs --threshold 0.005 --json > tests/visual/report.json && node tests/visual/print-report.mjs tests/visual/report.json",
"visual:update": "bash scripts/visual-update-baselines.sh",
"visual:seed": "bash tests/visual/seed.sh",
"lighthouse:run": "lhci autorun --config=./lighthouserc.json",
"lighthouse:collect": "lhci collect --config=./lighthouserc.json",
"lighthouse:assert": "lhci assert --config=./lighthouserc.json",
"lighthouse:open": "lhci open",
"lint:commits": "commitlint --from=$(git merge-base origin/main HEAD) --to=HEAD",
"lint:commits:last": "commitlint --from=HEAD~1 --to=HEAD",
"test:visual": "pnpm visual:diff",
"test:lighthouse": "pnpm lighthouse:run",
"playwright:install": "playwright install --with-deps chromium"
},
"devDependencies": {
"@commitlint/cli": "^19.5.0",
"@commitlint/config-conventional": "^19.5.0",
"@lhci/cli": "^0.14.0",
"pixelmatch": "^7.1.0",
"playwright": "1.60.0",
"pngjs": "^7.0.0"
Expand Down
Loading
Loading