mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-11-09 16:18:34 +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.
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,
|
|
}
|