Skip to content

Instantly share code, notes, and snippets.

@sean-e-dietrich
Created February 22, 2020 08:48
Show Gist options
  • Save sean-e-dietrich/ee8acac6b3e69523235c547e9b92cb86 to your computer and use it in GitHub Desktop.
Save sean-e-dietrich/ee8acac6b3e69523235c547e9b92cb86 to your computer and use it in GitHub Desktop.
circleci-lighthouse
#!/usr/local/bin/node
const fs = require("fs");
const path = require("path");
const bot = require("circle-github-bot").create();
const pkg = JSON.parse(fs.readFileSync(process.argv[2], "utf8"));
const requiredScores = pkg.requiredScores;
const reportsDir = process.argv[3];
const reports = {
anonymous: {
json: [],
htmlFilenames: [],
}
};
fs.readdirSync(reportsDir).forEach(file => {
const userType = file.split('-')[0];
if (path.extname(file) === ".json") {
reports[userType].json.push(
JSON.parse(fs.readFileSync(path.resolve(reportsDir, file), "utf8"))
);
} else if (path.extname(file) === ".html") {
reports[userType].htmlFilenames.push(file);
}
});
let success = true;
const ciStdout = [];
const prComment = [];
['anonymous'].forEach(userType => {
const scoresAcrossRunsByCategory = reports[userType].json.reduce((acc, run) => {
Object.keys(requiredScores).forEach(category => {
acc[category] = acc[category] || [];
acc[category].push(run.categories[category].score * 100);
});
return acc;
}, {});
ciStdout.push(
"------------------------------------------",
`Number of parallel test runs (${userType}): ${reports[userType].json.length}`,
"------------------------------------------"
);
// Look for base url
var baseUrl = false;
if (pkg.hasOwnProperty('is_relative_url') && pkg.is_relative_url) {
baseUrl = process.env.LIGHTHOUSE_BASE_URL || false;
}
var testedUrl = pkg.url;
if (baseUrl) {
testedUrl = baseUrl + pkg.url;
}
prComment.push(
`<h3>Lighthouse scores</h3>`,
`<p><strong>Tested url:</strong> <a href="${testedUrl}" target="_blank">${testedUrl}</a></p>`,
`<p>Best scores across <strong>${reports[userType].json.length}</strong> parallel runs:</p>`,
'<p>'
);
Object.keys(requiredScores).forEach(category => {
const requiredOutOf100 = requiredScores[category];
const actualBestOutOf100 = Math.max.apply(
null,
scoresAcrossRunsByCategory[category]
);
if (actualBestOutOf100 < requiredScores[category]) {
ciStdout.push(`❌ ${category}: ${actualBestOutOf100}/${requiredOutOf100}`);
prComment.push(
`<strong>❌ ${category}:</strong> ${actualBestOutOf100}/${requiredOutOf100}<br />`
);
success = false;
} else {
ciStdout.push(`✅ ${category}: ${actualBestOutOf100}/${requiredOutOf100}`);
prComment.push(
`<strong>✅ ${category}:</strong> ${actualBestOutOf100}/${requiredOutOf100}<br />`
);
}
});
prComment.push(
'</p>'
);
const reportLinks = reports[userType].htmlFilenames.map((filename, idx) => {
let link = bot.artifactLink(`reports/${filename}`, `run ${idx + 1}`);
// Clean reports URLs to match CircleCI artifact path.
return link.replace("/root/project/", "");
});
prComment.push(`<p><strong>Detailed reports</strong>: ${reportLinks.join(", ")}</p>`);
});
console.log(ciStdout.join("\n"));
// We shouldn't fail if the PR comment doesn't work, that is a "nice to have"
try {
bot.comment(process.env.GH_AUTH_TOKEN, prComment.join("\n"));
} catch (e) {
console.log(e);
}
if (!success) {
process.exit(1);
}
{
"name": "lighthouse-circleci",
"version": "0.0.1",
"private": true,
"dependencies": {
"circle-github-bot": "^2.0.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment