@@ -86,7 +86,7 @@ function extractPRFlavor(prTitle, prBranchRef) {
8686 return "" ;
8787}
8888
89- /// Find insertion point for changelog entry in a specific section
89+ /// Find insertion point and determine what content needs to be inserted
9090function findChangelogInsertionPoint ( changelogContent , sectionName ) {
9191 const lines = changelogContent . split ( '\n' ) ;
9292
@@ -99,15 +99,38 @@ function findChangelogInsertionPoint(changelogContent, sectionName) {
9999 }
100100 }
101101
102+ // Case 1: No Unreleased section exists
102103 if ( unreleasedIndex === - 1 ) {
103- return null ; // No Unreleased section found
104+ // Find first ## section or top of changelog to insert before it
105+ let insertionPoint = 0 ;
106+
107+ // Skip title and initial content, look for first version section
108+ for ( let i = 0 ; i < lines . length ; i ++ ) {
109+ if ( lines [ i ] . trim ( ) . match ( / ^ # # \s + / ) ) {
110+ insertionPoint = i ;
111+ break ;
112+ }
113+ }
114+
115+ // If no version sections exist, insert at end
116+ if ( insertionPoint === 0 ) {
117+ insertionPoint = lines . length ;
118+ }
119+
120+ return {
121+ lineNumber : insertionPoint + 1 , // 1-indexed for GitHub API
122+ insertContent : 'unreleased-and-section'
123+ } ;
104124 }
105125
106- // Find the target subsection (e.g., "### Features")
126+ // Case 2: Unreleased section exists, find the target subsection
107127 let sectionIndex = - 1 ;
128+ let nextSectionIndex = lines . length ; // End of file by default
129+
108130 for ( let i = unreleasedIndex + 1 ; i < lines . length ; i ++ ) {
109131 // Stop if we hit another main section (##)
110132 if ( lines [ i ] . trim ( ) . match ( / ^ # # \s + / ) ) {
133+ nextSectionIndex = i ;
111134 break ;
112135 }
113136
@@ -118,40 +141,37 @@ function findChangelogInsertionPoint(changelogContent, sectionName) {
118141 }
119142 }
120143
144+ // Case 3: Subsection doesn't exist, need to create it within Unreleased
121145 if ( sectionIndex === - 1 ) {
122- // Section doesn't exist, we need to create it
123- // Find insertion point after "## Unreleased"
146+ // Find insertion point after "## Unreleased" but before next main section
124147 let insertAfter = unreleasedIndex ;
125148
126149 // Skip empty lines after "## Unreleased"
127- while ( insertAfter + 1 < lines . length && lines [ insertAfter + 1 ] . trim ( ) === '' ) {
150+ while ( insertAfter + 1 < nextSectionIndex && lines [ insertAfter + 1 ] . trim ( ) === '' ) {
128151 insertAfter ++ ;
129152 }
130153
131154 return {
132155 lineNumber : insertAfter + 1 , // 1-indexed for GitHub API
133- createSection : true ,
134- sectionName : sectionName
156+ insertContent : 'section-and-entry'
135157 } ;
136158 }
137159
138- // Section exists, find first bullet point or insertion point
160+ // Case 4: Both Unreleased and subsection exist, just add entry
139161 let insertionPoint = sectionIndex + 1 ;
140162
141163 // Skip empty lines after section header
142- while ( insertionPoint < lines . length && lines [ insertionPoint ] . trim ( ) === '' ) {
164+ while ( insertionPoint < nextSectionIndex && lines [ insertionPoint ] . trim ( ) === '' ) {
143165 insertionPoint ++ ;
144166 }
145167
146- // If next line is a bullet point, insert before it
147- // If it's another section or end of file, insert here
148168 return {
149169 lineNumber : insertionPoint + 1 , // 1-indexed for GitHub API
150- createSection : false
170+ insertContent : 'entry-only'
151171 } ;
152172}
153173
154- /// Generate suggestion text for changelog entry
174+ /// Generate suggestion text for changelog entry based on what needs to be inserted
155175function generateChangelogSuggestion ( prTitle , prNumber , prUrl , sectionName , insertionInfo ) {
156176 // Clean up PR title (remove conventional commit prefix if present)
157177 const cleanTitle = prTitle
@@ -162,12 +182,22 @@ function generateChangelogSuggestion(prTitle, prNumber, prUrl, sectionName, inse
162182
163183 const bulletPoint = `- ${ cleanTitle } ([#${ prNumber } ](${ prUrl } ))` ;
164184
165- if ( insertionInfo . createSection ) {
166- // Need to create the section
167- return `\n### ${ sectionName } \n\n${ bulletPoint } ` ;
168- } else {
169- // Just add the bullet point
170- return bulletPoint ;
185+ switch ( insertionInfo . insertContent ) {
186+ case 'unreleased-and-section' :
187+ // Need to create both Unreleased section and subsection
188+ return `## Unreleased\n\n### ${ sectionName } \n\n${ bulletPoint } \n` ;
189+
190+ case 'section-and-entry' :
191+ // Need to create subsection within existing Unreleased
192+ return `\n### ${ sectionName } \n\n${ bulletPoint } ` ;
193+
194+ case 'entry-only' :
195+ // Just add the bullet point to existing section
196+ return bulletPoint ;
197+
198+ default :
199+ // Fallback to entry-only
200+ return bulletPoint ;
171201 }
172202}
173203
0 commit comments