Skip to content

Commit 669441b

Browse files
mathusanm6Copilot
andauthored
fix: pr size labeler should keep the label if appropriate (#94)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent e954a42 commit 669441b

1 file changed

Lines changed: 106 additions & 34 deletions

File tree

.github/workflows/pr-size-labeler.yml

Lines changed: 106 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,58 +18,130 @@ jobs:
1818
with:
1919
fetch-depth: 0
2020

21-
- name: Remove existing size labels
21+
- name: Calculate PR size and manage labels
2222
uses: actions/github-script@v7
2323
with:
2424
script: |
25+
// First, calculate the PR size to determine what label should be applied
26+
const { data: files } = await github.rest.pulls.listFiles({
27+
owner: context.repo.owner,
28+
repo: context.repo.repo,
29+
pull_number: context.issue.number,
30+
});
31+
32+
// Files to ignore (similar to the pr-size-labeler action)
33+
const filesToIgnore = [
34+
'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'Cargo.lock',
35+
'composer.lock', 'Pipfile.lock', 'poetry.lock'
36+
];
37+
38+
const ignoredExtensions = ['.min.js', '.min.css', '.map', '.pyc'];
39+
const ignoredPaths = ['dist/', 'build/', '__pycache__/'];
40+
41+
// Calculate total changes
42+
let totalChanges = 0;
43+
for (const file of files) {
44+
const filename = file.filename;
45+
46+
// Skip if file should be ignored
47+
if (filesToIgnore.includes(filename) ||
48+
ignoredExtensions.some(ext => filename.endsWith(ext)) ||
49+
ignoredPaths.some(path => filename.includes(path))) {
50+
continue;
51+
}
52+
53+
totalChanges += file.additions + file.deletions;
54+
}
55+
56+
console.log(`Total changes: ${totalChanges}`);
57+
58+
// Determine new label based on size thresholds
59+
let newLabel;
60+
if (totalChanges <= 10) {
61+
newLabel = 'size/XS';
62+
} else if (totalChanges <= 30) {
63+
newLabel = 'size/S';
64+
} else if (totalChanges <= 100) {
65+
newLabel = 'size/M';
66+
} else if (totalChanges <= 500) {
67+
newLabel = 'size/L';
68+
} else {
69+
newLabel = 'size/XL';
70+
}
71+
72+
console.log(`New label should be: ${newLabel}`);
73+
74+
// Get existing labels
2575
const sizeLabels = ['size/XS', 'size/S', 'size/M', 'size/L', 'size/XL'];
2676
const { data: labels } = await github.rest.issues.listLabelsOnIssue({
2777
owner: context.repo.owner,
2878
repo: context.repo.repo,
2979
issue_number: context.issue.number,
3080
});
3181
32-
for (const label of labels) {
33-
if (sizeLabels.includes(label.name)) {
82+
const existingSizeLabels = labels.filter(label => sizeLabels.includes(label.name));
83+
84+
// Only remove existing size labels if they're different from the new label
85+
for (const label of existingSizeLabels) {
86+
if (label.name !== newLabel) {
3487
console.log(`Removing existing size label: ${label.name}`);
3588
await github.rest.issues.removeLabel({
3689
owner: context.repo.owner,
3790
repo: context.repo.repo,
3891
issue_number: context.issue.number,
3992
name: label.name,
4093
});
94+
} else {
95+
console.log(`Keeping existing size label: ${label.name} (same as calculated)`);
4196
}
4297
}
4398
44-
- name: Label PR based on size
45-
uses: codelytv/pr-size-labeler@v1
99+
// Add the new label if it's not already present
100+
const hasNewLabel = existingSizeLabels.some(label => label.name === newLabel);
101+
if (!hasNewLabel) {
102+
console.log(`Adding new size label: ${newLabel}`);
103+
await github.rest.issues.addLabels({
104+
owner: context.repo.owner,
105+
repo: context.repo.repo,
106+
issue_number: context.issue.number,
107+
labels: [newLabel],
108+
});
109+
}
110+
111+
- name: Add XL message if applicable
112+
uses: actions/github-script@v7
113+
if: always()
46114
with:
47-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
48-
xs_label: "size/XS"
49-
xs_max_size: 10
50-
s_label: "size/S"
51-
s_max_size: 30
52-
m_label: "size/M"
53-
m_max_size: 100
54-
l_label: "size/L"
55-
l_max_size: 500
56-
xl_label: "size/XL"
57-
fail_if_xl: false
58-
message_if_xl: >
59-
This PR is very large. Consider breaking it down into smaller PRs
60-
for easier review and better maintainability.
61-
files_to_ignore: |
62-
package-lock.json
63-
yarn.lock
64-
pnpm-lock.yaml
65-
Cargo.lock
66-
composer.lock
67-
Pipfile.lock
68-
poetry.lock
69-
*.min.js
70-
*.min.css
71-
*.map
72-
dist/*
73-
build/*
74-
__pycache__/*
75-
*.pyc
115+
script: |
116+
// Check if PR has XL label and add message if needed
117+
const { data: labels } = await github.rest.issues.listLabelsOnIssue({
118+
owner: context.repo.owner,
119+
repo: context.repo.repo,
120+
issue_number: context.issue.number,
121+
});
122+
123+
const hasXLLabel = labels.some(label => label.name === 'size/XL');
124+
125+
if (hasXLLabel) {
126+
const message = `This PR is very large. Consider breaking it down into smaller PRs for easier review and better maintainability.`;
127+
128+
// Check if we already commented
129+
const { data: comments } = await github.rest.issues.listComments({
130+
owner: context.repo.owner,
131+
repo: context.repo.repo,
132+
issue_number: context.issue.number,
133+
});
134+
135+
const hasExistingComment = comments.some(comment =>
136+
comment.user.login && comment.user.login.endsWith('[bot]') && comment.body.includes('This PR is very large')
137+
);
138+
139+
if (!hasExistingComment) {
140+
await github.rest.issues.createComment({
141+
owner: context.repo.owner,
142+
repo: context.repo.repo,
143+
issue_number: context.issue.number,
144+
body: message,
145+
});
146+
}
147+
}

0 commit comments

Comments
 (0)