Skip to content

Commit c75ec31

Browse files
ci: run lighthouse report (#1985)
1 parent abee42a commit c75ec31

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed

.github/workflows/lighthouse.yml

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
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.sha }}
21+
repository: ${{ github.event.pull_request.head.repo.full_name }}
22+
23+
- name: Setup Node.js with npm cache
24+
uses: actions/setup-node@v4
25+
with:
26+
node-version: '22.x'
27+
cache: 'npm'
28+
29+
- name: Install dependencies
30+
run: npm install lighthouse
31+
32+
- name: Wait for Netlify preview to be live
33+
run: |
34+
PREVIEW_URL="https://deploy-preview-${{ github.event.pull_request.number }}--expressjscom-preview.netlify.app"
35+
echo "PREVIEW_URL=$PREVIEW_URL" >> "$GITHUB_ENV"
36+
for i in {1..2}; do
37+
if curl -s --head "$PREVIEW_URL" | grep "200 OK" > /dev/null; then
38+
echo "Preview is live!"
39+
break
40+
fi
41+
echo "Waiting for Netlify to deploy... ($i/2)"
42+
sleep 10
43+
done
44+
45+
- name: Run Lighthouse audits
46+
run: |
47+
URLS=(
48+
"$PREVIEW_URL"
49+
"$PREVIEW_URL/en/blog/posts.html"
50+
"$PREVIEW_URL/en/5x/api.html"
51+
)
52+
53+
echo "## 🚦 Lighthouse Results (Mobile & Desktop)" > lighthouse-report.md
54+
echo "| URL | Device | Perf | A11y | Best Practices | ⚠️ SEO score unreliable |" >> lighthouse-report.md
55+
echo "| --- | ------ | ---- | ---- | -------------- | --- |" >> lighthouse-report.md
56+
57+
for device in mobile desktop; do
58+
for url in "${URLS[@]}"; do
59+
if [ "$device" = "desktop" ]; then
60+
lighthouse_args="--preset=desktop"
61+
else
62+
lighthouse_args="--form-factor=mobile"
63+
fi
64+
65+
npx lighthouse "$url" \
66+
$lighthouse_args \
67+
--output json \
68+
--output-path="lighthouse-report-${device}.json" \
69+
--chrome-flags="--headless"
70+
71+
report="lighthouse-report-${device}.json"
72+
perf=$(jq '.categories | .performance.score * 100' $report)
73+
a11y=$(jq '.categories | .accessibility.score * 100' $report)
74+
bp=$(jq '.categories | .["best-practices"].score * 100' $report)
75+
seo=$(jq '.categories | .seo.score * 100' $report)
76+
77+
stoplight() {
78+
if (( $(echo "$1 >= 90" | bc -l) )); then echo "🟢";
79+
elif (( $(echo "$1 >= 75" | bc -l) )); then echo "🟠";
80+
else echo "🔴"; fi
81+
}
82+
83+
perf_stoplight=$(stoplight $perf)
84+
a11y_stoplight=$(stoplight $a11y)
85+
bp_stoplight=$(stoplight $bp)
86+
seo_stoplight=$(stoplight $seo)
87+
88+
path=$(echo "$url" | sed "s|$PREVIEW_URL||")
89+
if [ -z "$path" ]; then path="/"; fi
90+
91+
echo "| $path | $device | $perf_stoplight $(printf "%.0f" $perf) | $a11y_stoplight $(printf "%.0f" $a11y) | $bp_stoplight $(printf "%.0f" $bp) | $seo_stoplight $(printf "%.0f" $seo) |" >> lighthouse-report.md
92+
done
93+
done
94+
95+
- name: Log Lighthouse report
96+
run: |
97+
cat lighthouse-report.md
98+
99+
- name: Upload Lighthouse reports as artifacts
100+
uses: actions/upload-artifact@v4
101+
with:
102+
name: lighthouse-reports
103+
path: |
104+
lighthouse-report.md
105+
106+
- name: Comment on PR with Lighthouse results
107+
uses: actions/github-script@v7
108+
with:
109+
github-token: ${{ secrets.GITHUB_TOKEN }}
110+
script: |
111+
const fs = require('fs');
112+
const report = fs.readFileSync('lighthouse-report.md', 'utf8');
113+
114+
const { data: comments } = await github.rest.issues.listComments({
115+
issue_number: context.payload.pull_request.number,
116+
owner: context.repo.owner,
117+
repo: context.repo.repo,
118+
});
119+
120+
const botComment = comments.find(comment =>
121+
comment.user.type === 'Bot' &&
122+
comment.body.includes('🚦Lighthouse Results (Mobile & Desktop)')
123+
);
124+
125+
if (botComment) {
126+
await github.rest.issues.updateComment({
127+
comment_id: botComment.id,
128+
owner: context.repo.owner,
129+
repo: context.repo.repo,
130+
body: report
131+
});
132+
} else {
133+
await github.rest.issues.createComment({
134+
issue_number: context.payload.pull_request.number,
135+
owner: context.repo.owner,
136+
repo: context.repo.repo,
137+
body: report
138+
});
139+
}
140+

0 commit comments

Comments
 (0)