@@ -21,6 +21,8 @@ import {
2121 extractPreservedBlocks ,
2222 buildReleaseNotesYaml ,
2323 appendNoteLines ,
24+ isSameNoteEntry ,
25+ replaceEntriesForSource ,
2426} from '@/ghes-releases/lib/parse-release-notes'
2527import {
2628 type IssueState ,
@@ -577,14 +579,12 @@ program
577579 preserved = extractPreservedBlocks ( existingContent ) ?? undefined
578580 const existing = loadExistingEntriesFromString ( existingContent )
579581 if ( existing . entries . length > 0 ) {
580- // Regenerate a single issue by dropping its previous source URL entry first .
582+ // Keep the issue's current entry until the agent produces a replacement .
581583 if ( singleIssue ) {
582- const issueUrl = `https://github.com/github/releases/issues/${ singleIssue } `
583- const kept = existing . entries . filter ( ( e ) => e . sourceUrl !== issueUrl )
584- allEntries . push ( ...kept )
585- existing . coveredUrls . delete ( issueUrl )
586- existingCoveredUrls = existing . coveredUrls
587- console . log ( ` Loaded ${ kept . length } existing note(s), will regenerate #${ singleIssue } ` )
584+ allEntries . push ( ...existing . entries )
585+ console . log (
586+ ` Loaded ${ existing . entries . length } existing note(s), will regenerate #${ singleIssue } ` ,
587+ )
588588 } else {
589589 allEntries . push ( ...existing . entries )
590590 existingCoveredUrls = existing . coveredUrls
@@ -622,12 +622,14 @@ program
622622
623623 const failures : { issue : ReleaseIssue ; error : string } [ ] = [ ]
624624 const existingEntryCount = allEntries . length
625+ let newCount = 0
625626
626627 const featureHeadings = loadFeatureHeadings ( )
627628
628629 // Flush after each success and on Ctrl+C so long runs keep completed notes.
629630 const writeCurrentOutput = ( ) => {
630- if ( stdout || allEntries . length === 0 ) return
631+ // Skip when nothing is new because rebuilding drops known issues, the date, and stacked source URL comments.
632+ if ( stdout || newCount === 0 ) return
631633 try {
632634 if ( ! fs . existsSync ( outputDir ) ) {
633635 fs . mkdirSync ( outputDir , { recursive : true } )
@@ -688,17 +690,16 @@ program
688690 }
689691 }
690692
691- // Avoid duplicates when an existing file already contributed the same issue note.
692- for ( const entry of entries ) {
693- const isDuplicate = allEntries . some (
694- ( existing ) =>
695- existing . sourceUrl === entry . sourceUrl &&
696- existing . heading === entry . heading &&
697- existing . notes . length === entry . notes . length &&
698- existing . notes . every ( ( n , idx ) => n === entry . notes [ idx ] ) ,
699- )
700- if ( ! isDuplicate ) {
701- allEntries . push ( entry )
693+ if ( singleIssue ) {
694+ newCount += replaceEntriesForSource ( allEntries , issue . url , entries )
695+ } else {
696+ // Avoid duplicates when an existing file already contributed the same issue note.
697+ for ( const entry of entries ) {
698+ const isDuplicate = allEntries . some ( ( existing ) => isSameNoteEntry ( existing , entry ) )
699+ if ( ! isDuplicate ) {
700+ allEntries . push ( entry )
701+ newCount ++
702+ }
702703 }
703704 }
704705 const retryNote = result . attempts > 1 ? ` (attempt ${ result . attempts } )` : ''
@@ -734,10 +735,9 @@ program
734735 }
735736
736737 flushBeforeExit = null
737- const newCount = allEntries . length - existingEntryCount
738738 if ( existingEntryCount > 0 ) {
739739 console . log (
740- `\nTotal: ${ allEntries . length } note(s) (${ existingEntryCount } existing + ${ newCount } new from ${ issues . length } issues)` ,
740+ `\nTotal: ${ allEntries . length } note(s) (${ allEntries . length - newCount } existing + ${ newCount } new from ${ issues . length } issues)` ,
741741 )
742742 } else {
743743 console . log ( `\nGenerated ${ allEntries . length } note(s) from ${ issues . length } issues` )
@@ -774,11 +774,11 @@ program
774774 console . log ( '\n--- Generated YAML ---\n' )
775775 console . log ( yamlOutput )
776776 }
777- } else if ( allEntries . length > 0 ) {
777+ } else if ( newCount > 0 ) {
778778 writeCurrentOutput ( )
779779 console . log ( `\n✅ Written to: ${ path . relative ( process . cwd ( ) , outputPath ) } ` )
780780 } else {
781- console . log ( '\nNo entries generated — no file written.' )
781+ console . log ( '\nNo new notes generated. No file written.' )
782782 }
783783
784784 // Clean up stdin raw mode so the process can exit gracefully.
0 commit comments