import { Probot , Context } from 'probot' ; import { logger } from 'gcf-utils' ; import { ConfigChecker , getConfigWithDefault , } from '@google-automations/bot-config-utils' ; import { ConfigurationOptions , CONFIGURATION_FILE_PATH , DEFAULT_CONFIGURATION , } from './configuration' ; import schema from './config-schema.json' ; const DO_NOT_MERGE = 'do not merge' ; const DO_NOT_MERGE_2 = 'do-not-merge' ; const CHECK_NAME = 'Do Not Merge' ; const FAILURE_OUTPUT = { title : 'Remove the do not merge label before merging' , summary : 'Remove the do not merge label before merging' , } ; const SUCCESS_OUTPUT = { title : 'OK to merge, label not found' , summary : 'OK to merge, label not found' , } ; export = ( app ) => { app . on ( [ 'pull_request.labeled' , 'pull_request.unlabeled' , 'pull_request.synchronize' , ] , async ( context ) => { if ( context . payload . pull_request . state === 'closed' ) { logger . info ( `The pull request ${ context . payload . pull_request . url } is closed, exiting.` ) ; return ; } const owner = context . payload . repository . owner . login ; const repo = context . payload . repository . name ; const sha = context . payload . pull_request . head . sha ; const labelFound = context . payload . pull_request . labels . find ( l => l . name === DO_NOT_MERGE || l . name === DO_NOT_MERGE_2 ) ; let config = DEFAULT_CONFIGURATION ; try { config = await getConfigWithDefault < ConfigurationOptions > ( context . octokit , owner , repo , CONFIGURATION_FILE_PATH , DEFAULT_CONFIGURATION ) ; } catch ( err ) { logger . error ( err as Error ) ; } const existingCheck = await findCheck ( context , owner , repo , sha ) ; if ( ! labelFound ) { logger . info ( `Do not merge label not found on ${ context . payload . pull_request . url }` ) ; if ( existingCheck && existingCheck . conclusion !== 'success' ) { logger . info ( `Updating check on ${ context . payload . pull_request . url } to success` ) ; await context . octokit . checks . update ( { conclusion : 'success' , check_run_id : existingCheck . id , owner , repo , output : SUCCESS_OUTPUT , } ) ; } else if ( config . alwaysCreateStatusCheck ) { await context . octokit . checks . create ( { conclusion : 'success' , name : CHECK_NAME , owner , repo , head_sha : sha , output : SUCCESS_OUTPUT , } ) ; } return ; } if ( existingCheck ) { if ( existingCheck . conclusion !== 'failure' ) { logger . info ( `Updating check on ${ context . payload . pull_request . url } to failure` ) ; await context . octokit . checks . update ( { conclusion : 'failure' , check_run_id : existingCheck . id , owner , repo , output : FAILURE_OUTPUT , } ) ; } else { logger . info ( `Check on ${ context . payload . pull_request . url } is already failure` ) ; } return ; } logger . info ( `Creating failed check on ${ context . payload . pull_request . url }` ) ; await context . octokit . checks . create ( { conclusion : 'failure' , name : CHECK_NAME , owner , repo , head_sha : sha , output : FAILURE_OUTPUT , } ) ; logger . metric ( 'do_not_merge.add_label' ) ; } ) ; app . on ( [ 'pull_request.opened' , 'pull_request.reopened' , 'pull_request.edited' , 'pull_request.synchronize' , ] , async ( context ) => { if ( context . payload . pull_request . state === 'closed' ) { logger . info ( `The pull request ${ context . payload . pull_request . url } is closed, exiting.` ) ; return ; } if ( context . payload . pull_request . head . repo === undefined || context . payload . pull_request . head . repo === null ) { logger . info ( `The head repo is undefined for ${ context . payload . pull_request . url }, exiting.` ) ; return ; } const { owner , repo } = context . repo ( ) ; const configChecker = new ConfigChecker < ConfigurationOptions > ( schema , CONFIGURATION_FILE_PATH ) ; await configChecker . validateConfigChanges ( context . octokit , owner , repo , context . payload . pull_request . head . sha , context . payload . pull_request . number ) ; } ) ; } ; async function findCheck ( context , owner , repo , sha ) { const checks = ( await context . octokit . checks . listForRef ( { owner , repo , check_name : CHECK_NAME , filter : 'latest' , ref : sha , } ) ) . data ; return checks . check_runs ?. length ? checks . check_runs [ 0 ] : undefined ; }