@@ -29,15 +29,15 @@ interface RFC {
2929 filename : string ;
3030 html : string ;
3131 git : RFCGitInfo ;
32- authors : string [ ] | null ; // parsed from markdown frontmatter, overrides git author
32+ authors : GitHubAuthor [ ] ; // parsed from markdown frontmatter @usernames , or git author fallback
3333}
3434
3535interface ProposedRFC {
3636 number : string ;
3737 title : string ;
3838 prNumber : number ;
3939 prUrl : string ;
40- author : GitHubAuthor | null ;
40+ authors : GitHubAuthor [ ] ;
4141}
4242
4343const THEME_SCRIPT = `
@@ -151,19 +151,14 @@ function indexPage(
151151 . map ( ( rfc ) => {
152152 const dateStr = rfc . git . accepted ? formatDate ( rfc . git . accepted . date ) : "" ;
153153
154- let authorHTML = "" ;
155- if ( rfc . authors ) {
156- authorHTML = `<span class="rfc-author-name">${ rfc . authors . map ( escapeHTML ) . join ( ", " ) } </span>` ;
157- } else if ( rfc . git . author && rfc . git . accepted ) {
158- const commitUrl = repoUrl
159- ? `${ repoUrl } /commit/${ rfc . git . accepted . hash } `
160- : `https://github.com/${ rfc . git . author . login } ` ;
161- authorHTML = `
162- <a href="${ commitUrl } " class="rfc-author-link" title="${ rfc . git . author . login } ">
163- <img src="${ rfc . git . author . avatarUrl } " alt="${ rfc . git . author . login } " class="rfc-author-avatar">
164- <span class="rfc-author-name">${ rfc . git . author . login } </span>
165- </a>` ;
166- }
154+ const authorHTML = rfc . authors
155+ . map (
156+ ( author ) => `
157+ <a href="${ author . profileUrl } " class="rfc-author-link" title="${ author . login } ">
158+ <img src="${ author . avatarUrl } " alt="${ author . login } " class="rfc-author-avatar">
159+ </a>` ,
160+ )
161+ . join ( "" ) ;
167162
168163 return `
169164 <li>
@@ -180,14 +175,14 @@ function indexPage(
180175 if ( proposed . length > 0 ) {
181176 const proposedList = proposed
182177 . map ( ( rfc ) => {
183- let authorHTML = "" ;
184- if ( rfc . author ) {
185- authorHTML = `
186- <a href="${ rfc . author . profileUrl } " class="rfc-author-link" title="${ rfc . author . login } ">
187- <img src="${ rfc . author . avatarUrl } " alt="${ rfc . author . login } " class="rfc-author-avatar">
188- <span class="rfc-author-name"> ${ rfc . author . login } </span>
189- </a>` ;
190- }
178+ const authorHTML = rfc . authors
179+ . map (
180+ ( author ) => `
181+ <a href="${ author . profileUrl } " class="rfc-author-link" title="${ author . login } ">
182+ <img src="${ author . avatarUrl } " alt="${ author . login } " class="rfc-author-avatar">
183+ </a>` ,
184+ )
185+ . join ( "" ) ;
191186
192187 return `
193188 <li>
@@ -238,20 +233,20 @@ function rfcPage(
238233 <span class="rfc-status-pill status-accepted">Accepted</span>
239234 </div>` ;
240235
241- if ( rfc . git . accepted || rfc . git . author || rfc . authors ) {
242- // Author section
243- if ( rfc . authors ) {
236+ if ( rfc . git . accepted || rfc . authors . length > 0 ) {
237+ if ( rfc . authors . length > 0 ) {
238+ const authorsHTML = rfc . authors
239+ . map (
240+ ( author ) => `
241+ <a href="${ author . profileUrl } " class="author-link">
242+ <img src="${ author . avatarUrl } " alt="${ author . login } " class="author-avatar">
243+ <span class="author-name">${ author . login } </span>
244+ </a>` ,
245+ )
246+ . join ( ", " ) ;
244247 gitHeader += `
245248 <div class="rfc-meta-item rfc-author">
246- <span class="author-name">${ rfc . authors . map ( escapeHTML ) . join ( ", " ) } </span>
247- </div>` ;
248- } else if ( rfc . git . author ) {
249- gitHeader += `
250- <div class="rfc-meta-item rfc-author">
251- <a href="${ rfc . git . author . profileUrl } " class="author-link">
252- <img src="${ rfc . git . author . avatarUrl } " alt="${ rfc . git . author . login } " class="author-avatar">
253- <span class="author-name">${ rfc . git . author . login } </span>
254- </a>
249+ ${ authorsHTML }
255250 </div>` ;
256251 }
257252
@@ -422,17 +417,24 @@ async function validateProposals(): Promise<ValidationError[]> {
422417 return errors ;
423418}
424419
425- function parseAuthors ( markdown : string ) : string [ ] | null {
426- // Match "- Authors: Name1, Name2 " or "**Authors:** Name1, Name2 "
420+ function parseAuthorLogins ( markdown : string ) : string [ ] {
421+ // Match "- Authors: @user1, @user2 " or "**Authors:** @user 1, @user2 "
427422 const match = markdown . match (
428423 / ^ (?: - \s * A u t h o r s : \s * | \* \* A u t h o r s : \* \* \s * ) ( .+ ) $ / im,
429424 ) ;
430- if ( ! match ?. [ 1 ] ) return null ;
431- const authors = match [ 1 ]
425+ if ( ! match ?. [ 1 ] ) return [ ] ;
426+ return match [ 1 ]
432427 . split ( "," )
433- . map ( ( a ) => a . trim ( ) )
428+ . map ( ( a ) => a . trim ( ) . replace ( / ^ @ / , "" ) )
434429 . filter ( Boolean ) ;
435- return authors . length > 0 ? authors : null ;
430+ }
431+
432+ function loginsToAuthors ( logins : string [ ] ) : GitHubAuthor [ ] {
433+ return logins . map ( ( login ) => ( {
434+ login,
435+ avatarUrl : `https://github.com/${ login } .png?size=48` ,
436+ profileUrl : `https://github.com/${ login } ` ,
437+ } ) ) ;
436438}
437439
438440function parseTitle ( markdown : string , filename : string ) : string {
@@ -510,7 +512,7 @@ async function getProposedRFCs(
510512 if ( ! repoPath ) return [ ] ;
511513 try {
512514 const result =
513- await $ `gh pr list --repo ${ repoPath } --state open --json number,title,url,files,author` . quiet ( ) ;
515+ await $ `gh pr list --repo ${ repoPath } --state open --json number,title,url,files,author,headRefName ` . quiet ( ) ;
514516 const prs = JSON . parse ( result . stdout . toString ( ) ) ;
515517 const proposed : ProposedRFC [ ] = [ ] ;
516518
@@ -527,18 +529,30 @@ async function getProposedRFCs(
527529 const rfcNumber = rfcFile . path . match ( / ( \d { 4 } ) - / ) ?. [ 1 ] ;
528530 if ( ! rfcNumber ) continue ;
529531
532+ // Fetch file content from PR branch to parse authors
533+ let authors : GitHubAuthor [ ] = [ ] ;
534+ try {
535+ const fileResult =
536+ await $ `gh api repos/${ repoPath } /contents/${ rfcFile . path } ?ref=${ pr . headRefName } --jq '.content'` . quiet ( ) ;
537+ const content = atob ( fileResult . stdout . toString ( ) . trim ( ) ) ;
538+ const logins = parseAuthorLogins ( content ) ;
539+ if ( logins . length > 0 ) {
540+ authors = loginsToAuthors ( logins ) ;
541+ }
542+ } catch {
543+ // Fall back to PR author
544+ }
545+
546+ if ( authors . length === 0 && pr . author ) {
547+ authors = loginsToAuthors ( [ pr . author . login ] ) ;
548+ }
549+
530550 proposed . push ( {
531551 number : rfcNumber ,
532552 title : pr . title ,
533553 prNumber : pr . number ,
534554 prUrl : pr . url ,
535- author : pr . author
536- ? {
537- login : pr . author . login ,
538- avatarUrl : `https://github.com/${ pr . author . login } .png?size=48` ,
539- profileUrl : `https://github.com/${ pr . author . login } ` ,
540- }
541- : null ,
555+ authors,
542556 } ) ;
543557 }
544558
@@ -579,8 +593,14 @@ async function build(liveReload: boolean = false): Promise<number> {
579593 const html = await highlightCodeBlocks ( rawHtml ) ;
580594 const number = parseRFCNumber ( filename ) ;
581595 const title = parseTitle ( content , filename ) ;
582- const authors = parseAuthors ( content ) ;
596+ const authorLogins = parseAuthorLogins ( content ) ;
583597 const git = await getGitHistory ( path , repoPath ) ;
598+ const authors =
599+ authorLogins . length > 0
600+ ? loginsToAuthors ( authorLogins )
601+ : git . author
602+ ? [ git . author ]
603+ : [ ] ;
584604
585605 rfcs . push ( { number, title, filename, html, git, authors } ) ;
586606 }
@@ -738,8 +758,14 @@ async function buildPreview(): Promise<void> {
738758 const html = await highlightCodeBlocks ( rawHtml ) ;
739759 const number = parseRFCNumber ( filename ) ;
740760 const title = parseTitle ( content , filename ) ;
741- const authors = parseAuthors ( content ) ;
761+ const authorLogins = parseAuthorLogins ( content ) ;
742762 const git = await getGitHistory ( path , repoPath ) ;
763+ const authors =
764+ authorLogins . length > 0
765+ ? loginsToAuthors ( authorLogins )
766+ : git . author
767+ ? [ git . author ]
768+ : [ ] ;
743769
744770 rfcs . push ( { number, title, filename, html, git, authors } ) ;
745771 }
0 commit comments