@@ -251,6 +251,52 @@ async function findRelatedPR(github, context, core, workflowRun) {
251251 return null ;
252252}
253253
254+ async function findExistingRetryComment ( github , context , core , pr ) {
255+ try {
256+ // Get comments for the PR
257+ const { data : comments } = await github . rest . issues . listComments ( {
258+ owner : context . repo . owner ,
259+ repo : context . repo . repo ,
260+ issue_number : pr . number ,
261+ per_page : 100
262+ } ) ;
263+
264+ // Look for our smart retry analysis comment
265+ const retryComment = comments . find ( comment =>
266+ comment . user . type === 'Bot' &&
267+ comment . body . includes ( '## 🤖 Smart Auto-retry Analysis' )
268+ ) ;
269+
270+ if ( retryComment ) {
271+ core . info ( `Found existing retry analysis comment: ${ retryComment . id } ` ) ;
272+ return retryComment ;
273+ }
274+
275+ core . info ( 'No existing retry analysis comment found' ) ;
276+ return null ;
277+ } catch ( error ) {
278+ core . warning ( `Failed to find existing retry comment: ${ error . message } ` ) ;
279+ return null ;
280+ }
281+ }
282+
283+ function getRetryCount ( existingComment ) {
284+ if ( ! existingComment ) return 0 ;
285+
286+ // Try to extract retry count from the title
287+ const titleMatch = existingComment . body . match ( / # # 🤖 S m a r t A u t o - r e t r y A n a l y s i s \s * (?: \( R e t r y # ( \d + ) \) ) ? / ) ;
288+ if ( titleMatch && titleMatch [ 1 ] ) {
289+ return parseInt ( titleMatch [ 1 ] , 10 ) ;
290+ }
291+
292+ // If no retry count in title, check if it's a retry by looking for retry indicators
293+ if ( existingComment . body . includes ( '### ✅ **AUTO-RETRY INITIATED**' ) ) {
294+ return 1 ; // This is likely the first retry
295+ }
296+
297+ return 0 ;
298+ }
299+
254300async function addCommentToPR ( github , context , core , runID , runURL , failedJobs , analyzedJobs , retryableJobsCount , priorityCancelled ) {
255301 try {
256302 // Get workflow run to find the branch
@@ -268,107 +314,93 @@ async function addCommentToPR(github, context, core, runID, runURL, failedJobs,
268314 return ;
269315 }
270316
271- let comment = `## 🤖 Smart Auto-retry Analysis
317+ // Try to find existing retry comment
318+ const existingComment = await findExistingRetryComment ( github , context , core , pr ) ;
272319
273- > **Workflow Run:** [\`${ runID } \`](${ runURL } )
320+ // Get current retry count
321+ const currentRetryCount = getRetryCount ( existingComment ) ;
322+ const newRetryCount = retryableJobsCount > 0 ? currentRetryCount + 1 : currentRetryCount ;
274323
275- The workflow run has been analyzed for retryable errors using job annotations.
324+ // Build title with retry count
325+ const titleSuffix = newRetryCount > 0 ? ` (Retry #${ newRetryCount } )` : '' ;
276326
277- ---
327+ let comment = `## 🤖 Smart Auto-retry Analysis ${ titleSuffix }
278328
279- ### 📊 Analysis Summary
329+ > **Workflow:** [\` ${ runID } \`]( ${ runURL } )
280330
281- | Metric | Count |
282- |--------|-------|
283- | **Total Failed/Cancelled Jobs** | \`${ failedJobs . length } \` |
284- | **Jobs with Retryable Errors** | \`${ retryableJobsCount } \` |
285- | **Jobs with Code/Test Issues** | \`${ failedJobs . length - retryableJobsCount } \` |` ;
331+ ### 📊 Summary
332+ - **Failed Jobs:** ${ failedJobs . length }
333+ - **Retryable:** ${ retryableJobsCount }
334+ - **Code Issues:** ${ failedJobs . length - retryableJobsCount } ` ;
286335
287336 if ( priorityCancelled ) {
288337 comment += `
289338
290- ### ⛔️ Retry Status: **CANCELLED**
291-
292- > **Reason:** Higher priority request detected - retry has been cancelled to avoid resource conflicts.` ;
339+ ### ⛔️ **CANCELLED**
340+ Higher priority request detected - retry cancelled to avoid conflicts.` ;
293341 } else if ( retryableJobsCount > 0 ) {
294342 comment += `
295343
296- ### ✅ Retry Status: **AUTOMATIC RETRY INITIATED**
344+ ### ✅ **AUTO-RETRY INITIATED**
345+ **${ retryableJobsCount } job(s)** retried due to infrastructure issues (runner failures, timeouts, etc.)
297346
298- > **${ retryableJobsCount } job(s)** have been automatically retried due to infrastructure issues detected in annotations:
299- > - Runner communication failures
300- > - Network timeouts
301- > - Resource exhaustion
302- > - Other transient infrastructure problems
303-
304- **📈 Monitor Progress:** [View in Actions](${ runURL } )` ;
347+ [View Progress](${ runURL } )` ;
305348 } else {
306349 comment += `
307350
308- ### ❌ Retry Status: **NO RETRY NEEDED**
309-
310- > All failures appear to be **code or test related issues** that require manual fixes rather than automatic retries.` ;
351+ ### ❌ **NO RETRY NEEDED**
352+ All failures appear to be code/test issues requiring manual fixes.` ;
311353 }
312354
313355 comment += `
314356
315- ---
316-
317- ### 🔍 Detailed Job Analysis
318-
357+ ### 🔍 Job Details
319358${ analyzedJobs . map ( job => {
320359 if ( job . reason . includes ( 'Analysis failed' ) ) {
321- return `#### ❓ **${ job . name } **
322- > **Status:** Analysis failed
323- > **Reason:** ${ job . reason } ` ;
360+ return `- ❓ **${ job . name } **: Analysis failed` ;
324361 }
325362 if ( job . reason . includes ( 'Cancelled by higher priority' ) ) {
326- return `#### ⛔️ **${ job . name } **
327- > **Status:** Cancelled by higher priority request
328- > **Reason:** ${ job . reason } ` ;
363+ return `- ⛔️ **${ job . name } **: Cancelled by higher priority` ;
329364 }
330365 if ( job . reason . includes ( 'No annotations found' ) ) {
331- return `#### ❓ **${ job . name } **
332- > **Status:** No annotations available
333- > **Reason:** ${ job . reason } ` ;
366+ return `- ❓ **${ job . name } **: No annotations available` ;
334367 }
335368 if ( job . retryable ) {
336- return `#### 🔄 **${ job . name } **
337- > **Status:** ✅ **Retryable** (Infrastructure Issue)
338- > **Reason:** ${ job . reason }
339- > **Annotations:** ${ job . annotationCount } found` ;
369+ return `- 🔄 **${ job . name } **: ✅ Retryable (Infrastructure)` ;
340370 } else {
341- return `#### ❌ **${ job . name } **
342- > **Status:** Not retryable (Code/Test Issue)
343- > **Reason:** ${ job . reason }
344- > **Annotations:** ${ job . annotationCount } found` ;
371+ return `- ❌ **${ job . name } **: Not retryable (Code/Test)` ;
345372 }
346- } ) . join ( '\n\n ' ) }
373+ } ) . join ( '\n' ) }
347374
348375---
349376
350377<details>
351- <summary>🤖 About This Analysis</summary>
352-
353- This is an **automated analysis and retry** triggered by the smart retry workflow using job annotations. The system analyzes failure patterns to distinguish between:
354-
355- - **🔄 Infrastructure Issues:** Runner failures, network timeouts, resource exhaustion
356- - **❌ Code/Test Issues:** Compilation errors, test failures, logic problems
357-
358- Only infrastructure issues are automatically retried to avoid wasting resources on code problems that need manual fixes.
378+ <summary>🤖 About</summary>
359379
380+ Automated analysis using job annotations to distinguish infrastructure issues (auto-retried) from code/test issues (manual fixes needed).
360381</details>` ;
361382
362- await github . rest . issues . createComment ( {
363- owner : context . repo . owner ,
364- repo : context . repo . repo ,
365- issue_number : pr . number ,
366- body : comment
367- } ) ;
368-
369- core . info ( `Added smart retry analysis comment to PR #${ pr . number } ` ) ;
383+ if ( existingComment ) {
384+ // Update existing comment
385+ await github . rest . issues . updateComment ( {
386+ owner : context . repo . owner ,
387+ repo : context . repo . repo ,
388+ comment_id : existingComment . id ,
389+ body : comment
390+ } ) ;
391+ core . info ( `Updated existing smart retry analysis comment on PR #${ pr . number } (Retry #${ newRetryCount } )` ) ;
392+ } else {
393+ // Create new comment
394+ await github . rest . issues . createComment ( {
395+ owner : context . repo . owner ,
396+ repo : context . repo . repo ,
397+ issue_number : pr . number ,
398+ body : comment
399+ } ) ;
400+ core . info ( `Added new smart retry analysis comment to PR #${ pr . number } ` ) ;
401+ }
370402 } catch ( error ) {
371- core . error ( `Failed to add comment to PR:` , error . message ) ;
403+ core . error ( `Failed to add/update comment to PR:` , error . message ) ;
372404 }
373405}
374406
0 commit comments