Skip to content

Commit 0f2aff3

Browse files
committed
add lighthouse ci
1 parent 1917b49 commit 0f2aff3

1 file changed

Lines changed: 119 additions & 0 deletions

File tree

.github/workflows/lighthouse.yml

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
name: Lighthouse Audit
2+
3+
on:
4+
pull_request_target:
5+
types: [opened, synchronize]
6+
7+
permissions:
8+
contents: read
9+
pull-requests: write
10+
11+
jobs:
12+
lighthouse:
13+
if: github.actor != 'dependabot[bot]'
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- name: ⬇️ Checkout PR code
18+
uses: actions/checkout@v4
19+
with:
20+
ref: ${{ github.event.pull_request.head.ref }}
21+
repository: ${{ github.event.pull_request.head.repo.full_name }}
22+
23+
- name: ⏳ Wait for Netlify preview to be live
24+
run: |
25+
PREVIEW_URL="https://deploy-preview-${{ github.event.pull_request.number }}--expressjscom-preview.netlify.app"
26+
echo "PREVIEW_URL=$PREVIEW_URL" >> "$GITHUB_ENV"
27+
for i in {1..3}; do
28+
if curl -s --head "$PREVIEW_URL" | grep "200 OK" > /dev/null; then
29+
echo "Preview is live!"
30+
break
31+
fi
32+
echo "Waiting for Netlify to deploy... ($i/3)"
33+
sleep 10
34+
done
35+
36+
- name: ⚙️ Install Lighthouse
37+
run: npm install -g lighthouse
38+
39+
- name: 📊 Run Lighthouse audits
40+
run: |
41+
mkdir -p lighthouse-report
42+
URLS=(
43+
"$PREVIEW_URL"
44+
"$PREVIEW_URL/en/blog/posts.html"
45+
"$PREVIEW_URL/en/support/"
46+
"$PREVIEW_URL/en/resources/glossary.html"
47+
"$PREVIEW_URL/en/5x/api.html"
48+
)
49+
echo "[" > lighthouse-report/manifest.json
50+
for url in "${URLS[@]}"; do
51+
name=$(echo "$url" | sed 's|https://||;s|[/.]|_|g')
52+
path="./lighthouse-report/$name.report.json"
53+
lighthouse "$url" \
54+
--output json \
55+
--output-path="$path" \
56+
--chrome-flags="--headless"
57+
jq -n --arg url "$url" \
58+
--argjson summary "$(jq '.categories | {
59+
performance: .performance.score,
60+
accessibility: .accessibility.score,
61+
"best-practices": .["best-practices"].score,
62+
seo: .seo.score
63+
}' "$path")" \
64+
'{url: $url, summary: $summary}' >> lighthouse-report/manifest.json
65+
echo "," >> lighthouse-report/manifest.json
66+
done
67+
sed -i '$ s/,$//' lighthouse-report/manifest.json
68+
echo "]" >> lighthouse-report/manifest.json
69+
70+
# create dummy links file
71+
jq -n '{
72+
'"$(for url in "${URLS[@]}"; do echo "\"$url\": \"$url\","; done | sed '$ s/,$//')"'
73+
}' > lighthouse-report/links.json
74+
75+
- name: 📝 Format comment
76+
id: format
77+
uses: actions/github-script@v7
78+
with:
79+
script: |
80+
const fs = require('fs');
81+
82+
const stoplight = res => (res >= 90 ? '🟢' : res >= 75 ? '🟠' : '🔴');
83+
const normalizeScore = res => Math.round(res * 100);
84+
const formatScore = res => {
85+
const s = normalizeScore(res);
86+
return `${stoplight(s)} ${s}`;
87+
};
88+
89+
const results = JSON.parse(fs.readFileSync('./lighthouse-report/manifest.json', 'utf8'));
90+
const links = JSON.parse(fs.readFileSync('./lighthouse-report/links.json', 'utf8'));
91+
92+
const header = [
93+
'## 🚦 Lighthouse Results',
94+
'| URL | Perf | A11y | Best Practices | SEO | Report |',
95+
'| --- | ---- | ---- | -------------- | --- | ------ |',
96+
];
97+
98+
const rows = results.map(({ url, summary }) => {
99+
const short = `[${new URL(url).pathname}](${url})`;
100+
const perf = formatScore(summary.performance);
101+
const a11y = formatScore(summary.accessibility);
102+
const bp = formatScore(summary['best-practices']);
103+
const seo = formatScore(summary.seo);
104+
return `${short} | ${perf} | ${a11y} | ${bp} | ${seo} | [🔗](${links[url]})`;
105+
});
106+
107+
const comment = [...header, ...rows].join('\n');
108+
core.setOutput('comment', comment);
109+
110+
- name: 💬 Comment on PR
111+
uses: actions/github-script@v7
112+
with:
113+
script: |
114+
github.rest.issues.createComment({
115+
issue_number: context.payload.pull_request.number,
116+
owner: context.repo.owner,
117+
repo: context.repo.repo,
118+
body: `${{ steps.format.outputs.comment }}`
119+
});

0 commit comments

Comments
 (0)