status-github-bot/lib/github-helpers.js
2018-02-20 13:08:31 +01:00

80 lines
2.3 KiB
JavaScript

// Description:
// GtHub-related helpers
//
// Dependencies:
// github: "^13.1.0"
//
// Author:
// PombeirP
module.exports.getPullRequestReviewStates = _getPullRequestReviewStates
module.exports.getReviewApprovalState = _getReviewApprovalState
module.exports.getProjectCardForIssue = _getProjectCardForIssue
async function _getPullRequestReviewStates (github, prInfo) {
let finalReviewsMap = new Map()
const ghreviews = await github.paginate(
github.pullRequests.getReviews({ ...prInfo, per_page: 100 }),
res => res.data)
for (var review of ghreviews) {
switch (review.state) {
case 'APPROVED':
case 'CHANGES_REQUESTED':
case 'PENDING':
finalReviewsMap.set(review.user.id, review.state)
break
}
}
return Array.from(finalReviewsMap.values())
}
async function _getReviewApprovalState (github, robot, prInfo) {
// Get detailed pull request
const pullRequestPayload = await github.pullRequests.get(prInfo)
const pullRequest = pullRequestPayload.data
if (pullRequest.mergeable !== null && pullRequest.mergeable !== undefined && !pullRequest.mergeable) {
robot.log.debug(`pullRequest.mergeable is ${pullRequest.mergeable}, considering as failed`)
return 'failed'
}
let state
switch (pullRequest.mergeable_state) {
case 'clean':
state = 'approved'
break
case 'dirty':
state = 'failed'
break
}
robot.log.debug(`pullRequest.mergeable_state is ${pullRequest.mergeable_state}, considering state as ${state}`)
if (state !== 'approved') {
return state
}
const threshold = 2 // Minimum number of approvers
const finalReviews = await _getPullRequestReviewStates(github, prInfo)
robot.log.debug(finalReviews)
const approvedReviews = finalReviews.filter(reviewState => reviewState === 'APPROVED')
if (approvedReviews.length >= threshold) {
const reviewsWithChangesRequested = finalReviews.filter(reviewState => reviewState === 'CHANGES_REQUESTED')
if (reviewsWithChangesRequested.length === 0) {
return 'approved'
}
return 'changes_requested'
}
return 'awaiting_reviewers'
}
async function _getProjectCardForIssue (github, columnId, issueUrl) {
const ghcardsPayload = await github.projects.getProjectCards({column_id: columnId})
const ghcard = ghcardsPayload.data.find(c => c.content_url === issueUrl)
return ghcard
}