Add dynamic badge for lighthouse scores #157
Workflow file for this run
This file contains 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: Unlighthouse | |
on: | |
push: | |
branches: | |
main | |
pull_request: | |
permissions: | |
pull-requests: write | |
jobs: | |
unlighthouse: | |
runs-on: ubuntu-latest | |
env: | |
COMMENT_ID: unlighthouse-node${{matrix.node-version}} | |
PORT: 8000 | |
CLOUDFLARE_PROJECT: hellobart-unlighthouse | |
strategy: | |
matrix: | |
node-version: [18] | |
steps: | |
- name: Create initial comment | |
uses: marocchino/[email protected] | |
if: github.ref != 'refs/heads/main' | |
with: | |
header: ${{ env.COMMENT_ID }} | |
message: | | |
⚡️ Lighthouse report | |
![loading](https://github.com/bartvdbraak/hellob.art/assets/3996360/0e00b3fc-d5f9-490b-9aa7-07cb4b59f85f) | |
- name: Set variables based on trigger | |
run: | | |
echo "Discovering the environment stage:" | |
if [[ ${{ github.ref == 'refs/heads/main' }} ]]; then | |
echo "CLOUDFLARE_BRANCH=main" >> $GITHUB_ENV | |
else | |
echo "CLOUDFLARE_BRANCH=pull-${{ github.event.pull_request.number }}" >> $GITHUB_ENV | |
fi | |
- name: Checkout repository | |
uses: actions/[email protected] | |
- name: Setup pnpm | |
uses: pnpm/[email protected] | |
with: | |
version: latest | |
- name: Use Node.js ${{ matrix.node-version }} | |
uses: actions/[email protected] | |
with: | |
node-version: ${{ matrix.node-version }} | |
cache: 'pnpm' | |
- name: Retrieve Vercel Preview URL | |
uses: zentered/[email protected] | |
id: vercel_preview_url | |
env: | |
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} | |
with: | |
vercel_project_id: ${{ vars.VERCEL_PROJECT_ID }} | |
- name: Await Vercel Deployment | |
uses: UnlyEd/[email protected] | |
env: | |
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} | |
with: | |
deployment-url: ${{ steps.vercel_preview_url.outputs.preview_url }} | |
timeout: 120 | |
- name: Install Dependencies | |
run: pnpm install -g @unlighthouse/cli puppeteer | |
- name: Run Unlighthouse | |
run: | | |
unlighthouse-ci \ | |
--site "${{ steps.vercel_preview_url.outputs.preview_url }}" \ | |
--reporter jsonExpanded \ | |
--build-static | |
- name: Upload report to Cloudflare pages | |
uses: cloudflare/[email protected] | |
with: | |
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
command: pages deploy .unlighthouse --project-name="${{ env.CLOUDFLARE_PROJECT }}" --branch=${{ env.CLOUDFLARE_BRANCH }} | |
- name: Create result content | |
id: create_result_content | |
uses: actions/[email protected] | |
with: | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
script: | | |
const fs = require('fs'); | |
const result = JSON.parse(fs.readFileSync('.unlighthouse/ci-result.json', 'utf8')); | |
const formatScore = score => `${Math.round(score * 100)} (${score})`; | |
const getEmoji = score => score >= 0.9 ? '🟢' : score >= 0.5 ? '🟠' : '🔴'; | |
const getColor = score => score >= 0.9 ? 'green' : score >= 0.5 ? 'orange' : 'red'; | |
const score = res => `${getEmoji(res)} ${formatScore(res)}`; | |
const reportUrl = `https://${{ env.CLOUDFLARE_BRANCH }}.${{ env.CLOUDFLARE_PROJECT }}.pages.dev`; | |
const comment = [ | |
`⚡️ Lighthouse report for the changes in this PR:`, | |
'| Category | Score |', | |
'| --- | --- |', | |
`| Performance | ${score(result.summary.categories.performance.averageScore)} |`, | |
`| Accessibility | ${score(result.summary.categories.accessibility.averageScore)} |`, | |
`| Best practices | ${score(result.summary.categories['best-practices'].averageScore)} |`, | |
`| SEO | ${score(result.summary.categories.seo.averageScore)} |`, | |
`| *Overall* | ${score(result.summary.score)} |`, | |
'', | |
'*Lighthouse scores for individual routes:*', | |
'', | |
'| Path | Performance | Accessibility | Best practices | SEO | Overall |', | |
'| --- | --- | --- | --- | --- | --- |', | |
`${result.routes.map(route => `| ${route.path} | ${score(route.categories.performance.score)} | ${score(route.categories.accessibility.score)} | ${score(route.categories['best-practices'].score)} | ${score(route.categories.seo.score)} | ${score(route.score)} |`).join('\n')}`, | |
'', | |
'*Lighthouse metrics:*', | |
'', | |
'| Metric | Average Value |', | |
'| --- | --- |', | |
`${Object.entries(result.summary.metrics).map(([metric, { averageNumericValue }]) => `| ${metric} | ${averageNumericValue} |`).join('\n')}`, | |
'', | |
`View the full Lighthouse report [here](${reportUrl}).`, | |
].join('\n'); | |
core.setOutput("comment", comment); | |
core.setOutput("score", `${result.summary.score}`); | |
core.setOutput("scoreColor", getColor(result.summary.score)); | |
- name: Update comment with result | |
uses: marocchino/[email protected] | |
if: github.ref != 'refs/heads/main' | |
with: | |
header: ${{ env.COMMENT_ID }} | |
message: ${{ steps.create_result_content.outputs.comment }} | |
- name: Create Lighthouse Score badge | |
uses: schneegans/[email protected] | |
# if: github.ref == 'refs/heads/main' | |
with: | |
auth: ${{ secrets.GIST_SECRET }} | |
gistID: 795a3d6af5b0db5754cf7279898c3c16 | |
filename: hellob.art-unlighthouse.json | |
namedLogo: Lighthouse | |
label: Lighthouse | |
message: ${{ steps.create_result_content.outputs.score }} | |
color: ${{ steps.create_result_content.outputs.scoreColor }} | |
- name: Update comment on failure | |
uses: marocchino/[email protected] | |
if: failure() && github.ref != 'refs/heads/main' | |
with: | |
header: ${{ env.COMMENT_ID }} | |
message: | | |
⚡️ Lighthouse report failed | |
See deployment for any errors | |
- name: Update comment on cancel | |
uses: marocchino/[email protected] | |
if: cancelled() && github.ref != 'refs/heads/main' | |
with: | |
header: ${{ env.COMMENT_ID }} | |
message: | | |
⚡️ Lighthouse report cancelled |