authorgravatar for crazywolf132@gmail.com0x1f99d <crazywolf132@gmail.com> 2026-03-24 14:16:13+11:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-03-23 20:16:13-07:00
loge823f8f14ecb99c92345dbd72ba82b836858ba09
treecb4a51b4e7f1afa64773b461aca4369f761ad701
parent2b08d8669646109ffa101b1b767f4c1922d2e072
signature Signed by PGP key B5690EEEBB952194

ci(github): exclude test files from mixed PR size calculation (#1105)


1 files changed, 64 insertions(+), 11 deletions(-)

.github/workflows/pr-size.yml+64-11
...@@ -24,32 +24,32 @@ jobs:...@@ -24,32 +24,32 @@ jobs:
24 {24 {
25 name: "size:XS",25 name: "size:XS",
26 color: "0e8a16",26 color: "0e8a16",
27 description: "0-9 changed lines (additions + deletions).",27 description: "0-9 effective changed lines (test files excluded in mixed PRs).",
28 },28 },
29 {29 {
30 name: "size:S",30 name: "size:S",
31 color: "5ebd3e",31 color: "5ebd3e",
32 description: "10-29 changed lines (additions + deletions).",32 description: "10-29 effective changed lines (test files excluded in mixed PRs).",
33 },33 },
34 {34 {
35 name: "size:M",35 name: "size:M",
36 color: "fbca04",36 color: "fbca04",
37 description: "30-99 changed lines (additions + deletions).",37 description: "30-99 effective changed lines (test files excluded in mixed PRs).",
38 },38 },
39 {39 {
40 name: "size:L",40 name: "size:L",
41 color: "fe7d37",41 color: "fe7d37",
42 description: "100-499 changed lines (additions + deletions).",42 description: "100-499 effective changed lines (test files excluded in mixed PRs).",
43 },43 },
44 {44 {
45 name: "size:XL",45 name: "size:XL",
46 color: "d93f0b",46 color: "d93f0b",
47 description: "500-999 changed lines (additions + deletions).",47 description: "500-999 effective changed lines (test files excluded in mixed PRs).",
48 },48 },
49 {49 {
50 name: "size:XXL",50 name: "size:XXL",
51 color: "b60205",51 color: "b60205",
52 description: "1,000+ changed lines (additions + deletions).",52 description: "1,000+ effective changed lines (test files excluded in mixed PRs).",
53 },53 },
54 ];54 ];
5555
...@@ -131,12 +131,18 @@ jobs:...@@ -131,12 +131,18 @@ jobs:
131 with:131 with:
132 script: |132 script: |
133 const issueNumber = context.payload.pull_request.number;133 const issueNumber = context.payload.pull_request.number;
134 const additions = context.payload.pull_request.additions ?? 0;
135 const deletions = context.payload.pull_request.deletions ?? 0;
136 const changedLines = additions + deletions;
137 const managedLabels = JSON.parse(process.env.PR_SIZE_LABELS_JSON ?? "[]");134 const managedLabels = JSON.parse(process.env.PR_SIZE_LABELS_JSON ?? "[]");
138
139 const managedLabelNames = new Set(managedLabels.map((label) => label.name));135 const managedLabelNames = new Set(managedLabels.map((label) => label.name));
136 // Keep this aligned with the repo's test entrypoints and test-only support files.
137 const testFilePatterns = [
138 /(^|\/)__tests__(\/|$)/,
139 /(^|\/)tests?(\/|$)/,
140 /^apps\/server\/integration\//,
141 /\.(test|spec|browser|integration)\.[^.\/]+$/,
142 ];
143
144 const isTestFile = (filename) =>
145 testFilePatterns.some((pattern) => pattern.test(filename));
140146
141 const resolveSizeLabel = (totalChangedLines) => {147 const resolveSizeLabel = (totalChangedLines) => {
142 if (totalChangedLines < 10) {148 if (totalChangedLines < 10) {
...@@ -162,6 +168,42 @@ jobs:...@@ -162,6 +168,42 @@ jobs:
162 return "size:XXL";168 return "size:XXL";
163 };169 };
164170
171 const files = await github.paginate(
172 github.rest.pulls.listFiles,
173 {
174 owner: context.repo.owner,
175 repo: context.repo.repo,
176 pull_number: issueNumber,
177 per_page: 100,
178 },
179 (response) => response.data,
180 );
181
182 if (files.length >= 3000) {
183 core.warning(
184 "The GitHub pull request files API may truncate results at 3,000 files; PR size may be undercounted.",
185 );
186 }
187
188 let testChangedLines = 0;
189 let nonTestChangedLines = 0;
190
191 for (const file of files) {
192 const changedLinesForFile = (file.additions ?? 0) + (file.deletions ?? 0);
193
194 if (changedLinesForFile === 0) {
195 continue;
196 }
197
198 if (isTestFile(file.filename)) {
199 testChangedLines += changedLinesForFile;
200 continue;
201 }
202
203 nonTestChangedLines += changedLinesForFile;
204 }
205
206 const changedLines = nonTestChangedLines === 0 ? testChangedLines : nonTestChangedLines;
165 const nextLabelName = resolveSizeLabel(changedLines);207 const nextLabelName = resolveSizeLabel(changedLines);
166208
167 const { data: currentLabels } = await github.rest.issues.listLabelsOnIssue({209 const { data: currentLabels } = await github.rest.issues.listLabelsOnIssue({
...@@ -199,4 +241,15 @@ jobs:...@@ -199,4 +241,15 @@ jobs:
199 });241 });
200 }242 }
201243
202 core.info(`PR #${issueNumber}: ${changedLines} changed lines -> ${nextLabelName}`);244 const classification =
245 nonTestChangedLines === 0
246 ? testChangedLines > 0
247 ? "test-only PR"
248 : "no line changes"
249 : testChangedLines > 0
250 ? "test lines excluded"
251 : "all non-test changes";
252
253 core.info(
254 `PR #${issueNumber}: ${nonTestChangedLines} non-test lines, ${testChangedLines} test lines, ${changedLines} effective lines -> ${nextLabelName} (${classification})`,
255 );