@@ -41,6 +41,41 @@ module.exports = async ({ github, context, core }) => {
4141 now . getTime ( ) - NO_RESPONSE_DAYS * 24 * 60 * 60 * 1000 ,
4242 ) ;
4343
44+ const maintainerCache = new Map ( ) ;
45+ async function isMaintainer ( user , association ) {
46+ if ( user ?. type === 'Bot' ) return true ;
47+ if ( [ 'OWNER' , 'MEMBER' , 'COLLABORATOR' ] . includes ( association ) ) return true ;
48+
49+ const username = user ?. login ;
50+ if ( ! username ) return false ;
51+
52+ if ( maintainerCache . has ( username ) ) {
53+ return maintainerCache . get ( username ) ;
54+ }
55+
56+ try {
57+ const { data } = await github . rest . repos . getCollaboratorPermissionLevel ( {
58+ owner,
59+ repo,
60+ username,
61+ } ) ;
62+ // Permission can be admin, write, read, none.
63+ // Roles like 'maintain' or 'triage' often map to 'write' or 'read' in the top-level field.
64+ const isM =
65+ [ 'admin' , 'write' ] . includes ( data . permission ) ||
66+ [ 'admin' , 'maintain' , 'write' ] . includes ( data . role_name ) ;
67+
68+ maintainerCache . set ( username , isM ) ;
69+ return isM ;
70+ } catch ( err ) {
71+ core . warning (
72+ `Could not check permissions for ${ username } : ${ err . message } ` ,
73+ ) ;
74+ maintainerCache . set ( username , false ) ;
75+ return false ;
76+ }
77+ }
78+
4479 async function processItems ( query , callback ) {
4580 core . info ( `Searching: ${ query } ` ) ;
4681 try {
@@ -83,10 +118,7 @@ module.exports = async ({ github, context, core }) => {
83118 const lastComment = comments [ 0 ] ;
84119 if (
85120 lastComment &&
86- ! [ 'OWNER' , 'MEMBER' , 'COLLABORATOR' ] . includes (
87- lastComment . author_association ,
88- ) &&
89- lastComment . user ?. type !== 'Bot'
121+ ! ( await isMaintainer ( lastComment . user , lastComment . author_association ) )
90122 ) {
91123 core . info (
92124 `Removing ${ NEED_INFO_LABEL } from #${ item . number } due to contributor response.` ,
@@ -188,11 +220,7 @@ module.exports = async ({ github, context, core }) => {
188220 await processItems (
189221 `repo:${ owner } /${ repo } is:open is:pr -label:"help wanted" -label:"🔒 maintainer only" -label:"status/pr-nudge-sent" created:${ prCloseThreshold . toISOString ( ) } ..${ nudgeThreshold . toISOString ( ) } ` ,
190222 async ( pr ) => {
191- if (
192- [ 'OWNER' , 'MEMBER' , 'COLLABORATOR' ] . includes ( pr . author_association ) ||
193- pr . user ?. type === 'Bot'
194- )
195- return ;
223+ if ( await isMaintainer ( pr . user , pr . author_association ) ) return ;
196224
197225 core . info ( `Nudging PR #${ pr . number } for contribution policy.` ) ;
198226 if ( ! dryRun ) {
@@ -216,11 +244,7 @@ module.exports = async ({ github, context, core }) => {
216244 await processItems (
217245 `repo:${ owner } /${ repo } is:open is:pr -label:"help wanted" -label:"🔒 maintainer only" created:<${ prCloseThreshold . toISOString ( ) } ` ,
218246 async ( pr ) => {
219- if (
220- [ 'OWNER' , 'MEMBER' , 'COLLABORATOR' ] . includes ( pr . author_association ) ||
221- pr . user ?. type === 'Bot'
222- )
223- return ;
247+ if ( await isMaintainer ( pr . user , pr . author_association ) ) return ;
224248
225249 core . info (
226250 `Closing PR #${ pr . number } per contribution policy (no 'help wanted').` ,
0 commit comments