Skip to content

Commit 897d2d2

Browse files
committed
feat: 테스트가 실패했을 시 어떤 스킴, 어떤 부분에서 에러가 났는지 코멘트를 달도록 구현
1 parent 233085e commit 897d2d2

1 file changed

Lines changed: 67 additions & 6 deletions

File tree

.github/workflows/test.yml

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,63 @@ jobs:
269269
});
270270
}
271271
272+
function cleanLine(line) {
273+
return line
274+
.replace(/\u001b\[[0-9;]*m/g, '')
275+
.trim()
276+
.slice(0, 300);
277+
}
278+
279+
function extractFailureSnippet(logPath) {
280+
if (!fs.existsSync(logPath)) return '';
281+
282+
const lines = fs.readFileSync(logPath, 'utf8').split(/\r?\n/);
283+
const importantPatterns = [
284+
/\.swift:\d+:\d+:\s+error:/,
285+
/Testing failed:/,
286+
/\*\* TEST FAILED \*\*/,
287+
/The following build commands failed:/,
288+
/Issue recorded:/,
289+
/Expectation failed:/,
290+
/✘/,
291+
];
292+
const indexes = [];
293+
294+
lines.forEach((line, index) => {
295+
if (importantPatterns.some((pattern) => pattern.test(line))) {
296+
indexes.push(index);
297+
}
298+
});
299+
300+
const selectedLines = [];
301+
const seenLines = new Set();
302+
303+
for (const index of indexes.slice(0, 5)) {
304+
const start = Math.max(0, index - 2);
305+
const end = Math.min(lines.length, index + 9);
306+
for (const line of lines.slice(start, end)) {
307+
const cleanedLine = cleanLine(line);
308+
if (!cleanedLine || seenLines.has(cleanedLine)) continue;
309+
seenLines.add(cleanedLine);
310+
selectedLines.push(cleanedLine);
311+
}
312+
}
313+
314+
if (selectedLines.length <= 0) {
315+
for (const line of lines.slice(-25)) {
316+
const cleanedLine = cleanLine(line);
317+
if (!cleanedLine || seenLines.has(cleanedLine)) continue;
318+
seenLines.add(cleanedLine);
319+
selectedLines.push(cleanedLine);
320+
}
321+
}
322+
323+
return selectedLines.slice(0, 30).join('\n');
324+
}
325+
272326
for (const summaryPath of walk(root).filter((filePath) => path.basename(filePath) === 'summary.txt')) {
273327
const artifactName = summaryPath.split(path.sep)[1] || 'unknown';
328+
const artifactDirectory = path.dirname(summaryPath);
274329
const text = fs.readFileSync(summaryPath, 'utf8');
275330
const records = text
276331
.trim()
@@ -287,25 +342,31 @@ jobs:
287342
288343
for (const record of records) {
289344
if (record.status && record.status !== '0') {
345+
const scheme = record.scheme || 'unknown';
346+
const logPath = path.join(artifactDirectory, `${scheme}.log`);
290347
summaries.push({
291348
artifactName,
292-
scheme: record.scheme || 'unknown',
349+
scheme,
293350
status: record.status,
351+
snippet: extractFailureSnippet(logPath),
294352
});
295353
}
296354
}
297355
}
298356
299-
let body = '❌ iOS tests failed.\n\n';
357+
let body = '❌ iOS CI tests failed.\n\n';
300358
301359
if (summaries.length <= 0) {
302360
body += 'No failed scheme summary was found. Check the uploaded test log artifacts.';
303361
} else {
304362
body += 'Failed schemes:\n\n';
305-
body += summaries
306-
.map((summary) => `- ${summary.scheme} (${summary.artifactName}, exit ${summary.status})`)
307-
.join('\n');
308-
body += '\n\nCheck the uploaded test log artifacts for full diagnostics.';
363+
for (const summary of summaries) {
364+
body += `- ${summary.scheme} (${summary.artifactName})\n`;
365+
if (summary.snippet) {
366+
body += '\n```text\n' + summary.snippet + '\n```\n\n';
367+
}
368+
}
369+
body += '\nCheck the uploaded test log artifacts for full diagnostics.';
309370
}
310371
311372
if (!context.payload.pull_request) {

0 commit comments

Comments
 (0)