92 lines
2.6 KiB
JavaScript
92 lines
2.6 KiB
JavaScript
|
const getUserFromContext = ( types, context ) => {
|
||
|
for ( const type of types ) {
|
||
|
if ( context.payload[ type ] && context.payload[ type ].user && context.payload[ type ].user.login ) {
|
||
|
return context.payload[ type ].user;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
};
|
||
|
|
||
|
const userIsBot = user => user.type && user.type === 'Bot';
|
||
|
|
||
|
const userInOrg = async ( github, username, org ) => {
|
||
|
console.log( 'Checking for user %s in org %s', username, org );
|
||
|
try {
|
||
|
// First attempt to check memberships.
|
||
|
const result = await github.request( 'GET /orgs/{org}/memberships/{username}', {
|
||
|
org,
|
||
|
username,
|
||
|
} );
|
||
|
|
||
|
if ( result && Math.floor( result.status / 100 ) === 2 ) {
|
||
|
console.log( 'User %s found in %s via membership check', username, org );
|
||
|
return true;
|
||
|
}
|
||
|
} catch ( error ) {
|
||
|
// A 404 status means the user is definitively not in the organization.
|
||
|
if ( error.status === 404 ) {
|
||
|
console.log( 'User %s NOT found in %s via membership check', username, org );
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
// For anything else, we should also check public memberships.
|
||
|
const result = await github.request( 'GET /orgs/{org}/public_members/{username}', {
|
||
|
org,
|
||
|
username,
|
||
|
} );
|
||
|
|
||
|
if ( result && Math.floor( result.status / 100 ) === 2 ) {
|
||
|
console.log( 'User %s found in %s via public membership check', username, org );
|
||
|
return true;
|
||
|
}
|
||
|
} catch ( error ) {
|
||
|
if ( error.status === 404 ) {
|
||
|
console.log( 'User %s NOT found in %s via public membership check', username, org );
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// If we've gotten to this point, status is unknown.
|
||
|
throw new Error( "Unable to determine user's membership in org" );
|
||
|
};
|
||
|
|
||
|
const userInNonCommunityOrgs = async ( orgs, github, username ) => {
|
||
|
let checked = 0;
|
||
|
for ( const org of orgs ) {
|
||
|
try {
|
||
|
const isUserInOrg = await userInOrg( github, username, org );
|
||
|
if ( isUserInOrg ) {
|
||
|
return true;
|
||
|
}
|
||
|
// If no error was thrown, increment checked.
|
||
|
checked++;
|
||
|
} catch( e ) {} // Do nothing.
|
||
|
}
|
||
|
|
||
|
if ( checked !== orgs.length ) {
|
||
|
throw new Error( "Unable to check user's membership in all orgs." );
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
};
|
||
|
|
||
|
const isCommunityContributor = async ( { github, context, config } ) => {
|
||
|
const user = getUserFromContext( config.types, context );
|
||
|
if ( ! user ) {
|
||
|
throw new Error( 'Unable to get user from context' );
|
||
|
}
|
||
|
console.log( 'Checking user %s', user.login );
|
||
|
|
||
|
if ( userIsBot( user ) ) {
|
||
|
// Bots are not community contributors.
|
||
|
console.log( 'User detected as bot, skipping' );
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
const isInNonCommunityOrgs = await userInNonCommunityOrgs( config.orgs, github, user.login );
|
||
|
|
||
|
return ! isInNonCommunityOrgs;
|
||
|
};
|
||
|
|
||
|
module.exports = isCommunityContributor;
|