Automation: Draft PRs now get #g-ceo label if appropriate (#13325)

Closes #13324

Previously, `expectedReviewers` were not built for draft PRs, (they were
left empty) which meant the code for determining whether a PR should get
the #g-ceo label didn't work for PRs that began their life as draft PRs.
This commit is contained in:
Mike McNeil
2023-08-14 23:00:47 -05:00
committed by GitHub
parent aec640271d
commit d92e5df64c
+52 -54
View File
@@ -319,60 +319,59 @@ module.exports = {
// > History: https://github.com/fleetdm/fleet/pull/12786)
let expectedReviewers = [];//« GitHub usernames of people who we expect reviews from.
// Look up already-requested reviewers
// (for use later in minimizing extra notifications for editing PRs to contain new changes
// while also still doing appropriate review requests. Also for determining whether
// to apply the #g-ceo label)
//
// The "requested_reviewers" key in the pull request object:
// - https://developer.github.com/v3/activity/events/types
// - https://docs.github.com/en/webhooks-and-events/webhooks/webhook-events-and-payloads?actionType=edited#pull_request
// - https://docs.github.com/en/rest/pulls/pulls?apiVersion=2022-11-28#get-a-pull-request
let alreadyRequestedReviewers = _.isArray(issueOrPr.requested_reviewers) ? _.pluck(issueOrPr.requested_reviewers, 'login') : [];
alreadyRequestedReviewers = alreadyRequestedReviewers.map((username) => username.toLowerCase());// « make sure they are all lowercased
// Look up paths
// [?] https://docs.github.com/en/rest/reference/pulls#list-pull-requests-files
let changedPaths = _.pluck(await sails.helpers.http.get(`https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/files`, {
per_page: 100,//eslint-disable-line camelcase
}, baseHeaders).retry(), 'filename');// (don't worry, it's the whole path, not the filename)
// For each changed file, decide what reviewer to request, if any…
for (let changedPath of changedPaths) {
changedPath = changedPath.replace(/\/+$/,'');// « trim trailing slashes, just in case (b/c otherwise could loop forever)
sails.log.verbose(`…checking DRI of changed path "${changedPath}"`);
let reviewer = undefined;//« whether to request review for this change
let exactMatchDri = DRI_BY_PATH[changedPath];
if (exactMatchDri) {// « If we've found our DRI, then we'll stop looking (for *this* changed path, anyway)
reviewer = exactMatchDri;
} else {// If there's no DRI for this *exact* file path, then check ancestral paths for the nearest DRI
let numRemainingPathsToCheck = changedPath.split('/').length - 1;
while (numRemainingPathsToCheck > 0) {
let ancestralPath = changedPath.split('/').slice(0, numRemainingPathsToCheck).join('/');
sails.log.verbose(`…checking DRI of ancestral path "${ancestralPath}" for changed path "${changedPath}"`);
let nearestAncestralDri = DRI_BY_PATH[ancestralPath];// this is like the "catch-all" DRI, for a higher-level path
if (nearestAncestralDri) {// Otherwise, if we have our DRI, we can stop here.
reviewer = nearestAncestralDri;
break;
}//fi
numRemainingPathsToCheck--;
}//∞
}
if (reviewer) {
expectedReviewers.push(reviewer);
expectedReviewers = _.uniq(expectedReviewers);// « avoid attempting to request review from the same person twice
}//fi
}//∞
// Now, if reviews should be requested for this PR, do so.
//
// > Note: Should we automatically remove reviewers? Nah, we excluded this on purpose, to avoid removing deliberate
// > custom review requests sent by real humans humans.
if (!issueOrPr.draft) {// « (Draft PRs are skipped)
// Look up already-requested reviewers
// (for use later in minimizing extra notifications for editing PRs to contain new changes
// while also still doing appropriate review requests. Also for determining whether
// to apply the #g-ceo label)
//
// The "requested_reviewers" key in the pull request object:
// - https://developer.github.com/v3/activity/events/types
// - https://docs.github.com/en/webhooks-and-events/webhooks/webhook-events-and-payloads?actionType=edited#pull_request
// - https://docs.github.com/en/rest/pulls/pulls?apiVersion=2022-11-28#get-a-pull-request
let alreadyRequestedReviewers = _.isArray(issueOrPr.requested_reviewers) ? _.pluck(issueOrPr.requested_reviewers, 'login') : [];
alreadyRequestedReviewers = alreadyRequestedReviewers.map((username) => username.toLowerCase());// « make sure they are all lowercased
// Look up paths
// [?] https://docs.github.com/en/rest/reference/pulls#list-pull-requests-files
let changedPaths = _.pluck(await sails.helpers.http.get(`https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/files`, {
per_page: 100,//eslint-disable-line camelcase
}, baseHeaders).retry(), 'filename');// (don't worry, it's the whole path, not the filename)
// For each changed file, decide what reviewer to request, if any…
for (let changedPath of changedPaths) {
changedPath = changedPath.replace(/\/+$/,'');// « trim trailing slashes, just in case (b/c otherwise could loop forever)
sails.log.verbose(`…checking DRI of changed path "${changedPath}"`);
let reviewer = undefined;//« whether to request review for this change
let exactMatchDri = DRI_BY_PATH[changedPath];
if (exactMatchDri) {// « If we've found our DRI, then we'll stop looking (for *this* changed path, anyway)
reviewer = exactMatchDri;
} else {// If there's no DRI for this *exact* file path, then check ancestral paths for the nearest DRI
let numRemainingPathsToCheck = changedPath.split('/').length - 1;
while (numRemainingPathsToCheck > 0) {
let ancestralPath = changedPath.split('/').slice(0, numRemainingPathsToCheck).join('/');
sails.log.verbose(`…checking DRI of ancestral path "${ancestralPath}" for changed path "${changedPath}"`);
let nearestAncestralDri = DRI_BY_PATH[ancestralPath];// this is like the "catch-all" DRI, for a higher-level path
if (nearestAncestralDri) {// Otherwise, if we have our DRI, we can stop here.
reviewer = nearestAncestralDri;
break;
}//fi
numRemainingPathsToCheck--;
}//∞
}
if (reviewer) {
expectedReviewers.push(reviewer);
expectedReviewers = _.uniq(expectedReviewers);// « avoid attempting to request review from the same person twice
}//fi
}//∞
// Now, if reviews should be requested for this PR, do so.
//
// > Note: Should we automatically remove reviewers? Nah, we excluded this on purpose, to avoid removing deliberate
// > custom review requests sent by real humans humans.
let newReviewers;
newReviewers = _.difference(expectedReviewers, alreadyRequestedReviewers);// « Don't request review from people whose review has already been requested.
newReviewers = _.difference(newReviewers, [// « If the original PR author OR you, the sender (current PR author/editor) are the DRI, then don't request review. No need to request review from yourself, and you CAN'T request review from the author (or the GitHub API will respond with an error.)
@@ -385,7 +384,6 @@ module.exports = {
reviewers: newReviewers,
}, baseHeaders);
}//fi
}//fi
// ┌┬┐┌─┐┌┐┌┌─┐┌─┐┌─┐ ┬ ┌─┐┌┐ ┌─┐┬ ┌─┐