Skip to content

Commit

Permalink
feat(action): Support multiple runs on the same site and average the …
Browse files Browse the repository at this point in the history
…score
  • Loading branch information
manrueda committed Feb 9, 2020
1 parent 554c980 commit 429ae00
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 33 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ jobs:
- name: Audit URLs using Lighthouse
uses: treosh/lighthouse-ci-action@v2
with:
runs: 3
urls: |
https://github.com/
https://duckduckgo.com/
- name: Displays Lighthouse report result as annotations
- name: Lighthouse Report
uses: ./ # Uses an action in the root directory
with:
reports: '.lighthouseci'
Expand Down
62 changes: 45 additions & 17 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11783,22 +11783,50 @@ const path_1 = __webpack_require__(622);
const fs_1 = __webpack_require__(747);
const glob_1 = __importDefault(__webpack_require__(120));
const glob = util_1.promisify(glob_1.default);
async function calculateScore(fullPath) {
const textContent = await (await fs_1.promises.readFile(fullPath)).toString('utf8');
const report = JSON.parse(textContent);
if (report.categories) {
const scores = Object.values(report.categories).map((category) => ({
name: category.title,
score: Math.round(category.score * 100)
}));
return {
url: report.finalUrl,
scores
};
}
else {
return null;
function getScoreFromReport(report) {
// Extract each score from a report into a known format
return Object.values(report.categories).map((category) => ({
name: category.title,
score: Math.round(category.score * 100)
}));
}
async function mergeReports(paths) {
// Read all reports from the FS
const rawReports = await Promise.all(paths.map(async (p) => JSON.parse((await fs_1.promises.readFile(p)).toString('utf8'))));
const results = new Map();
for (const rawReport of rawReports) {
// Ignore reports that does not have categories information
if (rawReport.categories) {
if (results.has(rawReport.finalUrl)) {
// If the same URL was already reported, merge the scores
const base = results.get(rawReport.finalUrl);
const partials = getScoreFromReport(rawReport);
for (const partial of partials) {
// Iterate each individual score inside the report and merge the results
const baseScore = base.scores.find(s => s.name === partial.name);
if (baseScore) {
const newScore = {
name: baseScore.name,
score: (baseScore.score + partial.score) / 2
};
base.scores.splice(base.scores.indexOf(baseScore), 1, newScore);
}
else {
base.scores.push(partial);
}
}
results.set(rawReport.finalUrl, base);
}
else {
// Adds the report to the result Map
results.set(rawReport.finalUrl, {
url: rawReport.finalUrl,
scores: getScoreFromReport(rawReport)
});
}
}
}
return Array.from(results.values());
}
function composeSummary(first, others) {
return `
Expand All @@ -11814,7 +11842,7 @@ async function run() {
const reportsPath = core.getInput('reports');
const octokit = new github.GitHub(core.getInput('github-token'));
const paths = await glob(path_1.join(reportsPath, '*.json'));
const scores = await Promise.all(paths.map(async (reportPath) => calculateScore(reportPath)));
const scores = await mergeReports(paths);
const [first, ...others] = scores.filter(s => s !== null);
await octokit.checks.create(Object.assign({}, github.context.repo, { name: `Lighthouse Report`, head_sha: github.context.sha, status: 'completed', conclusion: 'success', output: {
title: `Lighthouse Scores for ${first.url}`,
Expand All @@ -11823,7 +11851,7 @@ async function run() {
} }));
}
run().catch(error => core.setFailed(error.message || error));
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZmlsZTovLy9Vc2Vycy9tYW5ydWVkYS9kZXYvcGVyc29uYWwvbGlnaHRob3VzZS1yZXBvcnQtYWN0aW9uL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBLG9EQUFzQztBQUN0Qyx3REFBMEM7QUFDMUMsK0JBQWlDO0FBQ2pDLCtCQUE0QjtBQUM1QiwyQkFBOEI7QUFDOUIsZ0RBQXlCO0FBQ3pCLE1BQU0sSUFBSSxHQUFHLGdCQUFTLENBQUMsY0FBSyxDQUFDLENBQUM7QUFZOUIsS0FBSyxVQUFVLGNBQWMsQ0FBQyxRQUFnQjtJQUM1QyxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsTUFBTSxhQUFRLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQy9FLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDdkMsSUFBSSxNQUFNLENBQUMsVUFBVSxFQUFFO1FBQ3JCLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN0RSxJQUFJLEVBQUUsUUFBUSxDQUFDLEtBQUs7WUFDcEIsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUM7U0FDeEMsQ0FBQyxDQUFDLENBQUM7UUFDSixPQUFPO1lBQ0wsR0FBRyxFQUFFLE1BQU0sQ0FBQyxRQUFRO1lBQ3BCLE1BQU07U0FDUCxDQUFDO0tBQ0g7U0FBTTtRQUNMLE9BQU8sSUFBSSxDQUFDO0tBQ2I7QUFDSCxDQUFDO0FBRUQsU0FBUyxjQUFjLENBQUMsS0FBYSxFQUFFLE1BQWdCO0lBQ3JELE9BQU87RUFDUCxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksT0FBTyxDQUFDLENBQUMsS0FBSyxVQUFVLENBQUMsQ0FBQyxLQUFLLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQzs7RUFFbEcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDOzRCQUNVLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLEdBQUc7RUFDekMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxDQUFDLEtBQUssVUFBVSxDQUFDLENBQUMsS0FBSyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7Q0FDL0YsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7R0FDVixDQUFDLElBQUksRUFBRSxDQUFDO0FBQ1gsQ0FBQztBQUVELEtBQUssVUFBVSxHQUFHO0lBQ2hCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0MsTUFBTSxPQUFPLEdBQUcsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQztJQUVqRSxNQUFNLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFJLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFFdEQsTUFBTSxNQUFNLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLFVBQVUsRUFBRSxFQUFFLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUU5RixNQUFNLENBQUMsS0FBSyxFQUFFLEdBQUcsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxJQUFJLENBQWEsQ0FBQztJQUV0RSxNQUFPLE9BQWUsQ0FBQyxNQUFNLENBQUMsTUFBTSxtQkFDL0IsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLElBQ3RCLElBQUksRUFBRSxtQkFBbUIsRUFDekIsUUFBUSxFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUM1QixNQUFNLEVBQUUsV0FBVyxFQUNuQixVQUFVLEVBQUUsU0FBUyxFQUNyQixNQUFNLEVBQUU7WUFDTixLQUFLLEVBQUUseUJBQXlCLEtBQUssQ0FBQyxHQUFHLEVBQUU7WUFDM0MsSUFBSSxFQUFFLG1CQUFtQjtZQUN6QixPQUFPLEVBQUUsY0FBYyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUM7U0FDdkMsSUFTRCxDQUFDO0FBQ0wsQ0FBQztBQUVELEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLE9BQU8sSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDIn0=
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZmlsZTovLy9Vc2Vycy9tYW5ydWVkYS9kZXYvcGVyc29uYWwvbGlnaHRob3VzZS1yZXBvcnQtYWN0aW9uL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBLG9EQUFzQztBQUN0Qyx3REFBMEM7QUFDMUMsK0JBQWlDO0FBQ2pDLCtCQUE0QjtBQUM1QiwyQkFBOEI7QUFDOUIsZ0RBQXlCO0FBQ3pCLE1BQU0sSUFBSSxHQUFHLGdCQUFTLENBQUMsY0FBSyxDQUFDLENBQUM7QUFZOUIsU0FBUyxrQkFBa0IsQ0FBQyxNQUFXO0lBQ3JDLHVEQUF1RDtJQUN2RCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUM5RCxJQUFJLEVBQUUsUUFBUSxDQUFDLEtBQUs7UUFDcEIsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUM7S0FDeEMsQ0FBQyxDQUFDLENBQUE7QUFDTCxDQUFDO0FBRUQsS0FBSyxVQUFVLFlBQVksQ0FBQyxLQUFlO0lBQ3pDLCtCQUErQjtJQUMvQixNQUFNLFVBQVUsR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQ2xDLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFDLENBQUMsRUFBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sYUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQ2hGLENBQUE7SUFDRCxNQUFNLE9BQU8sR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUMxQyxLQUFLLE1BQU0sU0FBUyxJQUFJLFVBQVUsRUFBRTtRQUNsQywyREFBMkQ7UUFDM0QsSUFBSSxT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

/***/ }),

Expand Down
62 changes: 47 additions & 15 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,53 @@ interface Score {
score: number;
}

async function calculateScore(fullPath: string): Promise<Report | null> {
const textContent = await (await promises.readFile(fullPath)).toString('utf8');
const report = JSON.parse(textContent);
if (report.categories) {
const scores = Object.values(report.categories).map((category: any) => ({
name: category.title,
score: Math.round(category.score * 100)
}));
return {
url: report.finalUrl,
scores
};
} else {
return null;
function getScoreFromReport(report: any): Score[] {
// Extract each score from a report into a known format
return Object.values(report.categories).map((category: any) => ({
name: category.title,
score: Math.round(category.score * 100)
}))
}

async function mergeReports(paths: string[]): Promise<Report[]> {
// Read all reports from the FS
const rawReports = await Promise.all(
paths.map(async p => JSON.parse((await promises.readFile(p)).toString('utf8')))
)
const results = new Map<string, Report>();
for (const rawReport of rawReports) {
// Ignore reports that does not have categories information
if (rawReport.categories) {
if (results.has(rawReport.finalUrl)) {
// If the same URL was already reported, merge the scores
const base = results.get(rawReport.finalUrl)!;
const partials: Score[] = getScoreFromReport(rawReport);

for (const partial of partials) {
// Iterate each individual score inside the report and merge the results
const baseScore = base.scores.find(s => s.name === partial.name);
if (baseScore) {
const newScore: Score = {
name: baseScore.name,
score: (baseScore.score + partial.score) / 2
}
base.scores.splice(base.scores.indexOf(baseScore), 1, newScore);
} else {
base.scores.push(partial);
}
}
results.set(rawReport.finalUrl, base);

} else {
// Adds the report to the result Map
results.set(rawReport.finalUrl, {
url: rawReport.finalUrl,
scores: getScoreFromReport(rawReport)
})
}
}
}
return Array.from(results.values())
}

function composeSummary(first: Report, others: Report[]) {
Expand All @@ -50,7 +82,7 @@ async function run() {

const paths = await glob(join(reportsPath, '*.json'));

const scores = await Promise.all(paths.map(async (reportPath) => calculateScore(reportPath)));
const scores = await mergeReports(paths);

const [first, ...others] = scores.filter(s => s !== null) as Report[];

Expand Down

0 comments on commit 429ae00

Please sign in to comment.