1+ import { matchPattern , parse } from 'codeowners-utils' ;
2+ import { readFileSync } from 'node:fs' ;
3+
4+ const { GITHUB_TOKEN , PR_NUMBER , REPO_OWNER , REPO_NAME } = process . env ;
5+
6+ async function githubRequest ( path , options = { } ) {
7+ const response = await fetch ( `https://api.github.com${ path } ` , {
8+ ...options ,
9+ headers : {
10+ 'Authorization' : `Bearer ${ GITHUB_TOKEN } ` ,
11+ 'Accept' : 'application/vnd.github.v3+json' ,
12+ 'X-GitHub-Api-Version' : '2022-11-28' ,
13+ ...options . headers ,
14+ } ,
15+ } ) ;
16+ if ( ! response . ok ) {
17+ throw new Error ( `GitHub API error: ${ response . status } ${ response . statusText } ` ) ;
18+ }
19+ return response . json ( ) ;
20+ }
21+
22+ async function getChangedFiles ( ) {
23+ const files = [ ] ;
24+ let page = 1 ;
25+ while ( true ) {
26+ const data = await githubRequest (
27+ `/repos/${ REPO_OWNER } /${ REPO_NAME } /pulls/${ PR_NUMBER } /files?per_page=100&page=${ page } ` ,
28+ ) ;
29+ files . push ( ...data . map ( ( f ) => f . filename ) ) ;
30+ if ( data . length < 100 ) break ;
31+ page ++ ;
32+ }
33+ return files ;
34+ }
35+
36+ export function getOwnersForPaths ( codeownersContent , changedFiles ) {
37+ const definitions = parse ( codeownersContent ) ;
38+ let ownersForPaths = [ ] ;
39+
40+ for ( const { pattern, owners } of definitions ) {
41+ for ( const file of changedFiles ) {
42+ if ( matchPattern ( file , pattern ) ) {
43+ ownersForPaths = ownersForPaths . concat ( owners ) ;
44+ }
45+ }
46+ }
47+
48+ return ownersForPaths . filter ( ( v , i ) => ownersForPaths . indexOf ( v ) === i ) . sort ( ) ;
49+ }
50+
51+ export function getCommentBody ( owners ) {
52+ return `Review requested:\n\n${ owners . map ( ( i ) => `- [ ] ${ i } ` ) . join ( '\n' ) } ` ;
53+ }
54+
55+ try {
56+ const changedFiles = await getChangedFiles ( ) ;
57+ const codeownersContent = readFileSync ( '.github/CODEOWNERS' , 'utf8' ) ;
58+ const owners = getOwnersForPaths ( codeownersContent , changedFiles ) ;
59+ if ( owners . length !== 0 ) {
60+ await githubRequest (
61+ `/repos/${ REPO_OWNER } /${ REPO_NAME } /issues/${ PR_NUMBER } /comments` ,
62+ {
63+ method : 'POST' ,
64+ body : JSON . stringify ( { body : getCommentBody ( owners ) } ) ,
65+ } ,
66+ ) ;
67+ }
68+ } catch ( err ) {
69+ console . error ( err ) ;
70+ process . exitCode = 1 ;
71+ }
0 commit comments