From 0f2aff39c99fb5fdd85538a73427d6bddd31691c Mon Sep 17 00:00:00 2001 From: Shubham Oulkar Date: Wed, 23 Jul 2025 11:28:33 +0530 Subject: [PATCH] add lighthouse ci --- .github/workflows/lighthouse.yml | 119 +++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 .github/workflows/lighthouse.yml diff --git a/.github/workflows/lighthouse.yml b/.github/workflows/lighthouse.yml new file mode 100644 index 0000000000..9a0a9b0f47 --- /dev/null +++ b/.github/workflows/lighthouse.yml @@ -0,0 +1,119 @@ +name: Lighthouse Audit + +on: + pull_request_target: + types: [opened, synchronize] + +permissions: + contents: read + pull-requests: write + +jobs: + lighthouse: + if: github.actor != 'dependabot[bot]' + runs-on: ubuntu-latest + + steps: + - name: ⬇️ Checkout PR code + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.ref }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + + - name: ⏳ Wait for Netlify preview to be live + run: | + PREVIEW_URL="https://deploy-preview-${{ github.event.pull_request.number }}--expressjscom-preview.netlify.app" + echo "PREVIEW_URL=$PREVIEW_URL" >> "$GITHUB_ENV" + for i in {1..3}; do + if curl -s --head "$PREVIEW_URL" | grep "200 OK" > /dev/null; then + echo "Preview is live!" + break + fi + echo "Waiting for Netlify to deploy... ($i/3)" + sleep 10 + done + + - name: ⚙️ Install Lighthouse + run: npm install -g lighthouse + + - name: 📊 Run Lighthouse audits + run: | + mkdir -p lighthouse-report + URLS=( + "$PREVIEW_URL" + "$PREVIEW_URL/en/blog/posts.html" + "$PREVIEW_URL/en/support/" + "$PREVIEW_URL/en/resources/glossary.html" + "$PREVIEW_URL/en/5x/api.html" + ) + echo "[" > lighthouse-report/manifest.json + for url in "${URLS[@]}"; do + name=$(echo "$url" | sed 's|https://||;s|[/.]|_|g') + path="./lighthouse-report/$name.report.json" + lighthouse "$url" \ + --output json \ + --output-path="$path" \ + --chrome-flags="--headless" + jq -n --arg url "$url" \ + --argjson summary "$(jq '.categories | { + performance: .performance.score, + accessibility: .accessibility.score, + "best-practices": .["best-practices"].score, + seo: .seo.score + }' "$path")" \ + '{url: $url, summary: $summary}' >> lighthouse-report/manifest.json + echo "," >> lighthouse-report/manifest.json + done + sed -i '$ s/,$//' lighthouse-report/manifest.json + echo "]" >> lighthouse-report/manifest.json + + # create dummy links file + jq -n '{ + '"$(for url in "${URLS[@]}"; do echo "\"$url\": \"$url\","; done | sed '$ s/,$//')"' + }' > lighthouse-report/links.json + + - name: 📝 Format comment + id: format + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + + const stoplight = res => (res >= 90 ? '🟢' : res >= 75 ? '🟠' : '🔴'); + const normalizeScore = res => Math.round(res * 100); + const formatScore = res => { + const s = normalizeScore(res); + return `${stoplight(s)} ${s}`; + }; + + const results = JSON.parse(fs.readFileSync('./lighthouse-report/manifest.json', 'utf8')); + const links = JSON.parse(fs.readFileSync('./lighthouse-report/links.json', 'utf8')); + + const header = [ + '## 🚦 Lighthouse Results', + '| URL | Perf | A11y | Best Practices | SEO | Report |', + '| --- | ---- | ---- | -------------- | --- | ------ |', + ]; + + const rows = results.map(({ url, summary }) => { + const short = `[${new URL(url).pathname}](${url})`; + const perf = formatScore(summary.performance); + const a11y = formatScore(summary.accessibility); + const bp = formatScore(summary['best-practices']); + const seo = formatScore(summary.seo); + return `${short} | ${perf} | ${a11y} | ${bp} | ${seo} | [🔗](${links[url]})`; + }); + + const comment = [...header, ...rows].join('\n'); + core.setOutput('comment', comment); + + - name: 💬 Comment on PR + uses: actions/github-script@v7 + with: + script: | + github.rest.issues.createComment({ + issue_number: context.payload.pull_request.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `${{ steps.format.outputs.comment }}` + });