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
74 changes: 74 additions & 0 deletions .github/workflows/leave-comment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Adapted from https://github.com/nodejs/nodejs.org/blob/main/.github/workflows/leave-comment.yml
name: Leave Comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing this was adopted from https://github.com/nodejs/nodejs.org/blob/main/.github/workflows/leave-comment.yml? Can you add a comment so we know to reference that workflow

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes , I have used the nodeJS workflow here, and sure will be referencing this workflow


on:
workflow_run: # zizmor: ignore[dangerous-triggers]
workflows: [Lighthouse]
types: [completed]

permissions:
contents: read
actions: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.workflow_run.id }}
cancel-in-progress: true

jobs:
leave-comment:
name: Leave Comment
runs-on: ubuntu-latest
permissions:
actions: read
pull-requests: write

steps:
- name: Download Comment Artifact
id: download
continue-on-error: true
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: pr-comment
path: pr-comment
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Resolve Pull Request Number
id: pr
if: steps.download.outcome == 'success'
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const run = context.payload.workflow_run;

if (run.pull_requests && run.pull_requests.length) {
core.setOutput('number', run.pull_requests[0].number);
return;
}

const match = await github.rest.pulls
.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
head: `${run.head_repository.owner.login}:${run.head_branch}`,
sort: 'updated',
direction: 'desc',
per_page: 1,
})
.then(r => r.data[0]);

if (!match) {
core.info(`No open pull request found for HEAD ${run.head_sha}`);
return;
}

core.setOutput('number', match.number);

- name: Add Comment to PR
if: steps.download.outcome == 'success' && steps.pr.outputs.number != ''
uses: thollander/actions-comment-pull-request@e2c37e53a7d2227b61585343765f73a9ca57eda9 # v3.0.0
with:
file-path: pr-comment/comment.md
comment-tag: lighthouse_audit
pr-number: ${{ steps.pr.outputs.number }}
77 changes: 77 additions & 0 deletions .github/workflows/lighthouse.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Adapted from https://github.com/nodejs/nodejs.org/blob/main/.github/workflows/lighthouse.yml
name: Lighthouse

on:
pull_request:
branches: [main]

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true

permissions:
contents: read

jobs:
lighthouse:
name: Lighthouse Report
if: startsWith(github.event.pull_request.head.ref, 'dependabot/') == false
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Wait for Vercel preview deployment
id: preview
uses: patrickedqvist/wait-for-vercel-preview@06c79330064b0e6ef7a2574603b62d3c98789125 # v1.3.2
with:
token: ${{ secrets.GITHUB_TOKEN }}
max_timeout: 300
check_interval: 10

- name: Audit preview URLs with Lighthouse
id: lighthouse
uses: treosh/lighthouse-ci-action@3e7e23fb74242897f95c0ba9cabad3d0227b9b18 # v12
with:
configPath: ./.lighthouserc.json
uploadArtifacts: true
temporaryPublicStorage: true
urls: |
${{ steps.preview.outputs.url }}/
${{ steps.preview.outputs.url }}/about
${{ steps.preview.outputs.url }}/about/sponsors
${{ steps.preview.outputs.url }}/docs
${{ steps.preview.outputs.url }}/guides
Comment thread
avivkeller marked this conversation as resolved.
${{ steps.preview.outputs.url }}/blog

- name: Format Lighthouse report
id: format
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
LIGHTHOUSE_RESULT: ${{ steps.lighthouse.outputs.manifest }}
LIGHTHOUSE_LINKS: ${{ steps.lighthouse.outputs.links }}
VERCEL_PREVIEW_URL: ${{ steps.preview.outputs.url }}
with:
script: |
const { formatLighthouseResults } = await import(
'${{ github.workspace }}/scripts/lighthouse/index.mjs'
);
await formatLighthouseResults({ core });

- name: Prepare PR comment
env:
COMMENT: ${{ steps.format.outputs.comment }}
run: |
set -euo pipefail
mkdir -p pr-comment
printf '%s' "$COMMENT" > pr-comment/comment.md

- name: Upload PR comment
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: pr-comment
path: pr-comment/
retention-days: 1
19 changes: 19 additions & 0 deletions .lighthouserc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"ci": {
"collect": {
"numberOfRuns": 1,
"settings": {
"preset": "desktop",
"skipAudits": ["is-crawlable"]
}
},
"assert": {
"assertions": {
"categories:performance": ["warn", { "minScore": 0.9 }],
"categories:accessibility": ["warn", { "minScore": 0.9 }],
"categories:best-practices": ["warn", { "minScore": 0.9 }],
"categories:seo": ["warn", { "minScore": 0.9 }]
}
}
}
}
62 changes: 62 additions & 0 deletions scripts/lighthouse/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Adapted from https://github.com/nodejs/nodejs.org/blob/main/apps/site/scripts/lighthouse/index.mjs

const CATEGORIES = [
['performance', 'Performance'],
['accessibility', 'Accessibility'],
['best-practices', 'Best Practices'],
['seo', 'SEO'],
];

const formatScore = score => {
if (score === undefined || score === null) {
return 'n/a';
}

const value = Math.round(score * 100);
const emoji = value >= 90 ? '🟢' : value >= 75 ? '🟠' : '🔴';

return `${emoji} ${value}`;
};

export const formatLighthouseResults = ({ core }) => {
const previewUrl = process.env.VERCEL_PREVIEW_URL ?? '';

const results = JSON.parse(process.env.LIGHTHOUSE_RESULT || '[]');
const links = JSON.parse(process.env.LIGHTHOUSE_LINKS || '{}');

const runs = results.filter(result => result.isRepresentativeRun ?? true);

const header =
'| URL | ' +
CATEGORIES.map(([, label]) => label).join(' | ') +
' | Report |';
const divider = `|${' --- |'.repeat(CATEGORIES.length + 2)}`;

const rows = runs.map(({ url, summary }) => {
const path = previewUrl ? url.replace(previewUrl, '') || '/' : url;
const scores = CATEGORIES.map(([key]) => formatScore(summary?.[key])).join(
' | '
);
const report = links[url] ? `[🔗](${links[url]})` : 'n/a';

return `| [${path}](${url}) | ${scores} | ${report} |`;
});

const comment = [
'## ⚡ Lighthouse report',
'',
previewUrl
? `Audited the Vercel preview deployment: ${previewUrl}`
: 'Audited the Vercel preview deployment.',
'',
header,
divider,
...rows,
'',
'> Scores are advisory (warn at 90); they do not fail the build. See `.lighthouserc.json`.',
].join('\n');

core.setOutput('comment', comment);

return comment;
};
Loading