CI: add PR size autolabel workflow (#14410)

This commit is contained in:
Tak Hoffman
2026-02-11 21:12:27 -06:00
committed by GitHub
parent 631102e714
commit c28cbac512
2 changed files with 94 additions and 1 deletions

View File

@@ -25,6 +25,95 @@ jobs:
configuration-path: .github/labeler.yml
repo-token: ${{ steps.app-token.outputs.token }}
sync-labels: true
- name: Apply PR size label
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
with:
github-token: ${{ steps.app-token.outputs.token }}
script: |
const pullRequest = context.payload.pull_request;
if (!pullRequest) {
return;
}
const sizeLabels = ["size: XS", "size: S", "size: M", "size: L", "size: XL"];
const labelColor = "fbca04";
for (const label of sizeLabels) {
try {
await github.rest.issues.getLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: label,
});
} catch (error) {
if (error?.status !== 404) {
throw error;
}
await github.rest.issues.createLabel({
owner: context.repo.owner,
repo: context.repo.repo,
name: label,
color: labelColor,
});
}
}
const files = await github.paginate(github.rest.pulls.listFiles, {
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pullRequest.number,
per_page: 100,
});
const excludedLockfiles = new Set(["pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lockb"]);
const totalChangedLines = files.reduce((total, file) => {
const path = file.filename ?? "";
if (path === "docs.acp.md" || path.startsWith("docs/") || excludedLockfiles.has(path)) {
return total;
}
return total + (file.additions ?? 0) + (file.deletions ?? 0);
}, 0);
let targetSizeLabel = "size: XL";
if (totalChangedLines < 50) {
targetSizeLabel = "size: XS";
} else if (totalChangedLines < 200) {
targetSizeLabel = "size: S";
} else if (totalChangedLines < 500) {
targetSizeLabel = "size: M";
} else if (totalChangedLines < 1000) {
targetSizeLabel = "size: L";
}
const currentLabels = await github.paginate(github.rest.issues.listLabelsOnIssue, {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pullRequest.number,
per_page: 100,
});
for (const label of currentLabels) {
const name = label.name ?? "";
if (!sizeLabels.includes(name)) {
continue;
}
if (name === targetSizeLabel) {
continue;
}
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pullRequest.number,
name,
});
}
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pullRequest.number,
labels: [targetSizeLabel],
});
- name: Apply maintainer label for org members
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
with:

View File

@@ -14,10 +14,14 @@ const COLOR_BY_PREFIX = new Map<string, string>([
["docs", "0075ca"],
["cli", "f9d0c4"],
["gateway", "d4c5f9"],
["size", "fbca04"],
]);
const configPath = resolve(".github/labeler.yml");
const labelNames = extractLabelNames(readFileSync(configPath, "utf8"));
const EXTRA_LABELS = ["size: XS", "size: S", "size: M", "size: L", "size: XL"] as const;
const labelNames = [
...new Set([...extractLabelNames(readFileSync(configPath, "utf8")), ...EXTRA_LABELS]),
];
if (!labelNames.length) {
throw new Error("labeler.yml must declare at least one label.");