From 519d0dfed9abeb0689d5c58bb21bd08cb74f8d4d Mon Sep 17 00:00:00 2001 From: Pedro Pombeiro Date: Thu, 22 Feb 2018 16:37:53 +0100 Subject: [PATCH] Extract additional reusable GitHub-related methods into `github-helpers.js` --- bot_scripts/assign-approved-pr-to-test.js | 24 +------ bot_scripts/assign-new-pr-to-review.js | 39 ++-------- .../assign-to-bounty-awaiting-for-approval.js | 72 +++++-------------- lib/github-helpers.js | 68 ++++++++++++++++++ 4 files changed, 96 insertions(+), 107 deletions(-) diff --git a/bot_scripts/assign-approved-pr-to-test.js b/bot_scripts/assign-approved-pr-to-test.js index b7d006d..359f0e1 100644 --- a/bot_scripts/assign-approved-pr-to-test.js +++ b/bot_scripts/assign-approved-pr-to-test.js @@ -24,12 +24,6 @@ module.exports = robot => { robot.on('schedule.repository', context => checkOpenPullRequests(robot, context)) } -async function getProjectFromName (github, repoInfo, projectBoardName) { - const ghprojectsPayload = await github.projects.getRepoProjects({ ...repoInfo, state: 'open' }) - - return ghprojectsPayload.data.find(p => p.name === projectBoardName) -} - async function checkOpenPullRequests (robot, context) { const { github, payload } = context const repo = payload.repository @@ -46,21 +40,9 @@ async function checkOpenPullRequests (robot, context) { const reviewColumnName = projectBoardConfig['review-column-name'] const testColumnName = projectBoardConfig['test-column-name'] - // Fetch repo projects - // TODO: The repo project and project column info should be cached - // in order to improve performance and reduce roundtrips - let project - try { - // Find 'Pipeline for QA' project - project = await getProjectFromName(github, repoInfo, projectBoardConfig.name) - if (!project) { - robot.log.error(`${botName} - Couldn't find project ${projectBoardConfig.name} in repo ${repoInfo.owner}/${repoInfo.repo}`) - return - } - - robot.log.debug(`${botName} - Fetched ${project.name} project (${project.id})`) - } catch (err) { - robot.log.error(`${botName} - Couldn't fetch the github projects for repo: ${err}`, repoInfo) + // Find 'Pipeline for QA' project + const project = await gitHubHelpers.getRepoProjectByName(github, robot, repoInfo, projectBoardConfig.name, botName) + if (!project) { return } diff --git a/bot_scripts/assign-new-pr-to-review.js b/bot_scripts/assign-new-pr-to-review.js index cefb8ae..1f89696 100644 --- a/bot_scripts/assign-new-pr-to-review.js +++ b/bot_scripts/assign-new-pr-to-review.js @@ -11,6 +11,7 @@ const defaultConfig = require('../lib/config') const slackHelper = require('../lib/slack') +const gitHubHelpers = require('../lib/github-helpers') const getConfig = require('probot-config') @@ -39,41 +40,13 @@ async function assignPullRequestToReview (context, robot) { robot.log(`${botName} - Handling Pull Request #${prNumber} on repo ${repoInfo.owner}/${repoInfo.repo}`) - // Fetch repo projects - // TODO: The repo project and project column info should be cached - // in order to improve performance and reduce roundtrips - let column = null const projectBoardName = projectBoardConfig.name const reviewColumnName = projectBoardConfig['review-column-name'] - try { - const ghprojectsPayload = await github.projects.getRepoProjects({ ...repoInfo, state: 'open' }) - - // Find 'Pipeline for QA' project - const project = ghprojectsPayload.data.find(p => p.name === projectBoardName) - if (!project) { - robot.log.error(`${botName} - Couldn't find project ${projectBoardName} in repo ${repoInfo.owner}/${repoInfo.repo}`) - return - } - - robot.log.debug(`${botName} - Fetched ${project.name} project (${project.id})`) - - // Fetch REVIEW column ID - try { - const ghcolumnsPayload = await github.projects.getProjectColumns({ project_id: project.id }) - - column = ghcolumnsPayload.data.find(c => c.name === reviewColumnName) - if (!column) { - robot.log.error(`${botName} - Couldn't find ${reviewColumnName} column in project ${project.name}`) - return - } - - robot.log.debug(`${botName} - Fetched ${column.name} column (${column.id})`) - } catch (err) { - robot.log.error(`${botName} - Couldn't fetch the github columns for project: ${err}`, repoInfo, project.id) - return - } - } catch (err) { - robot.log.error(`${botName} - Couldn't fetch the github projects for repo: ${err}`, repoInfo) + // Find 'Pipeline for QA' project + const project = await gitHubHelpers.getRepoProjectByName(github, robot, repoInfo, projectBoardName, botName) + // Fetch REVIEW column ID + const column = await gitHubHelpers.getProjectColumnByName(github, robot, project, reviewColumnName, botName) + if (!column) { return } diff --git a/bot_scripts/assign-to-bounty-awaiting-for-approval.js b/bot_scripts/assign-to-bounty-awaiting-for-approval.js index 374f79f..2838735 100644 --- a/bot_scripts/assign-to-bounty-awaiting-for-approval.js +++ b/bot_scripts/assign-to-bounty-awaiting-for-approval.js @@ -56,46 +56,11 @@ async function assignIssueToBountyAwaitingForApproval (context, robot, assign) { robot.log(`${botName} - Handling unlabeling of #${payload.issue.number} with ${payload.label.name} on repo ${repoInfo.owner}/${repoInfo.repo}`) } - // Fetch org projects - // TODO: The org project and project column info should be cached - // in order to improve performance and reduce roundtrips - let column = null - const projectBoardName = projectBoardConfig.name + // Fetch bounty-awaiting-approval column in project board const approvalColumnName = projectBoardConfig['awaiting-approval-column-name'] - try { - const orgName = repoInfo.owner - - const ghprojectsPayload = await github.projects.getOrgProjects({ - org: orgName, - state: 'open' - }) - - // Find 'Status SOB Swarm' project - const project = ghprojectsPayload.data.find(p => p.name === projectBoardName) - if (!project) { - robot.log.error(`${botName} - Couldn't find project ${projectBoardName} in ${orgName} org`) - return - } - - robot.log.debug(`${botName} - Fetched ${project.name} project (${project.id})`) - - // Fetch bounty-awaiting-approval column ID - try { - const ghcolumnsPayload = await github.projects.getProjectColumns({ project_id: project.id }) - - column = ghcolumnsPayload.data.find(c => c.name === approvalColumnName) - if (!column) { - robot.log.error(`${botName} - Couldn't find ${approvalColumnName} column in project ${project.name}`) - return - } - - robot.log.debug(`${botName} - Fetched ${column.name} column (${column.id})`) - } catch (err) { - robot.log.error(`${botName} - Couldn't fetch the github columns for project: ${err}`, repoInfo, project.id) - return - } - } catch (err) { - robot.log.error(`${botName} - Couldn't fetch the github projects for repo: ${err}`, repoInfo) + const project = await gitHubHelpers.getOrgProjectByName(github, robot, repoInfo.owner, projectBoardConfig.name, botName) + const column = await gitHubHelpers.getProjectColumnByName(github, robot, project, approvalColumnName, botName) + if (!column) { return } @@ -136,20 +101,21 @@ async function assignIssueToBountyAwaitingForApproval (context, robot, assign) { } } - let message - // Send message to Slack - if (assign) { - message = `Assigned issue to ${approvalColumnName} in ${projectBoardName} project\n${payload.issue.html_url}` - } else { - if (isOfficialBounty) { - message = `${payload.issue.html_url} has been approved as an official bounty!` - } else { - message = `Unassigned issue from ${approvalColumnName} in ${projectBoardName} project\n${payload.issue.html_url}` - } - } - - if (message && !process.env.DRY_RUN_BOUNTY_APPROVAL) { + const slackMessage = getSlackMessage(projectBoardConfig.name, approvalColumnName, payload, assign, isOfficialBounty) + if (slackMessage && !process.env.DRY_RUN_BOUNTY_APPROVAL) { // Send message to Slack - slackHelper.sendMessage(robot, config.slack.notification.room, message) + slackHelper.sendMessage(robot, config.slack.notification.room, slackMessage) + } +} + +function getSlackMessage (projectBoardName, approvalColumnName, payload, assign, isOfficialBounty) { + if (assign) { + return `Assigned issue to ${approvalColumnName} in ${projectBoardName} project\n${payload.issue.html_url}` + } else { + if (isOfficialBounty) { + return `${payload.issue.html_url} has been approved as an official bounty!` + } else { + return `Unassigned issue from ${approvalColumnName} in ${projectBoardName} project\n${payload.issue.html_url}` + } } } diff --git a/lib/github-helpers.js b/lib/github-helpers.js index 5de97b4..895947c 100644 --- a/lib/github-helpers.js +++ b/lib/github-helpers.js @@ -10,6 +10,9 @@ module.exports.getPullRequestReviewStates = _getPullRequestReviewStates module.exports.getReviewApprovalState = _getReviewApprovalState module.exports.getProjectCardForIssue = _getProjectCardForIssue +module.exports.getOrgProjectByName = _getOrgProjectByName +module.exports.getRepoProjectByName = _getRepoProjectByName +module.exports.getProjectColumnByName = _getProjectColumnByName async function _getPullRequestReviewStates (github, prInfo) { let finalReviewsMap = new Map() @@ -77,3 +80,68 @@ async function _getProjectCardForIssue (github, columnId, issueUrl) { return ghcard } + +async function _getOrgProjectByName (github, robot, orgName, projectName, botName) { + try { + // Fetch org projects + // TODO: The org project and project column info should be cached + // in order to improve performance and reduce roundtrips + const ghprojectsPayload = await github.projects.getOrgProjects({ + org: orgName, + state: 'open' + }) + + const project = ghprojectsPayload.data.find(p => p.name === projectName) + if (!project) { + robot.log.error(`${botName} - Couldn't find project ${projectName} in ${orgName} org`) + return null + } + + robot.log.debug(`${botName} - Fetched ${project.name} project (${project.id})`) + + return project + } catch (err) { + robot.log.error(`${botName} - Couldn't fetch the github projects for org`, orgName, err) + return null + } +} + +async function _getRepoProjectByName (github, robot, repoInfo, projectName, botName) { + try { + const ghprojectsPayload = await github.projects.getRepoProjects({ ...repoInfo, state: 'open' }) + const project = ghprojectsPayload.data.find(p => p.name === projectName) + if (!project) { + robot.log.error(`${botName} - Couldn't find project ${projectName} in repo ${repoInfo.owner}/${repoInfo.repo}`) + return null + } + + robot.log.debug(`${botName} - Fetched ${project.name} project (${project.id})`) + + return project + } catch (err) { + robot.log.error(`${botName} - Couldn't fetch the github projects for repo: ${err}`, repoInfo) + return null + } +} + +async function _getProjectColumnByName (github, robot, project, columnName, botName) { + if (!project) { + return null + } + + try { + const ghcolumnsPayload = await github.projects.getProjectColumns({ project_id: project.id }) + const column = ghcolumnsPayload.data.find(c => c.name === columnName) + if (!column) { + robot.log.error(`${botName} - Couldn't find ${columnName} column in project ${project.name}`) + return null + } + + robot.log.debug(`${botName} - Fetched ${column.name} column (${column.id})`) + + return column + } catch (err) { + robot.log.error(`${botName} - Couldn't fetch the github columns for project: ${err}`, project.id) + return null + } +}