Skip to content

Commit 786fa47

Browse files
authored
Merge pull request #578 from mvlassis/add-all-reviewers-input
feat: Add `copy_all_reviewers` input This PR implements a new `copy_all_reviewers` input. Note that this input would always add a superset of the reviewers added in `copy_requested_reviewers`: - All users that have already submitted a reviews (regardless of whether it is approved or not) - All requested users, meaning people that have not yet submitted a review
2 parents c4bc5bc + 2b7c4f1 commit 786fa47

File tree

6 files changed

+160
-59
lines changed

6 files changed

+160
-59
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,15 @@ Specifically, those reachable from the pull request's head and not reachable fro
234234

235235
By default, the action cherry-picks the commits based on the method used to merge the pull request.
236236

237+
### `copy_all_reviewers`
238+
239+
Default: `false` (disabled)
240+
241+
Controls whether to copy all reviewers from the original pull request to the backport pull request.
242+
Note that this requests reviews from both requested reviewers, and people that have already reviewed the original pull request.
243+
Use `copy_requested_reviewers` instead to only request reviews from requested reviewers.
244+
By default, all reviewers are not copied.
245+
237246
### `copy_assignees`
238247

239248
Default: `false` (disabled)
@@ -262,6 +271,7 @@ Default: `false` (disabled)
262271

263272
Controls whether to copy the requested reviewers from the original pull request to the backport pull request.
264273
Note that this does not request reviews from those users who already reviewed the original pull request.
274+
Use `copy_all_reviewers` instead to also request reviews from those users.
265275
By default, the requested reviewers are not copied.
266276

267277
### `experimental`

action.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ inputs:
5151

5252
By default, the action cherry-picks the commits based on the method used to merge the pull request.
5353
default: auto
54+
copy_all_reviewers:
55+
description: >
56+
Controls whether to copy all reviewers from the original pull request to the backport pull request.
57+
Note that this requests reviews from both requested reviewers, and people that have already reviewed the original pull request.
58+
Use `copy_requested_reviewers` instead to only request reviews from requested reviewers.
59+
By default, all reviewers are not copied.
60+
default: false
5461
copy_assignees:
5562
description: >
5663
Controls whether to copy the assignees from the original pull request to the backport pull request.
@@ -70,6 +77,7 @@ inputs:
7077
description: >
7178
Controls whether to copy the requested reviewers from the original pull request to the backport pull request.
7279
Note that this does not request reviews from those users who already reviewed the original pull request.
80+
Use `copy_all_reviewers` instead to also request reviews from those users.
7381
By default, the requested reviewers are not copied.
7482
default: false
7583
experimental:

dist/index.js

Lines changed: 59 additions & 59 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/backport.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export type Config = {
3434
};
3535
copy_milestone: boolean;
3636
copy_assignees: boolean;
37+
copy_all_reviewers: boolean;
3738
copy_requested_reviewers: boolean;
3839
add_author_as_assignee: boolean;
3940
add_author_as_reviewer: boolean;
@@ -450,6 +451,52 @@ export class Backport {
450451
}
451452
}
452453

454+
if (this.config.copy_all_reviewers == true) {
455+
const requestedReviewers =
456+
mainpr.requested_reviewers?.map((reviewer) => reviewer.login) ??
457+
[];
458+
459+
let submittedReviewers: string[] = [];
460+
try {
461+
const { data: reviews } = await this.github.listReviews(
462+
workflowOwner,
463+
workflowRepo,
464+
mainpr.number,
465+
);
466+
467+
submittedReviewers = [
468+
...new Set(
469+
reviews
470+
.map((review) => review.user?.login)
471+
.filter((login): login is string => Boolean(login)),
472+
),
473+
];
474+
} catch (error) {
475+
if (!(error instanceof RequestError)) throw error;
476+
console.error(JSON.stringify(error.response));
477+
}
478+
479+
const reviewers = [
480+
...new Set([...requestedReviewers, ...submittedReviewers]),
481+
];
482+
483+
if (reviewers.length > 0) {
484+
console.info("Setting reviewers " + reviewers);
485+
const reviewRequest = {
486+
owner,
487+
repo,
488+
pull_number: new_pr.number,
489+
reviewers: reviewers,
490+
};
491+
try {
492+
await this.github.requestReviewers(reviewRequest);
493+
} catch (error) {
494+
if (!(error instanceof RequestError)) throw error;
495+
console.error(JSON.stringify(error.response));
496+
}
497+
}
498+
}
499+
453500
if (this.config.copy_requested_reviewers == true) {
454501
const reviewers =
455502
mainpr.requested_reviewers?.map((reviewer) => reviewer.login) ??

src/github.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ export interface GithubApi {
2424
labels: string[],
2525
repo: Repo,
2626
): Promise<LabelPullRequestResponse>;
27+
listReviews(
28+
owner: string,
29+
repo: string,
30+
pull_number: number,
31+
): Promise<ListReviewsResponse>;
2732
requestReviewers(request: ReviewRequest): Promise<RequestReviewersResponse>;
2833
addAssignees(
2934
pr: number,
@@ -136,6 +141,24 @@ export class Github implements GithubApi {
136141
return this.#octokit.rest.pulls.create(pr);
137142
}
138143

144+
/**
145+
* Retrieves a list of reviews for a specific pull request.
146+
147+
* @param owner - The account owner of the repository.
148+
* @param repo - The name of the repository.
149+
* @param pull_number - The unique identifier of the pull request.
150+
* @returns A promise that resolves to the list of reviews from the GitHub API.
151+
* @throws Will throw an error if the Octokit request fails (e.g., 404 Not Found).
152+
*/
153+
public async listReviews(owner: string, repo: string, pull_number: number) {
154+
console.log(`Retrieving reviews from pull request: ${pull_number}`);
155+
return this.#octokit.rest.pulls.listReviews({
156+
owner,
157+
repo,
158+
pull_number,
159+
});
160+
}
161+
139162
public async requestReviewers(request: ReviewRequest) {
140163
console.log(`Request reviewers: ${request.reviewers}`);
141164
return this.#octokit.rest.pulls.requestReviewers(request);
@@ -455,6 +478,17 @@ export type CreatePullRequestResponse = {
455478
};
456479
export type RequestReviewersResponse = CreatePullRequestResponse;
457480

481+
export type PullRequestReview = {
482+
user: {
483+
login: string;
484+
} | null;
485+
};
486+
487+
export type ListReviewsResponse = {
488+
status: number;
489+
data: PullRequestReview[];
490+
};
491+
458492
export type GenericResponse = {
459493
status: number;
460494
};

src/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ async function run(): Promise<void> {
3030
const merge_commits = core.getInput("merge_commits");
3131
const copy_assignees = core.getInput("copy_assignees");
3232
const copy_milestone = core.getInput("copy_milestone");
33+
const copy_all_reviewers = core.getInput("copy_all_reviewers");
3334
const copy_requested_reviewers = core.getInput("copy_requested_reviewers");
3435
const add_author_as_assignee = core.getInput("add_author_as_assignee");
3536
const add_author_as_reviewer = core.getInput("add_author_as_reviewer");
@@ -112,6 +113,7 @@ async function run(): Promise<void> {
112113
commits: { cherry_picking, merge_commits },
113114
copy_assignees: copy_assignees === "true",
114115
copy_milestone: copy_milestone === "true",
116+
copy_all_reviewers: copy_all_reviewers === "true",
115117
copy_requested_reviewers: copy_requested_reviewers === "true",
116118
add_author_as_assignee: add_author_as_assignee === "true",
117119
add_author_as_reviewer: add_author_as_reviewer === "true",

0 commit comments

Comments
 (0)