Skip to content

Commit 0aeee92

Browse files
committed
one issue for each failing test
1 parent 616cea7 commit 0aeee92

File tree

2 files changed

+36
-36
lines changed

2 files changed

+36
-36
lines changed

.github/FLAKY_CI_FAILURE_TEMPLATE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: '[Flaky CI]: {{ env.JOB_NAME }}'
2+
title: '[Flaky CI]: {{ env.JOB_NAME }} - {{ env.TEST_NAME }}'
33
labels: Tests
44
---
55

.github/workflows/build.yml

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,7 +1171,7 @@ jobs:
11711171
const jobUrl = job.html_url;
11721172
11731173
// Fetch annotations from the check run to extract failed test names
1174-
let testName = '_Not available - check the run link for details_';
1174+
let testNames = [];
11751175
try {
11761176
const annotations = await github.paginate(github.rest.checks.listAnnotations, {
11771177
owner: context.repo.owner,
@@ -1181,48 +1181,48 @@ jobs:
11811181
});
11821182
11831183
const testAnnotations = annotations.filter(a => a.annotation_level === 'failure' && a.path !== '.github');
1184-
if (testAnnotations.length > 0) {
1185-
const testNames = testAnnotations.map(a => {
1186-
// The title field contains the full test name (e.g. "file.test.ts > Suite > test name")
1187-
return a.title ? `- ${a.title}` : `- \`${a.path}\``;
1188-
});
1189-
// Deduplicate and limit to 20 entries to keep issues readable
1190-
testName = [...new Set(testNames)].slice(0, 20).join('\n');
1191-
}
1184+
testNames = [...new Set(testAnnotations.map(a => a.title || a.path))];
11921185
} catch (e) {
11931186
console.log(`Could not fetch annotations for ${jobName}: ${e.message}`);
11941187
}
11951188
1196-
// Replace template variables
1197-
const vars = {
1198-
'JOB_NAME': jobName,
1199-
'RUN_LINK': jobUrl,
1200-
'TEST_NAME': testName
1201-
};
1202-
1203-
let title = frontmatter.match(/title:\s*'(.*)'/)[1];
1204-
let issueBody = bodyTemplate;
1205-
for (const [key, value] of Object.entries(vars)) {
1206-
const pattern = new RegExp(`\\{\\{\\s*env\\.${key}\\s*\\}\\}`, 'g');
1207-
title = title.replace(pattern, value);
1208-
issueBody = issueBody.replace(pattern, value);
1189+
// If no test names found, fall back to one issue per job
1190+
if (testNames.length === 0) {
1191+
testNames = ['Unknown test'];
12091192
}
12101193
1211-
const existingIssue = existing.find(i => i.title === title);
1194+
// Create one issue per failing test for proper deduplication
1195+
for (const testName of testNames) {
1196+
const vars = {
1197+
'JOB_NAME': jobName,
1198+
'RUN_LINK': jobUrl,
1199+
'TEST_NAME': testName
1200+
};
1201+
1202+
let title = frontmatter.match(/title:\s*'(.*)'/)[1];
1203+
let issueBody = bodyTemplate;
1204+
for (const [key, value] of Object.entries(vars)) {
1205+
const pattern = new RegExp(`\\{\\{\\s*env\\.${key}\\s*\\}\\}`, 'g');
1206+
title = title.replace(pattern, value);
1207+
issueBody = issueBody.replace(pattern, value);
1208+
}
12121209
1213-
if (existingIssue) {
1214-
console.log(`Issue already exists for ${jobName}: #${existingIssue.number}`);
1215-
continue;
1216-
}
1210+
const existingIssue = existing.find(i => i.title === title);
1211+
1212+
if (existingIssue) {
1213+
console.log(`Issue already exists for "${testName}" in ${jobName}: #${existingIssue.number}`);
1214+
continue;
1215+
}
12171216
1218-
const newIssue = await github.rest.issues.create({
1219-
owner: context.repo.owner,
1220-
repo: context.repo.repo,
1221-
title: title,
1222-
body: issueBody.trim(),
1223-
labels: ['Tests']
1224-
});
1225-
console.log(`Created issue #${newIssue.data.number} for ${jobName}`);
1217+
const newIssue = await github.rest.issues.create({
1218+
owner: context.repo.owner,
1219+
repo: context.repo.repo,
1220+
title: title,
1221+
body: issueBody.trim(),
1222+
labels: ['Tests']
1223+
});
1224+
console.log(`Created issue #${newIssue.data.number} for "${testName}" in ${jobName}`);
1225+
}
12261226
}
12271227
12281228
- name: Check for failures

0 commit comments

Comments
 (0)