2018-01-22 13:48:57 +00:00
// Description:
// Script that listens to new labels on GitHub issues
2018-01-28 08:24:30 +00:00
// and assigns the issues to the bounty-awaiting-approval column on the 'Status SOB Swarm' project
2018-01-22 13:48:57 +00:00
//
// Dependencies:
// github: "^13.1.0"
2018-01-23 18:38:25 +00:00
// probot-config: "^0.1.0"
2018-01-22 13:48:57 +00:00
// probot-slack-status: "^0.2.2"
//
// Author:
// PombeirP
2018-01-28 08:24:30 +00:00
// const getConfig = require('probot-config')
2018-01-30 14:57:16 +00:00
const slackHelper = require ( '../lib/slack' )
2018-01-23 14:27:25 +00:00
const defaultConfig = require ( '../lib/config' )
const Slack = require ( 'probot-slack-status' )
2018-01-22 13:48:57 +00:00
2018-01-23 14:27:25 +00:00
let slackClient = null
2018-01-22 13:48:57 +00:00
2018-01-28 08:24:30 +00:00
module . exports = ( robot ) => {
2018-01-22 13:48:57 +00:00
// robot.on('slack.connected', ({ slack }) => {
Slack ( robot , ( slack ) => {
2018-01-28 08:24:30 +00:00
robot . log . trace ( 'Connected, assigned slackClient' )
2018-01-23 14:27:25 +00:00
slackClient = slack
} )
2018-01-28 08:24:30 +00:00
2018-01-22 13:48:57 +00:00
robot . on ( 'issues.labeled' , async context => {
// Make sure we don't listen to our own messages
2018-01-23 14:27:25 +00:00
if ( context . isBot ) { return }
2018-01-28 08:24:30 +00:00
2018-01-22 13:48:57 +00:00
// A new issue was labeled
2018-01-24 13:38:40 +00:00
await assignIssueToBountyAwaitingForApproval ( context , robot , true )
} )
robot . on ( 'issues.unlabeled' , async context => {
// Make sure we don't listen to our own messages
if ( context . isBot ) { return }
2018-01-28 08:24:30 +00:00
2018-01-24 13:38:40 +00:00
// An issue was unlabeled
await assignIssueToBountyAwaitingForApproval ( context , robot , false )
2018-01-23 14:27:25 +00:00
} )
}
2018-01-22 13:48:57 +00:00
2018-01-28 08:24:30 +00:00
async function assignIssueToBountyAwaitingForApproval ( context , robot , assign ) {
2018-01-23 14:27:25 +00:00
const github = context . github
const payload = context . payload
const ownerName = payload . repository . owner . login
const repoName = payload . repository . name
2018-01-28 08:24:30 +00:00
// const config = await getConfig(context, 'github-bot.yml', defaultConfig(robot, '.github/github-bot.yml'))
2018-01-24 13:38:40 +00:00
const config = defaultConfig ( robot , '.github/github-bot.yml' )
2018-01-28 08:24:30 +00:00
2018-01-23 14:30:24 +00:00
if ( ! config [ 'bounty-project-board' ] ) {
2018-01-28 08:24:30 +00:00
return
2018-01-23 14:30:24 +00:00
}
2018-01-28 08:24:30 +00:00
2018-01-24 13:38:40 +00:00
const watchedLabelName = config [ 'bounty-project-board' ] [ 'label-name' ]
if ( payload . label . name !== watchedLabelName ) {
robot . log . debug ( ` assignIssueToBountyAwaitingForApproval - ${ payload . label . name } doesn't match watched ${ watchedLabelName } label. Ignoring ` )
return
}
2018-01-28 08:24:30 +00:00
2018-01-24 13:38:40 +00:00
if ( assign ) {
2018-01-25 19:42:01 +00:00
robot . log ( ` assignIssueToBountyAwaitingForApproval - Handling labeling of # ${ payload . issue . number } with ${ payload . label . name } on repo ${ ownerName } / ${ repoName } ` )
2018-01-24 13:38:40 +00:00
} else {
2018-01-25 19:42:01 +00:00
robot . log ( ` assignIssueToBountyAwaitingForApproval - Handling unlabeling of # ${ payload . issue . number } with ${ payload . label . name } on repo ${ ownerName } / ${ repoName } ` )
2018-01-24 13:38:40 +00:00
}
2018-01-28 08:24:30 +00:00
2018-01-22 13:48:57 +00:00
// Fetch org projects
// TODO: The org project and project column info should be cached
// in order to improve performance and reduce roundtrips
2018-01-28 08:24:30 +00:00
let column = null
const projectBoardName = config [ 'bounty-project-board' ] . name
const approvalColumnName = config [ 'bounty-project-board' ] [ 'awaiting-approval-column-name' ]
2018-01-22 13:48:57 +00:00
try {
2018-01-24 13:38:40 +00:00
const orgName = ownerName
2018-01-28 08:24:30 +00:00
2018-02-05 16:12:16 +00:00
const ghprojectsPayload = await github . projects . getOrgProjects ( {
2018-01-22 13:48:57 +00:00
org : orgName ,
2018-01-28 08:24:30 +00:00
state : 'open'
2018-01-23 14:27:25 +00:00
} )
2018-01-28 08:24:30 +00:00
// Find 'Status SOB Swarm' project
2018-02-05 16:12:16 +00:00
const project = ghprojectsPayload . data . find ( p => p . name === projectBoardName )
2018-01-22 13:48:57 +00:00
if ( ! project ) {
2018-01-23 14:27:25 +00:00
robot . log . error ( ` Couldn't find project ${ projectBoardName } in ${ orgName } org ` )
return
2018-01-22 13:48:57 +00:00
}
2018-01-28 08:24:30 +00:00
2018-01-23 14:27:25 +00:00
robot . log . debug ( ` Fetched ${ project . name } project ( ${ project . id } ) ` )
2018-01-28 08:24:30 +00:00
2018-01-22 13:48:57 +00:00
// Fetch bounty-awaiting-approval column ID
try {
2018-02-05 16:12:16 +00:00
const ghcolumnsPayload = await github . projects . getProjectColumns ( { project _id : project . id } )
2018-01-28 08:24:30 +00:00
2018-02-05 16:12:16 +00:00
column = ghcolumnsPayload . data . find ( c => c . name === approvalColumnName )
2018-01-22 13:48:57 +00:00
if ( ! column ) {
2018-01-23 14:27:25 +00:00
robot . log . error ( ` Couldn't find ${ approvalColumnName } column in project ${ project . name } ` )
return
2018-01-22 13:48:57 +00:00
}
2018-01-28 08:24:30 +00:00
2018-01-23 14:27:25 +00:00
robot . log . debug ( ` Fetched ${ column . name } column ( ${ column . id } ) ` )
2018-01-22 13:48:57 +00:00
} catch ( err ) {
2018-01-23 14:27:25 +00:00
robot . log . error ( ` Couldn't fetch the github columns for project: ${ err } ` , ownerName , repoName , project . id )
2018-01-23 18:38:25 +00:00
return
2018-01-22 13:48:57 +00:00
}
} catch ( err ) {
2018-01-23 14:27:25 +00:00
robot . log . error ( ` Couldn't fetch the github projects for repo: ${ err } ` , ownerName , repoName )
2018-01-23 18:38:25 +00:00
return
}
2018-01-28 08:24:30 +00:00
2018-02-05 16:12:16 +00:00
let ghcardPayload = null
2018-01-28 08:24:30 +00:00
if ( process . env . DRY _RUN ) {
if ( assign ) {
robot . log . info ( ` Would have created card for issue ` , column . id , payload . issue . id )
} else {
robot . log . info ( ` Would have deleted card for issue ` , column . id , payload . issue . id )
}
} else {
2018-01-24 13:38:40 +00:00
if ( assign ) {
try {
// Create project card for the issue in the bounty-awaiting-approval column
2018-02-05 16:12:16 +00:00
ghcardPayload = await github . projects . createProjectCard ( {
2018-01-24 13:38:40 +00:00
column _id : column . id ,
content _type : 'Issue' ,
content _id : payload . issue . id
} )
2018-02-05 16:12:16 +00:00
const ghcard = ghcardPayload . data
2018-01-28 08:24:30 +00:00
robot . log ( ` Created card: ${ ghcard . url } ` , ghcard . id )
2018-01-24 13:38:40 +00:00
} catch ( err ) {
robot . log . error ( ` Couldn't create project card for the issue: ${ err } ` , column . id , payload . issue . id )
}
} else {
try {
2018-02-05 16:12:16 +00:00
const ghcard = await getProjectCardForIssue ( github , column . id , payload . issue . url )
2018-01-30 14:05:09 +00:00
if ( ghcard ) {
await github . projects . deleteProjectCard ( { id : ghcard . id } )
robot . log ( ` Deleted card: ${ ghcard . url } ` , ghcard . id )
}
2018-01-24 13:38:40 +00:00
} catch ( err ) {
robot . log . error ( ` Couldn't delete project card for the issue: ${ err } ` , column . id , payload . issue . id )
}
2018-01-23 18:38:25 +00:00
}
2018-01-24 13:38:40 +00:00
}
2018-01-30 14:05:09 +00:00
if ( ! process . env . DRY _RUN _BOUNTY _APPROVAL ) {
// Send message to Slack
if ( assign ) {
slackHelper . sendMessage ( robot , slackClient , config . slack . notification . room , ` Assigned issue to ${ approvalColumnName } in ${ projectBoardName } project \n ${ payload . issue . html _url } ` )
} else {
slackHelper . sendMessage ( robot , slackClient , config . slack . notification . room , ` Unassigned issue from ${ approvalColumnName } in ${ projectBoardName } project \n ${ payload . issue . html _url } ` )
}
2018-01-22 13:48:57 +00:00
}
2018-01-23 14:27:25 +00:00
}
2018-01-24 13:38:40 +00:00
2018-01-28 08:24:30 +00:00
async function getProjectCardForIssue ( github , columnId , issueUrl ) {
2018-02-05 16:12:16 +00:00
const ghcardsPayload = await github . projects . getProjectCards ( { column _id : columnId } )
const ghcard = ghcardsPayload . data . find ( c => c . content _url === issueUrl )
2018-01-28 08:24:30 +00:00
2018-01-24 13:38:40 +00:00
return ghcard
}