mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-11-18 05:33:56 +01:00
This should fix the bug where the "needs: reviewer" label was set too
early, just to be removed immediately, because reviewers were then
requested.
(cherry picked from commit e68b0aef13)
129 lines
3.8 KiB
JavaScript
129 lines
3.8 KiB
JavaScript
async function handleReviewers({
|
|
github,
|
|
context,
|
|
core,
|
|
log,
|
|
dry,
|
|
pull_request,
|
|
reviews,
|
|
maintainers,
|
|
owners,
|
|
getTeamMembers,
|
|
getUser,
|
|
}) {
|
|
const pull_number = pull_request.number
|
|
|
|
const users = new Set([
|
|
...(await Promise.all(
|
|
maintainers.map(async (id) => (await getUser(id)).login),
|
|
)),
|
|
...owners.filter((handle) => handle && !handle.includes('/')),
|
|
])
|
|
log('reviewers - users', Array.from(users).join(', '))
|
|
|
|
const teams = new Set(
|
|
owners
|
|
.map((handle) => handle.split('/'))
|
|
.filter(([org, slug]) => org === context.repo.owner && slug)
|
|
.map(([, slug]) => slug),
|
|
)
|
|
log('reviewers - teams', Array.from(teams).join(', '))
|
|
|
|
const team_members = new Set(
|
|
(await Promise.all(Array.from(teams, getTeamMembers)))
|
|
.flat(1)
|
|
.map(({ login }) => login),
|
|
)
|
|
log('reviewers - team_members', Array.from(team_members).join(', '))
|
|
|
|
const new_reviewers = users
|
|
.union(team_members)
|
|
// We can't request a review from the author.
|
|
.difference(new Set([pull_request.user?.login]))
|
|
log('reviewers - new_reviewers', Array.from(new_reviewers).join(', '))
|
|
|
|
// Filter users to repository collaborators. If they're not, they can't be requested
|
|
// for review. In that case, they probably missed their invite to the maintainers team.
|
|
const reviewers = (
|
|
await Promise.all(
|
|
Array.from(new_reviewers, async (username) => {
|
|
try {
|
|
await github.rest.repos.checkCollaborator({
|
|
...context.repo,
|
|
username,
|
|
})
|
|
return username
|
|
} catch (e) {
|
|
if (e.status !== 404) throw e
|
|
core.warn(
|
|
`PR #${pull_number}: User ${username} cannot be requested for review because they don't exist or are not a repository collaborator, ignoring. They probably missed the automated invite to the maintainers team (see <https://github.com/NixOS/nixpkgs/issues/234293>).`,
|
|
)
|
|
}
|
|
}),
|
|
)
|
|
).filter(Boolean)
|
|
log('reviewers - reviewers', reviewers.join(', '))
|
|
|
|
if (reviewers.length > 15) {
|
|
log(
|
|
`Too many reviewers (${reviewers.join(', ')}), skipping review requests.`,
|
|
)
|
|
// false indicates, that we do have reviewers and don't need the "needs: reviewers" label.
|
|
return false
|
|
}
|
|
|
|
const requested_reviewers = new Set(
|
|
pull_request.requested_reviewers.map(({ login }) => login),
|
|
)
|
|
log(
|
|
'reviewers - requested_reviewers',
|
|
Array.from(requested_reviewers).join(', '),
|
|
)
|
|
|
|
const existing_reviewers = new Set(
|
|
reviews.map(({ user }) => user?.login).filter(Boolean),
|
|
)
|
|
log(
|
|
'reviewers - existing_reviewers',
|
|
Array.from(existing_reviewers).join(', '),
|
|
)
|
|
|
|
const non_requested_reviewers = new Set(reviewers)
|
|
.difference(requested_reviewers)
|
|
// We don't want to rerequest reviews from people who already reviewed.
|
|
.difference(existing_reviewers)
|
|
log(
|
|
'reviewers - non_requested_reviewers',
|
|
Array.from(non_requested_reviewers).join(', '),
|
|
)
|
|
|
|
if (non_requested_reviewers.size === 0) {
|
|
log('Has reviewer changes', 'false (skipped)')
|
|
} else if (dry) {
|
|
core.info(
|
|
`Requesting reviewers for #${pull_number}: ${Array.from(non_requested_reviewers).join(', ')} (dry)`,
|
|
)
|
|
} else {
|
|
// We had tried the "request all reviewers at once" thing in the past, but it didn't work out:
|
|
// https://github.com/NixOS/nixpkgs/commit/034613f860fcd339bd2c20c8f6bc259a2f9dc034
|
|
// If we're hitting API errors here again, we'll need to investigate - and possibly reverse
|
|
// course.
|
|
await github.rest.pulls.requestReviewers({
|
|
...context.repo,
|
|
pull_number,
|
|
reviewers,
|
|
})
|
|
}
|
|
|
|
// Return a boolean on whether the "needs: reviewers" label should be set.
|
|
return (
|
|
new_reviewers.size === 0 &&
|
|
existing_reviewers.size === 0 &&
|
|
requested_reviewers.size === 0
|
|
)
|
|
}
|
|
|
|
module.exports = {
|
|
handleReviewers,
|
|
}
|