From 34ec1894842298124824c52a2e74743562ea35ee Mon Sep 17 00:00:00 2001 From: Gabriel Melo Date: Mon, 21 Aug 2023 19:17:33 -0400 Subject: [PATCH] Add group-by-label feature The idea of this feature is to limit which groups get selected for review on a given PR. It adds a match tag to groups with the effect that if the PR has labels, only groups whose matcher is present in one of these labels get selected for reviews. The use case for this is multiplatform or multiteam monorepos to not get all the groups in an organization reviewing every single PR. --- src/config.ts | 1 + src/lottery.ts | 36 ++++++++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/config.ts b/src/config.ts index f884c866..f7e74fd9 100644 --- a/src/config.ts +++ b/src/config.ts @@ -4,6 +4,7 @@ import fs from 'fs' interface Group { name: string + matchLabel?: string reviewers?: number internal_reviewers?: number usernames: string[] diff --git a/src/lottery.ts b/src/lottery.ts index 18898def..5a755420 100644 --- a/src/lottery.ts +++ b/src/lottery.ts @@ -6,6 +6,7 @@ export interface Pull { user: {login: string} | null number: number draft?: boolean + labels: {name: string}[] | null } interface Env { repository: string @@ -79,17 +80,22 @@ class Lottery { for (const { reviewers, internal_reviewers: internalReviewers, - usernames + usernames, + matchLabel } of this.config.groups) { - const reviewersToRequest = - usernames.includes(author) && internalReviewers - ? internalReviewers - : reviewers - - if (reviewersToRequest) { - selected = selected.concat( - this.pickRandom(usernames, reviewersToRequest, selected.concat(author)) - ) + const labels = this.getPRLabels() + const shouldRunForGroup = matchLabel === undefined || labels.length === 0 || labels.includes(matchLabel) + if (shouldRunForGroup) { + const reviewersToRequest = + usernames.includes(author) && internalReviewers + ? internalReviewers + : reviewers + + if (reviewersToRequest) { + selected = selected.concat( + this.pickRandom(usernames, reviewersToRequest, selected.concat(author)) + ) + } } } } catch (error: any) { @@ -138,6 +144,16 @@ class Lottery { return Number(this.pr?.number) } + getPRLabels(): string[] { + const labels = this.pr?.labels?.map((label) => label.name) + + if (labels) { + return labels + } else { + return [] + } + } + async getPR(): Promise { if (this.pr) return this.pr