diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e03d4a5..ac1f7a3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,6 +77,39 @@ jobs: env: CHROMATIC_ARCHIVE_LOCATION: ./test-results + lighthouse: + name: Lighthouse CI + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up pnpm + uses: pnpm/action-setup@v4 + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build + run: pnpm build + + # Tests the static dist/ output directly, so /api/geo and the Vercel + # Analytics script (both Vercel-runtime-only) 404 here even though + # they work in production — accounted for in lighthouserc.json's + # best-practices threshold. + - name: Run Lighthouse CI + uses: treosh/lighthouse-ci-action@v11 + with: + configPath: ./lighthouserc.json + uploadArtifacts: true + temporaryPublicStorage: true + lint: name: Lint + format runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 43a37a6..ed49f68 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ dist/ # playwright output test-results/ playwright-report/ +# lighthouse ci output +.lighthouseci/ # generated types .astro/ diff --git a/README.md b/README.md index f4da86a..4a08657 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # youthphase.dev + + + + + Personal site of Amy Lam. Built with [Astro](https://astro.build) and [Tailwind CSS](https://tailwindcss.com), package-managed with [pnpm](https://pnpm.io), linted with Prettier/ESLint/Stylelint. This @@ -117,6 +122,17 @@ Key files: every sun altitude and fails if any ink/background pairing drops below WCAG AAA — see [the sky section](#the-sky) above. +[Lighthouse CI](https://github.com/GoogleChrome/lighthouse-ci) runs +against every page in the built `dist/` output and fails the build if +Performance drops below 90, Best Practices drops below 95, or +Accessibility or SEO drop below 100 — thresholds set in +[lighthouserc.json](lighthouserc.json). Performance gets a lower floor +because build-to-build timing variance on CI runners is real; Best +Practices gets one because testing the static `dist/` directly (rather +than a deployed Vercel environment) makes `/api/geo` and the Vercel +Analytics script 404, which they don't in production. The badges above +reflect an actual production run, which hits neither issue. + The same Playwright run also feeds [Chromatic](https://www.chromatic.com) visual regression testing via [`@chromatic-com/playwright`](https://www.chromatic.com/docs/playwright/) — @@ -148,8 +164,8 @@ to actually publish. [GitHub Actions](https://github.com/features/actions) (`.github/workflows/ci.yml`) runs the build, `check:contrast`, the full -Playwright suite, and all three linters on every push to `main` and on -every pull request. +Playwright suite, Lighthouse CI, and all three linters on every push to +`main` and on every pull request. ## Deploying (Vercel) diff --git a/lighthouserc.json b/lighthouserc.json new file mode 100644 index 0000000..e70c96a --- /dev/null +++ b/lighthouserc.json @@ -0,0 +1,19 @@ +{ + "ci": { + "collect": { + "staticDistDir": "./dist", + "numberOfRuns": 3 + }, + "assert": { + "assertions": { + "categories:performance": ["error", { "minScore": 0.9 }], + "categories:accessibility": ["error", { "minScore": 1 }], + "categories:best-practices": ["error", { "minScore": 0.95 }], + "categories:seo": ["error", { "minScore": 1 }] + } + }, + "upload": { + "target": "temporary-public-storage" + } + } +} diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index 25f8a29..71e32bc 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -43,6 +43,7 @@ const ogImage = new URL('/og.png', Astro.site);
@@ -59,6 +60,7 @@ const ogImage = new URL('/og.png', Astro.site); @@ -73,7 +75,12 @@ const ogImage = new URL('/og.png', Astro.site); sliding off another circle. sky.ts positions it with the moon and rewrites the shadow path each tick; visibility and the bloom transition live in global.css under html.moon-cycle. --> -