86 lines
2.3 KiB
JavaScript
86 lines
2.3 KiB
JavaScript
// Computes a `size/*` label for a PR from its added + deleted lines,
|
|
// excluding generated / lock files, and reconciles the label on the PR.
|
|
|
|
const GENERATED = [/^uv\.lock$/, /package-lock\.json$/, /yarn\.lock$/];
|
|
|
|
const THRESHOLDS = {
|
|
XS: 9,
|
|
S: 49,
|
|
M: 199,
|
|
L: 499,
|
|
XL: Infinity,
|
|
};
|
|
|
|
function isGenerated(filename) {
|
|
return GENERATED.some((p) => p.test(filename));
|
|
}
|
|
|
|
function getSize(total) {
|
|
return Object.entries(THRESHOLDS).find(([, max]) => total <= max)[0];
|
|
}
|
|
|
|
module.exports = async ({ github, context }) => {
|
|
const { owner, repo } = context.repo;
|
|
const pr = context.payload.pull_request;
|
|
|
|
const files = await github.paginate(github.rest.pulls.listFiles, {
|
|
owner,
|
|
repo,
|
|
pull_number: pr.number,
|
|
per_page: 100,
|
|
});
|
|
|
|
const maxThreshold = Math.max(...Object.values(THRESHOLDS).filter(isFinite));
|
|
let total = 0;
|
|
for (const f of files) {
|
|
if (!isGenerated(f.filename)) {
|
|
total += f.additions + f.deletions;
|
|
}
|
|
if (total > maxThreshold) break;
|
|
}
|
|
|
|
const sizeLabel = `size/${getSize(total)}`;
|
|
console.log(`Size: ${total} lines -> ${sizeLabel}`);
|
|
|
|
const currentLabels = (
|
|
await github.paginate(github.rest.issues.listLabelsOnIssue, {
|
|
owner,
|
|
repo,
|
|
issue_number: pr.number,
|
|
})
|
|
).map((l) => l.name);
|
|
|
|
// Remove stale size labels.
|
|
for (const label of currentLabels) {
|
|
if (label.startsWith("size/") && label !== sizeLabel) {
|
|
console.log(`Removing stale label: ${label}`);
|
|
await github.rest.issues
|
|
.removeLabel({ owner, repo, issue_number: pr.number, name: label })
|
|
.catch((e) => console.warn(`Failed to remove label ${label}: ${e.message}`));
|
|
}
|
|
}
|
|
|
|
// Add the correct label, creating it on first use.
|
|
if (!currentLabels.includes(sizeLabel)) {
|
|
try {
|
|
await github.rest.issues.getLabel({ owner, repo, name: sizeLabel });
|
|
} catch (e) {
|
|
if (e.status !== 404) throw e;
|
|
console.log(`Creating label: ${sizeLabel}`);
|
|
await github.rest.issues.createLabel({
|
|
owner,
|
|
repo,
|
|
name: sizeLabel,
|
|
color: "ededed",
|
|
description: `Pull request size: ${sizeLabel.replace("size/", "")}`,
|
|
});
|
|
}
|
|
await github.rest.issues.addLabels({
|
|
owner,
|
|
repo,
|
|
issue_number: pr.number,
|
|
labels: [sizeLabel],
|
|
});
|
|
}
|
|
};
|