@@ -105,7 +105,53 @@ function filterCommitsByDate(commits) {
105105 } ) ;
106106}
107107
108- function categorizeCommits ( commits ) {
108+ function extractPRNumber ( commitMessage ) {
109+ // Extract PR number from commit message like "(#14813)"
110+ const match = commitMessage . match ( / \( # ( \d + ) \) / ) ;
111+ return match ? parseInt ( match [ 1 ] ) : null ;
112+ }
113+
114+ async function fetchPRDetails ( prNumber ) {
115+ if ( ! prNumber ) return null ;
116+
117+ try {
118+ const url = `https://api.github.com/repos/${ REPO } /pulls/${ prNumber } ` ;
119+ const res = await fetch ( url , { headers : HEADERS } ) ;
120+
121+ if ( ! res . ok ) {
122+ console . warn ( `Failed to fetch PR #${ prNumber } : ${ res . status } ` ) ;
123+ return null ;
124+ }
125+
126+ return await res . json ( ) ;
127+ } catch ( error ) {
128+ console . warn ( `Error fetching PR #${ prNumber } :` , error . message ) ;
129+ return null ;
130+ }
131+ }
132+
133+ function extractReleaseNotesSummary ( prDescription ) {
134+ if ( ! prDescription ) return null ;
135+
136+ // Look for the release notes summary marker
137+ const marker = 'Add a brief summary of the change to use in the release notes for the next release.' ;
138+ const markerIndex = prDescription . indexOf ( marker ) ;
139+
140+ if ( markerIndex === - 1 ) return null ;
141+
142+ // Get text after the marker
143+ const afterMarker = prDescription . substring ( markerIndex + marker . length ) ;
144+
145+ // Extract the next line or paragraph after the marker
146+ const lines = afterMarker . split ( '\n' ) . map ( line => line . trim ( ) ) . filter ( line => line . length > 0 ) ;
147+
148+ if ( lines . length === 0 ) return null ;
149+
150+ // Return the first non-empty line after the marker
151+ return lines [ 0 ] ;
152+ }
153+
154+ async function categorizeCommits ( commits ) {
109155// TODO: Update logic for commits categorisation, refer 'All Commits' section for all the commits.
110156 const categories = {
111157 'All Commits' : [ ] ,
@@ -147,7 +193,25 @@ function categorizeCommits(commits) {
147193 const lowerMsg = msg . toLowerCase ( ) ;
148194 const sha = c . sha . slice ( 0 , 7 ) ;
149195 const url = c . html_url ;
150- const entry = `- ${ msg . split ( '\n' ) [ 0 ] } [${ msg . split ( '\n' ) [ 0 ] } · ${ REPO } @${ sha } (github.com)](${ url } )` ;
196+ const commitTitle = msg . split ( '\n' ) [ 0 ] ;
197+
198+ // Try to get a better summary from PR description
199+ const prNumber = extractPRNumber ( commitTitle ) ;
200+ let summary = commitTitle ;
201+
202+ if ( prNumber ) {
203+ console . log ( `Fetching PR details for #${ prNumber } ...` ) ;
204+ const prDetails = await fetchPRDetails ( prNumber ) ;
205+ if ( prDetails ) {
206+ const releaseNotesSummary = extractReleaseNotesSummary ( prDetails . body ) ;
207+ if ( releaseNotesSummary ) {
208+ summary = releaseNotesSummary ;
209+ console . log ( `Found release notes summary for PR #${ prNumber } : ${ summary } ` ) ;
210+ }
211+ }
212+ }
213+
214+ const entry = `- ${ summary } [${ commitTitle } · ${ REPO } @${ sha } (github.com)](${ url } )` ;
151215
152216 const matched = Object . keys ( keywords ) . filter ( ( k ) =>
153217 keywords [ k ] . some ( ( word ) => lowerMsg . includes ( word ) )
@@ -198,7 +262,7 @@ function generateReleaseNotes(commits, categories) {
198262async function main ( ) {
199263 const commits = await fetchCommits ( ) ;
200264 const filtered = filterCommitsByDate ( commits ) ;
201- const categories = categorizeCommits ( filtered ) ;
265+ const categories = await categorizeCommits ( filtered ) ;
202266 const notes = generateReleaseNotes ( filtered , categories ) ;
203267 fs . writeFileSync ( 'release_notes.md' , notes , 'utf8' ) ;
204268}
0 commit comments