Skip to content

Commit

Permalink
add option for adding the reviewers of the original PRs (#452)
Browse files Browse the repository at this point in the history
* add option for adding the reviewers of the original PRs

* Fixup PR

* Fix spinner

* Add test

* Fix test

---------

Co-authored-by: Søren Louv-Jansen <sorenlouv@gmail.com>
  • Loading branch information
reey and sorenlouv committed Aug 27, 2023
1 parent b570116 commit 7d869aa
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
},
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": true
"source.fixAll.eslint": true
},
"typescript.tsdk": "node_modules/typescript/lib"
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
getPullRequestBody,
PullRequestPayload,
} from '../github/v3/createPullRequest';
import { syncSourcePullRequestReviewersToTargetPullRequest } from '../github/v3/syncSourcePullRequestReviewersToTargetPullRequest';
import { validateTargetBranch } from '../github/v4/validateTargetBranch';
import { consoleLog } from '../logger';
import { sequentially } from '../sequentially';
Expand Down Expand Up @@ -97,6 +98,15 @@ export async function cherrypickAndCreateTargetPullRequest({
);
}

// add reviewers of the original PRs to the target pull request
if (options.addOriginalReviewers) {
await syncSourcePullRequestReviewersToTargetPullRequest(
options,
commits,
targetPullRequest.number,
);
}

// add labels to target pull request
if (options.targetPRLabels.length > 0) {
const labels = getTargetPRLabels({
Expand Down
61 changes: 61 additions & 0 deletions src/lib/github/v3/getReviewersFromPullRequests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { Octokit } from '@octokit/rest';
import { flatten, uniq } from 'lodash';
import { filterNil } from '../../../utils/filterEmpty';
import { logger } from '../../logger';
import { ora } from '../../ora';

export async function getReviewersFromPullRequests({
options,
pullNumbers,
}: {
options: {
githubApiBaseUrlV3?: string;
repoName: string;
repoOwner: string;
accessToken: string;
interactive: boolean;
authenticatedUsername: string;
};
pullNumbers: number[];
}) {
const {
githubApiBaseUrlV3,
repoName,
repoOwner,
accessToken,
interactive,
authenticatedUsername,
} = options;

const text = `Retrieving original reviewers`;
const spinner = ora(interactive, text).start();

const octokit = new Octokit({
auth: accessToken,
baseUrl: githubApiBaseUrlV3,
log: logger,
});

try {
const promises = pullNumbers.map(async (pullNumber) => {
const reviews = await octokit.pulls.listReviews({
owner: repoOwner,
repo: repoName,
pull_number: pullNumber,
});

return reviews.data
.map((review) => review.user?.login)
.filter((username) => username !== authenticatedUsername)
.filter(filterNil);
});

const reviewers = uniq(flatten(await Promise.all(promises)));
spinner.stop();
return reviewers;
} catch (e) {
// eslint-disable-next-line no-console
console.log(e);
spinner.fail(`Retrieving reviewers failed`);
}
}
36 changes: 36 additions & 0 deletions src/lib/github/v3/getReviewersFromPullRequests.ts.private.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { getDevAccessToken } from '../../../test/private/getDevAccessToken';
import { getReviewersFromPullRequests } from './getReviewersFromPullRequests';

const accessToken = getDevAccessToken();

describe('getReviewersFromPullRequests', () => {
it('returns reviewers', async () => {
const reviewers = await getReviewersFromPullRequests({
options: {
repoOwner: 'backport-org',
repoName: 'commit-author',
accessToken,
authenticatedUsername: 'foobar',
interactive: true,
},
pullNumbers: [2],
});

expect(reviewers).toEqual(['sqren', 'backport-demo-user']);
});

it('excludes current user', async () => {
const reviewers = await getReviewersFromPullRequests({
options: {
repoOwner: 'backport-org',
repoName: 'commit-author',
accessToken,
authenticatedUsername: 'sqren',
interactive: false,
},
pullNumbers: [2],
});

expect(reviewers).toEqual(['backport-demo-user']);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ValidConfigOptions } from '../../../options/options';
import { filterNil } from '../../../utils/filterEmpty';
import { Commit } from '../../sourceCommit/parseSourceCommit';
import { addReviewersToPullRequest } from './addReviewersToPullRequest';
import { getReviewersFromPullRequests } from './getReviewersFromPullRequests';

export async function syncSourcePullRequestReviewersToTargetPullRequest(
options: ValidConfigOptions,
commits: Commit[],
pullNumber: number,
) {
const pullNumbers = commits
.map((commit) => commit.sourcePullRequest?.number)
.filter(filterNil);

const reviewers = await getReviewersFromPullRequests({
options,
pullNumbers,
});
if (reviewers) {
await addReviewersToPullRequest(options, pullNumber, reviewers);
}
}
1 change: 1 addition & 0 deletions src/options/ConfigOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type AutoFixConflictsHandler = ({

type Options = Partial<{
accessToken: string;
addOriginalReviewers: boolean;
assignees: string[];
author: string | null;
autoAssign: boolean;
Expand Down
5 changes: 5 additions & 0 deletions src/options/cliArgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,11 @@ export function getOptionsFromCliArgs(processArgs: readonly string[]) {
string: true,
})

.option('addOriginalReviewers', {
description: 'Add reviewers of the original PRs to the target PR',
type: 'boolean',
})

.option('repoForkOwner', {
description:
'The owner of the fork where the backport branch is pushed. Defaults to the currently authenticated user',
Expand Down
1 change: 1 addition & 0 deletions src/options/options.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ describe('getOptions', () => {
expect(options).toEqual({
accessToken: 'abc',
assignees: [],
addOriginalReviewers: false,
authenticatedUsername: 'john.diller',
author: 'john.diller',
autoAssign: false,
Expand Down
1 change: 1 addition & 0 deletions src/options/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export type ValidConfigOptions = Readonly<

export const defaultConfigOptions = {
assignees: [] as Array<string>,
addOriginalReviewers: false,
autoAssign: false,
autoMerge: false,
autoMergeMethod: 'merge',
Expand Down
1 change: 1 addition & 0 deletions src/test/e2e/cli/entrypoint.cli.private.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ Options:
--pullNumber, --pr Pull request to backport [number]
--resetAuthor Set yourself as commit author [boolean]
--reviewer Add reviewer to the target PR [array]
--addOriginalReviewers Add reviewers of the original PRs to the target PR [boolean]
--repoForkOwner The owner of the fork where the backport branch is pushed.
Defaults to the currently authenticated user [string]
--repo Repo owner and name [string]
Expand Down

0 comments on commit 7d869aa

Please sign in to comment.