@@ -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