Skip to content

Commit e871c60

Browse files
authored
Add lighthouse to build workflow (#400)
* Workflow: Add lighthouse to build * Lighthouse: Move to performance folder * Lighthouse: Add readme
1 parent 03bc483 commit e871c60

File tree

6 files changed

+2884
-1
lines changed

6 files changed

+2884
-1
lines changed

.github/workflows/build-push.yml

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ on:
88
env:
99
REPO_OWNER: "nginx"
1010
REPO_NAME: "documentation"
11+
FRONT_DOOR_USERNAME: ${{ secrets.FRONT_DOOR_USERNAME }}
12+
FRONT_DOOR_PASSWORD: ${{ secrets.FRONT_DOOR_PASSWORD }}
13+
GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
1114

1215
jobs:
1316
deploy-example-site:
@@ -24,4 +27,49 @@ jobs:
2427
auto_deploy_env: "prod"
2528
secrets:
2629
AZURE_CREDENTIALS: ${{secrets.AZURE_CREDENTIALS_DOCS}}
27-
AZURE_KEY_VAULT: ${{secrets.AZURE_KEY_VAULT_DOCS}}
30+
AZURE_KEY_VAULT: ${{secrets.AZURE_KEY_VAULT_DOCS}}
31+
lighthouseci:
32+
if: github.event.pull_request
33+
needs: call-docs-build-push
34+
runs-on: ubuntu-22.04
35+
steps:
36+
- uses: actions/checkout@v5
37+
with:
38+
ref: ${{ github.event.workflow_run.head_branch }}
39+
- uses: actions/setup-node@v5
40+
with:
41+
node-version: 18
42+
- name: Installing packages
43+
run: npm ci
44+
- name: Generating lighthouse reports for PR and main...
45+
run: |
46+
node performance/lighthouse-script.js
47+
- name: Compare the artifacts for negative differences in performance
48+
continue-on-error: true
49+
run: |
50+
FIELDS=("performance" "accessibility")
51+
for FIELD in "${FIELDS[@]}"; do
52+
PR_VALUE=$(cat lighthouse-reports/pr-report.json | jq -r ".categories.$FIELD.score")
53+
MAIN_VALUE=$(cat lighthouse-reports/main-report.json | jq -r ".categories.$FIELD.score")
54+
echo "$FIELD: PR - $PR_VALUE | Main - $MAIN_VALUE"
55+
56+
if [ $FIELD = "performance" ]; then
57+
LOWER_BOUND=$(echo "$MAIN_VALUE - 0.05" | bc)
58+
UPPER_BOUND=$(echo "$MAIN_VALUE + 0.05" | bc)
59+
if (( $(echo "$PR_VALUE < $LOWER_BOUND" | bc -l) || $(echo "$PR_VALUE > $UPPER_BOUND" | bc -l) )); then
60+
echo "Error: $FIELD score in PR ($PR_VALUE) is less than in MAIN ($MAIN_VALUE)"
61+
exit 1
62+
fi
63+
else
64+
if (( $(echo "$PR_VALUE < $MAIN_VALUE" | bc -l) )); then
65+
echo "Error: $FIELD score in PR ($PR_VALUE) is less than in MAIN ($MAIN_VALUE)"
66+
exit 1
67+
fi
68+
fi
69+
done
70+
- uses: actions/upload-artifact@v4
71+
if: ${{ !cancelled() }}
72+
with:
73+
name: lighthouse-reports
74+
path: lighthouse-reports/
75+
retention-days: 30

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,6 @@ exampleSite/hugo
3737

3838
# Biome
3939
biome.rb
40+
41+
# Local Lighthouse artifacts
42+
*/lighthouse-reports

performance/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Important Information
2+
3+
This folder is only to be run in the CI/CD system. Should not be ran locally!

performance/lighthouse-script.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
const puppeteer = require('puppeteer');
2+
const fs = require('fs');
3+
4+
const PORT = 8041;
5+
const PR_NUMBER = process.env.GITHUB_PR_NUMBER;
6+
const environments = [
7+
{
8+
title: 'pr',
9+
url: `https://frontdoor-test-docs.nginx.com/previews/docs/${PR_NUMBER}/`,
10+
},
11+
{
12+
title: 'main',
13+
url: 'https://docs.nginx.com/',
14+
},
15+
];
16+
const OUTPUT_DIR = './lighthouse-reports';
17+
18+
const signIntoFrontDoor = async (browser, env) => {
19+
const page = await browser.newPage();
20+
await page.authenticate({
21+
username: process.env.FRONT_DOOR_USERNAME,
22+
password: process.env.FRONT_DOOR_PASSWORD,
23+
});
24+
25+
await page.goto(env['url']);
26+
await page.waitForSelector('.grid-container');
27+
console.log('Logged in...');
28+
await page.close();
29+
};
30+
31+
const runLighthouse = async (env) => {
32+
const OUTPUT_FILE = `${env['title']}-report.json`;
33+
34+
const lighthouse = (await import('lighthouse')).default;
35+
console.log(`Running Lighthouse for ${env['title']}...`);
36+
const result = await lighthouse(env['url'], { port: PORT });
37+
fs.writeFileSync(`${OUTPUT_DIR}/${OUTPUT_FILE}`, result.report);
38+
};
39+
40+
(async () => {
41+
const browser = await puppeteer.launch({
42+
args: [`--remote-debugging-port=${PORT}`],
43+
headless: true,
44+
});
45+
if (!fs.existsSync(OUTPUT_DIR)) {
46+
fs.mkdirSync(OUTPUT_DIR);
47+
}
48+
49+
for (const env of environments) {
50+
if (env['title'] === 'pr') {
51+
await signIntoFrontDoor(browser, env);
52+
}
53+
await runLighthouse(env);
54+
}
55+
56+
await browser.close();
57+
})();

0 commit comments

Comments
 (0)