@@ -171,211 +171,5 @@ jobs:
171171 uses : actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
172172 with :
173173 script : |
174- const fs = require('fs');
175- const fileFailures = JSON.parse(fs.readFileSync('failures.json', 'utf8'));
176- const label = 'test-failure';
177-
178- // Ensure label exists
179- try {
180- await github.rest.issues.getLabel({
181- owner: context.repo.owner,
182- repo: context.repo.repo,
183- name: label,
184- });
185- } catch (e) {
186- if (e.status === 404) {
187- await github.rest.issues.createLabel({
188- owner: context.repo.owner,
189- repo: context.repo.repo,
190- name: label,
191- color: 'e11d48',
192- description: 'Test failure detected by CI',
193- });
194- }
195- }
196-
197- const existingIssues = await github.paginate(
198- github.rest.issues.listForRepo,
199- {
200- owner: context.repo.owner,
201- repo: context.repo.repo,
202- labels: label,
203- state: 'open',
204- },
205- (response) => response.data
206- );
207-
208- const today = new Date().toISOString().split('T')[0];
209-
210- for (const fileEntry of fileFailures) {
211- const testFile = fileEntry.test_file;
212- const tests = fileEntry.tests;
213- const title = `[TEST-FAILURE] ${testFile}`;
214-
215- // Collect all environments across all tests in this file
216- const allEnvs = [...new Set(tests.flatMap(t => t.jobs.map(j => j.job)))];
217- const envLine = `**Environments:** ${allEnvs.map(e => '`' + e + '`').join(', ')}`;
218-
219- // Build checklist of failing tests
220- const checklist = tests.map(t => `- [ ] ${t.test_name}`).join('\n');
221-
222- const existing = existingIssues.find(i => i.title === title);
223-
224- if (existing) {
225- console.log(`Found existing issue #${existing.number} for ${testFile}`);
226-
227- // Update checklist in issue body — add new test names
228- const bodyLines = existing.body.split('\n');
229- const existingTests = bodyLines
230- .filter(l => l.match(/^- \[[ x]\] /))
231- .map(l => l.replace(/^- \[[ x]\] /, ''));
232-
233- const newTests = tests.map(t => t.test_name).filter(n => !existingTests.includes(n));
234- if (newTests.length > 0) {
235- console.log(` New failing tests: ${newTests.join(', ')}`);
236- const newChecklistItems = newTests.map(n => `- [ ] ${n}`).join('\n');
237- const updatedBody = existing.body.replace(
238- /(---\n\*Auto-created)/,
239- `${newChecklistItems}\n\n$1`
240- );
241- await github.rest.issues.update({
242- owner: context.repo.owner,
243- repo: context.repo.repo,
244- issue_number: existing.number,
245- body: updatedBody,
246- });
247- }
248-
249- // Update environments
250- const envMatch = existing.body.match(/\*\*Environments:\*\*\s*(.+)/);
251- const envInner = envMatch ? envMatch[1].match(/`([^`]+)`/g) : null;
252- const existingEnvs = envInner ? envInner.map(e => e.replace(/`/g, '')) : [];
253- const brandNewEnvs = allEnvs.filter(e => !existingEnvs.includes(e));
254- if (brandNewEnvs.length > 0) {
255- const mergedEnvs = [...existingEnvs, ...brandNewEnvs];
256- const newEnvLine = `**Environments:** ${mergedEnvs.map(e => '`' + e + '`').join(', ')}`;
257- const currentBody = (await github.rest.issues.get({
258- owner: context.repo.owner,
259- repo: context.repo.repo,
260- issue_number: existing.number,
261- })).data.body;
262- const updatedBody = currentBody.replace(/\*\*Environments:\*\*\s*.+/, newEnvLine);
263- await github.rest.issues.update({
264- owner: context.repo.owner,
265- repo: context.repo.repo,
266- issue_number: existing.number,
267- body: updatedBody,
268- });
269- }
270-
271- // Get existing comments to find per-test comments
272- const comments = await github.paginate(
273- github.rest.issues.listComments,
274- {
275- owner: context.repo.owner,
276- repo: context.repo.repo,
277- issue_number: existing.number,
278- },
279- (response) => response.data
280- );
281-
282- // For each failing test, create or update a comment
283- for (const test of tests) {
284- const commentMarker = `<!-- test-failure: ${test.test_name} -->`;
285- const ciLinks = test.jobs.map(j => ` - \`${j.job}\`: [CI link](${j.url})`).join('\n');
286- const historyEntry = `- ${today}:\n${ciLinks}`;
287-
288- const existingComment = comments.find(c => c.body.includes(commentMarker));
289-
290- if (existingComment) {
291- // Append to failure history
292- const updatedComment = existingComment.body.replace(
293- /(\n---\n\*Auto-tracked)/,
294- `\n${historyEntry}$1`
295- );
296- await github.rest.issues.updateComment({
297- owner: context.repo.owner,
298- repo: context.repo.repo,
299- comment_id: existingComment.id,
300- body: updatedComment,
301- });
302- console.log(` Updated comment for test: ${test.test_name}`);
303- } else {
304- // Create new comment for this test
305- await github.rest.issues.createComment({
306- owner: context.repo.owner,
307- repo: context.repo.repo,
308- issue_number: existing.number,
309- body: [
310- commentMarker,
311- `**Test:** \`${test.test_name}\``,
312- ``,
313- `**Error:**`,
314- '```',
315- test.error || 'N/A',
316- '```',
317- ``,
318- `**Failure history:**`,
319- historyEntry,
320- ``,
321- `---`,
322- `*Auto-tracked by Test Failure Detector*`,
323- ].join('\n'),
324- });
325- console.log(` Created comment for test: ${test.test_name}`);
326- }
327- }
328-
329- } else {
330- // Create new issue for this test file
331- console.log(`Creating issue for ${testFile}`);
332- const issue = await github.rest.issues.create({
333- owner: context.repo.owner,
334- repo: context.repo.repo,
335- title: title,
336- labels: [label],
337- body: [
338- `**Test file:** \`${testFile}\``,
339- ``,
340- `**Failing tests:**`,
341- checklist,
342- ``,
343- envLine,
344- ``,
345- `---`,
346- `*Auto-created by Test Failure Detector*`,
347- ].join('\n'),
348- });
349-
350- // Create one comment per failing test
351- for (const test of tests) {
352- const commentMarker = `<!-- test-failure: ${test.test_name} -->`;
353- const ciLinks = test.jobs.map(j => ` - \`${j.job}\`: [CI link](${j.url})`).join('\n');
354-
355- await github.rest.issues.createComment({
356- owner: context.repo.owner,
357- repo: context.repo.repo,
358- issue_number: issue.data.number,
359- body: [
360- commentMarker,
361- `**Test:** \`${test.test_name}\``,
362- ``,
363- `**Error:**`,
364- '```',
365- test.error || 'N/A',
366- '```',
367- ``,
368- `**Failure history:**`,
369- `- ${today}:`,
370- ciLinks,
371- ``,
372- `---`,
373- `*Auto-tracked by Test Failure Detector*`,
374- ].join('\n'),
375- });
376- console.log(` Created comment for test: ${test.test_name}`);
377- }
378- }
379- }
380-
381- console.log(`Done. Processed ${fileFailures.length} file(s).`);
174+ const script = require('./.github/scripts/create-or-update-issues.js');
175+ await script({github, context});
0 commit comments