Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Lighthouse CI #6047

Merged
merged 59 commits into from
Oct 28, 2023
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
a32af21
add lighthouse preview
bmuenzenmeyer Oct 22, 2023
1e5cb9a
Merge pull request #47 from bmuenzenmeyer/lighthouse
bmuenzenmeyer Oct 22, 2023
b634add
add more than one url
bmuenzenmeyer Oct 22, 2023
67723fa
remove unneeded step
bmuenzenmeyer Oct 24, 2023
8c09fc3
use other vercel action
bmuenzenmeyer Oct 24, 2023
e3d86b5
Merge pull request #48 from bmuenzenmeyer/lighthouse-test
bmuenzenmeyer Oct 24, 2023
34f6231
remove unnecessary condition
bmuenzenmeyer Oct 24, 2023
7cce200
checkout forked branch again
bmuenzenmeyer Oct 24, 2023
1207084
Merge pull request #49 from bmuenzenmeyer/lighthouse-test2
bmuenzenmeyer Oct 24, 2023
a26dc58
increase vercel timeout
bmuenzenmeyer Oct 24, 2023
8a53510
use correct filename
bmuenzenmeyer Oct 24, 2023
7120f0c
Merge pull request #50 from bmuenzenmeyer/lighthouse-test2
bmuenzenmeyer Oct 24, 2023
5432a7f
update pull-request comment
bmuenzenmeyer Oct 24, 2023
a03f8ba
tun assertions
bmuenzenmeyer Oct 24, 2023
f24bc63
Merge pull request #51 from bmuenzenmeyer/lighthouse-test2
bmuenzenmeyer Oct 24, 2023
e450844
add more than one url a different way
bmuenzenmeyer Oct 24, 2023
d81847c
format lighthouse output
bmuenzenmeyer Oct 24, 2023
4af0813
Merge pull request #52 from bmuenzenmeyer/lighthouse-test2
bmuenzenmeyer Oct 24, 2023
885e46c
fix typo
bmuenzenmeyer Oct 24, 2023
369c73a
set locale in urls
bmuenzenmeyer Oct 24, 2023
0839bd2
Merge pull request #53 from bmuenzenmeyer/lighthouse-test2
bmuenzenmeyer Oct 24, 2023
4a1647e
remove unused config
bmuenzenmeyer Oct 24, 2023
f1e9033
format result
bmuenzenmeyer Oct 24, 2023
8a6b0b6
Merge pull request #54 from bmuenzenmeyer/lighthouse-test2
bmuenzenmeyer Oct 24, 2023
4e8549e
use same comment on final result
bmuenzenmeyer Oct 24, 2023
ee3c0da
make valid cjs module
bmuenzenmeyer Oct 24, 2023
3a28ae9
Merge pull request #55 from bmuenzenmeyer/lighthouse-test2
bmuenzenmeyer Oct 24, 2023
4b232d3
comment todo
bmuenzenmeyer Oct 24, 2023
dda14db
formatting scores
bmuenzenmeyer Oct 24, 2023
0a3cae8
Merge pull request #56 from bmuenzenmeyer/lighthouse-test2
bmuenzenmeyer Oct 24, 2023
aea8a2a
revert longer timeout
bmuenzenmeyer Oct 24, 2023
dbf1d49
formatting
bmuenzenmeyer Oct 24, 2023
50f23eb
Merge pull request #57 from bmuenzenmeyer/lighthouse-test2
bmuenzenmeyer Oct 24, 2023
90dc82f
increase vercel timeout afterall
bmuenzenmeyer Oct 24, 2023
45a7fa9
add more comment
bmuenzenmeyer Oct 24, 2023
db8b02a
change to ESM
bmuenzenmeyer Oct 24, 2023
a59de9b
Merge pull request #58 from bmuenzenmeyer/lighthouse-test2
bmuenzenmeyer Oct 24, 2023
4928135
add /en/about page
bmuenzenmeyer Oct 24, 2023
aaa56c9
Revert "change to ESM"
bmuenzenmeyer Oct 24, 2023
2eae555
Merge pull request #59 from bmuenzenmeyer/lighthouse-test2
bmuenzenmeyer Oct 24, 2023
9ae78a9
add previous releases page
bmuenzenmeyer Oct 24, 2023
25e7533
condensed output
bmuenzenmeyer Oct 25, 2023
7d27e72
Merge pull request #60 from bmuenzenmeyer/lighthouse-test2
bmuenzenmeyer Oct 25, 2023
31cd8b5
add blog
bmuenzenmeyer Oct 25, 2023
128c688
cleanup
bmuenzenmeyer Oct 25, 2023
cca36bf
Merge branch 'nodejs:main' into main
bmuenzenmeyer Oct 25, 2023
8f1e9f6
Merge pull request #61 from bmuenzenmeyer/lighthouse-test2
bmuenzenmeyer Oct 25, 2023
dd57898
do not run on push
bmuenzenmeyer Oct 25, 2023
4976e3f
Merge pull request #62 from bmuenzenmeyer/lighthouse-test2
bmuenzenmeyer Oct 25, 2023
7312973
simplify comment, trigger change
bmuenzenmeyer Oct 25, 2023
354764a
troubleshoot why links output is empty
bmuenzenmeyer Oct 25, 2023
8edd969
Merge pull request #63 from bmuenzenmeyer/lighthouse-verification
bmuenzenmeyer Oct 25, 2023
544cc7e
testing lighthouse
bmuenzenmeyer Oct 25, 2023
0f01d7b
Merge pull request #64 from bmuenzenmeyer/lh-test
bmuenzenmeyer Oct 25, 2023
41f9cd3
chore: simplify code, add tests
bmuenzenmeyer Oct 26, 2023
3e48178
Merge pull request #65 from bmuenzenmeyer/lh-test
bmuenzenmeyer Oct 26, 2023
4a84d2d
Merge branch 'nodejs:main' into main
bmuenzenmeyer Oct 26, 2023
2d31e59
use renamed function
bmuenzenmeyer Oct 26, 2023
58ddaca
increase vercel preview timeout
bmuenzenmeyer Oct 28, 2023
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
117 changes: 117 additions & 0 deletions .github/workflows/lighthouse.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Security Notes
# This workflow uses `pull_request_target`, so will run against all PRs automatically (without approval), be careful with allowing any user-provided code to be run here
# Only selected Actions are allowed within this repository. Please refer to (https://github.com/nodejs/nodejs.org/settings/actions)
# for the full list of available actions. If you want to add a new one, please reach out a maintainer with Admin permissions.
# REVIEWERS, please always double-check security practices before merging a PR that contains Workflow changes!!
# AUTHORS, please only use actions with explicit SHA references, and avoid using `@master` or `@main` references or `@version` tags.
# MERGE QUEUE NOTE: This Workflow does not run on `merge_group` trigger, as this Workflow is not required for Merge Queue's

name: Lighthouse

on:
pull_request_target:
branches:
- main
types:
- labeled

defaults:
run:
# This ensures that the working directory is the root of the repository
working-directory: ./

permissions:
contents: read
actions: read
# This permission is required by `thollander/actions-comment-pull-request`
pull-requests: write
bmuenzenmeyer marked this conversation as resolved.
Show resolved Hide resolved

jobs:
lighthouse-ci:
# We want to skip our lighthouse analysis on Dependabot PRs
if: startsWith(github.event.pull_request.head.ref, 'dependabot/') == false
ovflowd marked this conversation as resolved.
Show resolved Hide resolved

name: Lighthouse Report
runs-on: ubuntu-latest

steps:
- name: Git Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
# Since we checkout the HEAD of the current Branch, if the Pull Request comes from a Fork
# we want to clone the fork's repository instead of the base repository
# this allows us to have the correct history tree of the perspective of the Pull Request's branch
# If the Workflow is running on `merge_group` or `push` events it fallsback to the base repository
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
# We checkout the branch itself instead of a specific SHA (Commit) as we want to ensure that this Workflow
# is always running with the latest `ref` (changes) of the Pull Request's branch
# If the Workflow is running on `merge_group` or `push` events it fallsback to `github.ref` which will often be `main`
# or the merge_group `ref`
ref: ${{ github.event.pull_request.head.ref || github.ref }}

- name: Add Comment to PR
# Signal that a lighthouse run is about to start
uses: thollander/actions-comment-pull-request@d61db783da9abefc3437960d0cce08552c7c004f # v2.4.2
with:
message: |
Running Lighthouse audit...
# Used later to edit the existing comment
comment_tag: 'lighthouse_audit'

- name: Capture Vercel Preview
uses: patrickedqvist/wait-for-vercel-preview@dca4940010f36d2d44caa487087a09b57939b24a # v1.3.1
bmuenzenmeyer marked this conversation as resolved.
Show resolved Hide resolved
id: vercel_preview_url
with:
token: ${{ secrets.GITHUB_TOKEN }}
max_timeout: 60
bmuenzenmeyer marked this conversation as resolved.
Show resolved Hide resolved

- name: Git Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
# By default Git Checkout on `pull-request-target` will checkout
# the `default` branch of the Pull Request. We want to checkout
# the actual branch of the Pull Request.
ref: ${{ github.event.pull_request.head.ref }}

- name: Audit Preview URL with Lighthouse
# Conduct the lighthouse audit
id: lighthouse_audit
uses: treosh/lighthouse-ci-action@03becbfc543944dd6e7534f7ff768abb8a296826 # v10.1.0
bmuenzenmeyer marked this conversation as resolved.
Show resolved Hide resolved
with:
# Defines the settings and assertions to audit
configPath: './.lighthouserc.json'
# These URLS capture critical pages / site functionality.
urls: |
${{ steps.vercel_preview_url.outputs.url }}/en
${{ steps.vercel_preview_url.outputs.url }}/en/about
${{ steps.vercel_preview_url.outputs.url }}/en/about/previous-releases
${{ steps.vercel_preview_url.outputs.url }}/en/download
${{ steps.vercel_preview_url.outputs.url }}/en/blog
uploadArtifacts: true # save results as a action artifacts
temporaryPublicStorage: true # upload lighthouse report to the temporary storage

- name: Format Lighthouse Score
# Transform the audit results into a single, friendlier output
id: format_lighthouse_score
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6.4.1
env:
# using env as input to our script
# see https://github.com/actions/github-script#use-env-as-input
LIGHTHOUSE_RESULT: ${{ steps.lighthouse_audit.outputs.manifest }}
LIGHTHOUSE_LINKS: ${{ steps.lighthouse_audit.outputs.links }}
VERCEL_PREVIEW_URL: ${{ steps.vercel_preview_url.outputs.url }}
with:
# Run as a separate file so we do not have to inline all of our formatting logic.
# See https://github.com/actions/github-script#run-a-separate-file for more info.
script: |
const { formatLighthouseResults } = await import('${{github.workspace}}/scripts/lighthouse/index.mjs')
await formatLighthouseResults({core})

- name: Add Comment to PR
# Replace the previous message with our formatted lighthouse results
uses: thollander/actions-comment-pull-request@d61db783da9abefc3437960d0cce08552c7c004f # v2.4.2
with:
# Reference the previously created comment
comment_tag: 'lighthouse_audit'
message: |
${{ steps.format_lighthouse_score.outputs.comment }}
18 changes: 18 additions & 0 deletions .lighthouserc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"ci": {
"collect": {
"numberOfRuns": 1,
"settings": {
"preset": "desktop"
}
},
"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 }]
}
}
}
}
69 changes: 69 additions & 0 deletions scripts/lighthouse/__tests__/index.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { formatLighthouseResults } from '..';

describe('formatLighthouseResults', () => {
const MOCK_VERCEL_PREVIEW_URL = `https://some.vercel.preview.url`;

const MOCK_LIGHTHOUSE_RESULT = `[
{
"url": "${MOCK_VERCEL_PREVIEW_URL}/en",
"isRepresentativeRun": true,
"summary": { "performance": 0.99, "accessibility": 0.98, "best-practices": 1, "seo": 0.96, "pwa": 0.71 }
},
{
"url": "${MOCK_VERCEL_PREVIEW_URL}/en/download",
"isRepresentativeRun": true,
"summary": { "performance": 0.49, "accessibility": 0.75, "best-practices": 1, "seo": 0.90, "pwa": 0.71 }
}
]`;

const MOCK_LIGHTHOUSE_LINKS = `{
"${MOCK_VERCEL_PREVIEW_URL}/en": "fake.url/to/result/1",
"${MOCK_VERCEL_PREVIEW_URL}/en/download" : "fake.url/to/result/2"
}`;

let mockCore, originalEnv;

beforeEach(() => {
mockCore = { setOutput: jest.fn() };
originalEnv = process.env;
process.env = {
...process.env,
LIGHTHOUSE_RESULT: MOCK_LIGHTHOUSE_RESULT,
LIGHTHOUSE_LINKS: MOCK_LIGHTHOUSE_LINKS,
VERCEL_PREVIEW_URL: MOCK_VERCEL_PREVIEW_URL,
};
});

afterEach(() => {
process.env = originalEnv;
});

it('formats preview urls correctly', () => {
formatLighthouseResults({ core: mockCore });

const expectations = [
expect.stringContaining(`[/en](${MOCK_VERCEL_PREVIEW_URL}/en)`),
expect.stringContaining(
`[/en/download](${MOCK_VERCEL_PREVIEW_URL}/en/download)`
),
];

expectations.forEach(expectation => {
expect(mockCore.setOutput).toBeCalledWith('comment', expectation);
});
});

it('formats stoplight colors correctly', () => {
formatLighthouseResults({ core: mockCore });

const expectations = [
expect.stringContaining(`🟢 90`),
expect.stringContaining(`🟠 75`),
expect.stringContaining(`🔴 49`),
];

expectations.forEach(expectation => {
expect(mockCore.setOutput).toBeCalledWith('comment', expectation);
});
});
});
50 changes: 50 additions & 0 deletions scripts/lighthouse/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
'use strict';

const stoplight = res => (res >= 90 ? '🟢' : res >= 75 ? '🟠' : '🔴');
const normalizeScore = res => Math.round(res * 100);
const formatScore = res => {
const normalizedScore = normalizeScore(res);
return `${stoplight(normalizedScore)} ${normalizedScore}`;
};

/**
* `core` is in scope from https://github.com/actions/github-script
*/
export const formatLighthouseResults = ({ core }) => {
// this will be the shape of https://github.com/treosh/lighthouse-ci-action#manifest
const results = JSON.parse(process.env.LIGHTHOUSE_RESULT);
bmuenzenmeyer marked this conversation as resolved.
Show resolved Hide resolved

// this will be the shape of https://github.com/treosh/lighthouse-ci-action#links
const links = JSON.parse(process.env.LIGHTHOUSE_LINKS);

// start creating our markdown table
const header = [
'Lighthouse Results',
'URL | Performance | Accessibility | Best Practices | SEO | Report',
'| - | - | - | - | - | - |',
];

// map over each url result, formatting and linking to the output
const urlResults = results.map(({ url, summary }) => {
// make the tested link as a markdown link, without the long-generated host
const shortPreviewLink = `[${url.replace(
process.env.VERCEL_PREVIEW_URL,
ovflowd marked this conversation as resolved.
Show resolved Hide resolved
''
)}](${url})`;

// make each formatted score from our lighthouse properties
const performanceScore = formatScore(summary.performance);
const accessibilityScore = formatScore(summary.accessibility);
const bestPracticesScore = formatScore(summary['best-practices']);
const seoScore = formatScore(summary.seo);

// create the markdown table row
return `${shortPreviewLink} | ${performanceScore} | ${accessibilityScore} | ${bestPracticesScore} | ${seoScore} | [🔗](${links[url]})`;
});

// join the header and the rows together
const finalResults = [...header, ...urlResults].join('\n');

// return our output to the github action
core.setOutput('comment', finalResults);
};
Loading