Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(platform/bitbucket): handle author is also default reviewer #22978

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions lib/modules/platform/bitbucket/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,56 @@ describe('modules/platform/bitbucket/index', () => {
).rejects.toThrow(new Error('Response code 401 (Unauthorized)'));
});

it('removes reviewer if they are also the author of the pr', async () => {
const reviewers = [
{
user: {
display_name: 'Bob Smith',
uuid: '{d2238482-2e9f-48b3-8630-de22ccb9e42f}',
account_id: '123',
},
},
{
user: {
display_name: 'Jane Smith',
uuid: '{90b6646d-1724-4a64-9fd9-539515fe94e9}',
account_id: '456',
},
},
];
const scope = await initRepoMock();
scope
.get(
'/2.0/repositories/some/repo/effective-default-reviewers?pagelen=100'
)
.reply(200, {
values: reviewers,
})
.post('/2.0/repositories/some/repo/pullrequests')
.reply(400, {
type: 'error',
error: {
fields: {
reviewers: [
'Jane Smith is the author and cannot be included as a reviewer.',
],
},
},
})
.post('/2.0/repositories/some/repo/pullrequests')
.reply(200, { id: 5 });
const pr = await bitbucket.createPr({
sourceBranch: 'branch',
targetBranch: 'master',
prTitle: 'title',
prBody: 'body',
platformOptions: {
bbUseDefaultReviewers: true,
},
});
expect(pr?.number).toBe(5);
});

it('rethrows exception when PR create error due to unknown reviewers error', async () => {
const reviewer = {
user: {
Expand Down
26 changes: 20 additions & 6 deletions lib/modules/platform/bitbucket/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -719,9 +719,15 @@ async function sanitizeReviewers(
if (err.statusCode === 400 && err.body?.error?.fields?.reviewers) {
const sanitizedReviewers: Account[] = [];

const MSG_AUTHOR_AND_REVIEWER =
'is the author and cannot be included as a reviewer.';
const MSG_MALFORMED_REVIEWERS_LIST = 'Malformed reviewers list';
const MSG_NOT_WORKSPACE_MEMBER =
'is not a member of this workspace and cannot be added to this pull request';

for (const msg of err.body.error.fields.reviewers) {
// Bitbucket returns a 400 if any of the PR reviewer accounts are now inactive (ie: disabled/suspended)
if (msg === 'Malformed reviewers list') {
if (msg === MSG_MALFORMED_REVIEWERS_LIST) {
logger.debug(
{ err },
'PR contains reviewers that may be either inactive or no longer a member of this workspace. Will try setting only active reviewers'
Expand All @@ -741,11 +747,7 @@ async function sanitizeReviewers(
}
}
// Bitbucket returns a 400 if any of the PR reviewer accounts are no longer members of this workspace
} else if (
msg.endsWith(
'is not a member of this workspace and cannot be added to this pull request'
)
) {
} else if (msg.endsWith(MSG_NOT_WORKSPACE_MEMBER)) {
logger.debug(
{ err },
'PR contains reviewer accounts which are no longer member of this workspace. Will try setting only member reviewers'
Expand All @@ -757,6 +759,17 @@ async function sanitizeReviewers(
sanitizedReviewers.push(reviewer);
}
}
} else if (msg.endsWith(MSG_AUTHOR_AND_REVIEWER)) {
logger.debug(
{ err },
'PR contains reviewer accounts which are also the author. Will try setting only non-author reviewers'
);
const author = msg.replace(MSG_AUTHOR_AND_REVIEWER, '').trim();
for (const reviewer of reviewers) {
if (reviewer.display_name !== author) {
sanitizedReviewers.push(reviewer);
}
}
} else {
return undefined;
}
Expand Down Expand Up @@ -822,6 +835,7 @@ export async function createPr({
).body;
reviewers = reviewersResponse.values.map((reviewer: EffectiveReviewer) => ({
uuid: reviewer.user.uuid,
display_name: reviewer.user.display_name,
}));
}

Expand Down