Lighthouse CI #122
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Lighthouse CI | |
| on: | |
| deployment_status: | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| concurrency: | |
| group: lighthouse-${{ github.event.deployment.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| lighthouse: | |
| if: github.event.deployment_status.state == 'success' && github.event.deployment_status.environment == 'Preview' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Create Lighthouse config | |
| run: | | |
| jq -n --arg secret "$VERCEL_BYPASS_SECRET" \ | |
| '{ci:{collect:{settings:{extraHeaders:{"x-vercel-protection-bypass":$secret}}}}}' \ | |
| > /tmp/lighthouserc.json | |
| env: | |
| VERCEL_BYPASS_SECRET: ${{ secrets.VERCEL_AUTOMATION_BYPASS_SECRET }} | |
| - name: Lighthouse audit | |
| id: lighthouse | |
| uses: treosh/lighthouse-ci-action@v12 | |
| with: | |
| urls: | | |
| ${{ github.event.deployment_status.target_url }}/ | |
| ${{ github.event.deployment_status.target_url }}/blog | |
| ${{ github.event.deployment_status.target_url }}/about | |
| runs: 3 | |
| configPath: /tmp/lighthouserc.json | |
| budgetPath: .github/lighthouse-budget.json | |
| uploadArtifacts: true | |
| - name: Find PR number | |
| id: find-pr | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| const { data: prs } = await github.rest.repos.listPullRequestsAssociatedWithCommit({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| commit_sha: context.payload.deployment.sha, | |
| }); | |
| const open = prs.find((pr) => pr.state === 'open'); | |
| if (open) { | |
| core.setOutput('number', open.number); | |
| } | |
| - name: Format results | |
| id: format | |
| if: always() && steps.find-pr.outputs.number | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const results = ${{ steps.lighthouse.outputs.manifest }}; | |
| let comment = '## Lighthouse Results\n\n'; | |
| comment += '| URL | Perf | A11y | BP | SEO | LCP | FCP | TBT | CLS |\n'; | |
| comment += '|-----|------|------|----|-----|-----|-----|-----|-----|\n'; | |
| for (const result of results) { | |
| const url = new URL(result.url).pathname || '/'; | |
| const perf = Math.round(result.summary.performance * 100); | |
| const a11y = Math.round(result.summary.accessibility * 100); | |
| const bp = Math.round(result.summary['best-practices'] * 100); | |
| const seo = Math.round(result.summary.seo * 100); | |
| const report = JSON.parse(fs.readFileSync(result.jsonPath, 'utf8')); | |
| const lcp = (report.audits['largest-contentful-paint'].numericValue / 1000).toFixed(2) + 's'; | |
| const fcp = (report.audits['first-contentful-paint'].numericValue / 1000).toFixed(2) + 's'; | |
| const tbt = Math.round(report.audits['total-blocking-time'].numericValue) + 'ms'; | |
| const cls = report.audits['cumulative-layout-shift'].numericValue.toFixed(3); | |
| comment += `| ${url} | ${perf} | ${a11y} | ${bp} | ${seo} | ${lcp} | ${fcp} | ${tbt} | ${cls} |\n`; | |
| } | |
| core.setOutput('comment', comment); | |
| - name: Post comment | |
| if: always() && steps.find-pr.outputs.number | |
| uses: marocchino/sticky-pull-request-comment@v3 | |
| with: | |
| header: lighthouse | |
| number: ${{ steps.find-pr.outputs.number }} | |
| message: ${{ steps.format.outputs.comment }} |