@@ -88,27 +88,48 @@ function readCommits(previousTag, currentRef) {
8888}
8989
9090function groupCommits ( commits ) {
91- const prs = [ ] ;
92- const seenPrs = new Set ( ) ;
93- const directCommits = [ ] ;
94- for ( const commit of commits ) {
95- if ( commit . pr ) {
96- if ( ! seenPrs . has ( commit . pr ) ) {
97- seenPrs . add ( commit . pr ) ;
98- prs . push ( commit ) ;
99- }
100- } else {
101- directCommits . push ( commit ) ;
102- }
103- }
104- return { prs, directCommits } ;
91+ return { directCommits : commits } ;
10592}
10693
10794function formatContributorName ( author ) {
10895 const value = String ( author || '' ) . trim ( ) ;
10996 return value || 'Unknown contributor' ;
11097}
11198
99+ const CONTRIBUTOR_PROFILES = new Map ( [
100+ [ 'awsl' , { login : 'awsl233777' , displayName : 'Awsl' } ] ,
101+ [ 'awsl233777' , { login : 'awsl233777' , displayName : 'Awsl' } ]
102+ ] ) ;
103+
104+ function escapeHtml ( value ) {
105+ return String ( value || '' )
106+ . replace ( / & / g, '&' )
107+ . replace ( / < / g, '<' )
108+ . replace ( / > / g, '>' )
109+ . replace ( / " / g, '"' )
110+ . replace ( / ' / g, ''' ) ;
111+ }
112+
113+ function contributorProfile ( author ) {
114+ const displayName = formatContributorName ( author ) ;
115+ const mapped = CONTRIBUTOR_PROFILES . get ( displayName . toLowerCase ( ) ) ;
116+ if ( mapped ) return mapped ;
117+ return { login : displayName , displayName } ;
118+ }
119+
120+ function formatContributorCard ( author ) {
121+ const { login, displayName } = contributorProfile ( author ) ;
122+ const safeLogin = encodeURIComponent ( login ) ;
123+ const safeDisplayName = escapeHtml ( displayName ) ;
124+ const githubAvatarUrl = `https://github.com/${ safeLogin } .png?size=96` ;
125+ const roundedAvatarUrl = `https://wsrv.nl/?url=${ encodeURIComponent ( githubAvatarUrl ) } &w=96&h=96&fit=cover&mask=circle` ;
126+ return [
127+ `<a href="https://github.com/${ safeLogin } " title="${ safeDisplayName } ">` ,
128+ ` <img src="${ roundedAvatarUrl } " width="64" height="64" alt="${ safeDisplayName } " />` ,
129+ `</a>`
130+ ] . join ( '\n' ) ;
131+ }
132+
112133function listContributors ( commits ) {
113134 const seen = new Set ( ) ;
114135 const contributors = [ ] ;
@@ -128,39 +149,60 @@ function compareUrl(repository, previousTag, currentTag, currentRef) {
128149 return `https://github.com/${ repository } /compare/${ previousTag } ...${ right } ` ;
129150}
130151
152+ function stripPullRequestSuffix ( subject ) {
153+ return String ( subject || '' ) . replace ( / \s * \( # \d + \) \s * $ / , '' ) . trim ( ) ;
154+ }
155+
156+ function formatChangeSummaryLine ( commit ) {
157+ const subject = stripPullRequestSuffix ( commit ?. subject || '' ) ;
158+ if ( ! subject ) return '' ;
159+ if ( / ^ c h o r e : \s * b u m p v e r s i o n \b / i. test ( subject ) ) return '' ;
160+
161+ const conventional = subject . match ( / ^ ( \w + ) (?: \( ( [ ^ ) ] + ) \) ) ? : \s * ( .+ ) $ / ) ;
162+ const summary = conventional
163+ ? `${ conventional [ 2 ] ? `${ conventional [ 2 ] } : ` : '' } ${ conventional [ 3 ] } `
164+ : subject ;
165+ return `- ${ summary } ${ commit . pr ? ` (#${ commit . pr } )` : '' } ` ;
166+ }
167+
168+ function formatChangeSummary ( commits ) {
169+ const lines = [ ] ;
170+ const seen = new Set ( ) ;
171+ for ( const commit of commits ) {
172+ const line = formatChangeSummaryLine ( commit ) ;
173+ if ( ! line ) continue ;
174+ const key = line . toLowerCase ( ) ;
175+ if ( seen . has ( key ) ) continue ;
176+ seen . add ( key ) ;
177+ lines . push ( line ) ;
178+ }
179+ return lines ;
180+ }
181+
131182function formatChangelog ( { repository = '' , previousTag = '' , currentTag = '' , currentRef = 'HEAD' , commits = [ ] } ) {
132- const currentLabel = currentTag || currentRef || 'HEAD' ;
133183 const lines = [ ] ;
134- const releaseName = repository ? repository . split ( '/' ) . pop ( ) : 'Release' ;
135- lines . push ( `## ${ releaseName } ${ currentLabel } ` ) ;
136- lines . push ( '' ) ;
137184
138185 if ( ! previousTag ) {
139- lines . push ( `### Changes` ) ;
140186 lines . push ( 'No previous semver tag was found. Treating this as the initial release.' ) ;
141187 lines . push ( '' ) ;
142188 lines . push ( '### Contributors' ) ;
143189 lines . push ( '- Unknown contributor' ) ;
144190 return `${ lines . join ( '\n' ) } \n` ;
145191 }
146192
147- lines . push ( `### Changes since ${ previousTag } ` ) ;
148- lines . push ( '' ) ;
149-
150- const { prs, directCommits } = groupCommits ( commits ) ;
193+ const { directCommits } = groupCommits ( commits ) ;
151194 if ( ! commits . length ) {
152195 lines . push ( 'No commits found in this range.' ) ;
153196 } else {
154- if ( prs . length ) {
155- lines . push ( 'PRs:' ) ;
156- for ( const commit of prs ) {
157- lines . push ( `- #${ commit . pr } ${ commit . subject . replace ( / \s * \( # \d + \) \s * $ / , '' ) } (${ commit . hash } )` ) ;
158- }
197+ const changeSummary = formatChangeSummary ( [ ...commits ] . reverse ( ) ) ;
198+ if ( changeSummary . length ) {
199+ lines . push ( '### Changes' ) ;
200+ lines . push ( ...changeSummary ) ;
159201 lines . push ( '' ) ;
160202 }
161203
162204 if ( directCommits . length ) {
163- lines . push ( 'Commits without PR: ' ) ;
205+ lines . push ( '### Commits without PR' ) ;
164206 for ( const commit of directCommits ) {
165207 lines . push ( `- ${ commit . hash } ${ commit . subject } ${ commit . author ? ` — ${ commit . author } ` : '' } ` ) ;
166208 }
@@ -179,9 +221,7 @@ function formatChangelog({ repository = '', previousTag = '', currentTag = '', c
179221 if ( ! contributors . length ) {
180222 lines . push ( '- Unknown contributor' ) ;
181223 } else {
182- for ( const contributor of contributors ) {
183- lines . push ( `- ${ contributor } ` ) ;
184- }
224+ lines . push ( contributors . map ( formatContributorCard ) . join ( '\n \n' ) ) ;
185225 }
186226 return `${ lines . join ( '\n' ) . replace ( / \n { 3 , } / g, '\n\n' ) } \n` ;
187227}
@@ -233,6 +273,11 @@ module.exports = {
233273 parseLogLine,
234274 groupCommits,
235275 listContributors,
276+ contributorProfile,
277+ formatContributorCard,
278+ stripPullRequestSuffix,
279+ formatChangeSummaryLine,
280+ formatChangeSummary,
236281 compareUrl,
237282 formatChangelog,
238283 main
0 commit comments