Skip to content

Commit

Permalink
feat(bitbucket): Implement PR cache for repositories (renovatebot#26345)
Browse files Browse the repository at this point in the history
  • Loading branch information
zharinov authored and zT-1337 committed Jan 24, 2024
1 parent d84a9e1 commit e6a80f1
Show file tree
Hide file tree
Showing 7 changed files with 351 additions and 65 deletions.
71 changes: 42 additions & 29 deletions lib/modules/platform/bitbucket/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import * as httpMock from '../../../../test/http-mock';
import type { logger as _logger } from '../../../logger';
import { reset as memCacheReset } from '../../../util/cache/memory';
import type * as _git from '../../../util/git';
import { setBaseUrl } from '../../../util/http/bitbucket';
import type { Platform, PlatformResult, RepoParams } from '../types';
import { prFieldsFilter } from './utils';

jest.mock('../../../util/git');
jest.mock('../../../util/host-rules');
Expand Down Expand Up @@ -43,6 +43,7 @@ describe('modules/platform/bitbucket/index', () => {
});

setBaseUrl(baseUrl);
memCacheReset();
});

async function initRepoMock(
Expand Down Expand Up @@ -235,9 +236,8 @@ describe('modules/platform/bitbucket/index', () => {
it('bitbucket finds PR for branch', async () => {
const scope = await initRepoMock();
scope
.get(
`/2.0/repositories/some/repo/pullrequests?state=OPEN&state=MERGED&state=DECLINED&state=SUPERSEDED&fields=${prFieldsFilter}&pagelen=50`,
)
.get(`/2.0/repositories/some/repo/pullrequests`)
.query(true)
.reply(200, { values: [pr] })
.get('/2.0/repositories/some/repo/pullrequests/5')
.reply(200, pr);
Expand All @@ -248,9 +248,8 @@ describe('modules/platform/bitbucket/index', () => {
it('returns null if no PR for branch', async () => {
const scope = await initRepoMock();
scope
.get(
`/2.0/repositories/some/repo/pullrequests?state=OPEN&state=MERGED&state=DECLINED&state=SUPERSEDED&fields=${prFieldsFilter}&pagelen=50`,
)
.get(`/2.0/repositories/some/repo/pullrequests`)
.query(true)
.reply(200, { values: [pr] });

const res = await bitbucket.getBranchPr('branch_without_pr');
Expand Down Expand Up @@ -753,9 +752,8 @@ describe('modules/platform/bitbucket/index', () => {
await bitbucket.initPlatform({ username: 'renovate', password: 'pass' });
await initRepoMock(undefined, null, scope);
scope
.get(
`/2.0/repositories/some/repo/pullrequests?state=OPEN&state=MERGED&state=DECLINED&state=SUPERSEDED&q=author.uuid="12345"&fields=${prFieldsFilter}&pagelen=50`,
)
.get(`/2.0/repositories/some/repo/pullrequests`)
.query(true)
.reply(200, {
values: [
{
Expand All @@ -779,9 +777,8 @@ describe('modules/platform/bitbucket/index', () => {
it('finds pr', async () => {
const scope = await initRepoMock();
scope
.get(
`/2.0/repositories/some/repo/pullrequests?state=OPEN&state=MERGED&state=DECLINED&state=SUPERSEDED&fields=${prFieldsFilter}&pagelen=50`,
)
.get(`/2.0/repositories/some/repo/pullrequests`)
.query(true)
.reply(200, { values: [pr] });
expect(
await bitbucket.findPr({
Expand All @@ -805,9 +802,8 @@ describe('modules/platform/bitbucket/index', () => {

const scope = await initRepoMock();
scope
.get(
`/2.0/repositories/some/repo/pullrequests?state=OPEN&state=MERGED&state=DECLINED&state=SUPERSEDED&fields=${prFieldsFilter}&pagelen=50`,
)
.get(`/2.0/repositories/some/repo/pullrequests`)
.query(true)
.reply(200, {
values: [
{
Expand Down Expand Up @@ -843,9 +839,8 @@ describe('modules/platform/bitbucket/index', () => {

const scope = await initRepoMock({}, { is_private: true });
scope
.get(
`/2.0/repositories/some/repo/pullrequests?state=OPEN&state=MERGED&state=DECLINED&state=SUPERSEDED&fields=${prFieldsFilter}&pagelen=50`,
)
.get(`/2.0/repositories/some/repo/pullrequests`)
.query(true)
.reply(200, {
values: [
{
Expand Down Expand Up @@ -883,9 +878,8 @@ describe('modules/platform/bitbucket/index', () => {

const scope = await initRepoMock({}, { is_private: false });
scope
.get(
`/2.0/repositories/some/repo/pullrequests?state=OPEN&state=MERGED&state=DECLINED&state=SUPERSEDED&fields=${prFieldsFilter}&pagelen=50`,
)
.get(`/2.0/repositories/some/repo/pullrequests`)
.query(true)
.reply(200, {
values: [
{
Expand Down Expand Up @@ -927,9 +921,8 @@ describe('modules/platform/bitbucket/index', () => {

const scope = await initRepoMock({}, { is_private: false });
scope
.get(
`/2.0/repositories/some/repo/pullrequests?state=OPEN&state=MERGED&state=DECLINED&state=SUPERSEDED&fields=${prFieldsFilter}&pagelen=50`,
)
.get(`/2.0/repositories/some/repo/pullrequests`)
.query(true)
.reply(200, {
values: [
{
Expand Down Expand Up @@ -1025,7 +1018,12 @@ describe('modules/platform/bitbucket/index', () => {
values: [projectReviewer, repoReviewer],
})
.post('/2.0/repositories/some/repo/pullrequests')
.reply(200, { id: 5 });
.reply(200, { id: 5 })
.get(`/2.0/repositories/some/repo/pullrequests`)
.query(true)
.reply(200, {
values: [{ id: 5 }],
});
const pr = await bitbucket.createPr({
sourceBranch: 'branch',
targetBranch: 'master',
Expand Down Expand Up @@ -1103,7 +1101,12 @@ describe('modules/platform/bitbucket/index', () => {
account_status: 'inactive',
})
.post('/2.0/repositories/some/repo/pullrequests')
.reply(200, { id: 5 });
.reply(200, { id: 5 })
.get(`/2.0/repositories/some/repo/pullrequests`)
.query(true)
.reply(200, {
values: [{ id: 5 }],
});
const pr = await bitbucket.createPr({
sourceBranch: 'branch',
targetBranch: 'master',
Expand Down Expand Up @@ -1161,7 +1164,12 @@ describe('modules/platform/bitbucket/index', () => {
)
.reply(200)
.post('/2.0/repositories/some/repo/pullrequests')
.reply(200, { id: 5 });
.reply(200, { id: 5 })
.get(`/2.0/repositories/some/repo/pullrequests`)
.query(true)
.reply(200, {
values: [{ id: 5 }],
});
const pr = await bitbucket.createPr({
sourceBranch: 'branch',
targetBranch: 'master',
Expand Down Expand Up @@ -1257,7 +1265,12 @@ describe('modules/platform/bitbucket/index', () => {
},
})
.post('/2.0/repositories/some/repo/pullrequests')
.reply(200, { id: 5 });
.reply(200, { id: 5 })
.get(`/2.0/repositories/some/repo/pullrequests`)
.query(true)
.reply(200, {
values: [{ id: 5 }],
});
const pr = await bitbucket.createPr({
sourceBranch: 'branch',
targetBranch: 'master',
Expand Down
60 changes: 25 additions & 35 deletions lib/modules/platform/bitbucket/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { repoFingerprint } from '../util';
import { smartTruncate } from '../utils/pr-body';
import { readOnlyIssueBody } from '../utils/read-only-issue-body';
import * as comments from './comments';
import { BitbucketPrCache } from './pr-cache';
import type {
Account,
BitbucketStatus,
Expand All @@ -44,7 +45,7 @@ import type {
RepoInfoBody,
} from './types';
import * as utils from './utils';
import { mergeBodyTransformer, prFieldsFilter } from './utils';
import { mergeBodyTransformer } from './utils';

export const id = 'bitbucket';

Expand Down Expand Up @@ -273,28 +274,11 @@ function matchesState(state: string, desiredState: string): boolean {

export async function getPrList(): Promise<Pr[]> {
logger.debug('getPrList()');
if (!config.prList) {
logger.debug('Retrieving PR list');
const querySearchParams = new URL.URLSearchParams();
for (const state of utils.prStates.all) {
querySearchParams.append('state', state);
}
if (renovateUserUuid && !config.ignorePrAuthor) {
querySearchParams.append('q', `author.uuid="${renovateUserUuid}"`);
}
querySearchParams.append('fields', prFieldsFilter);
const query = querySearchParams.toString();
const url = `/2.0/repositories/${config.repository}/pullrequests?${query}`;
const prs = (
await bitbucketHttp.getJson<PagedResult<PrResponse>>(url, {
paginate: true,
pagelen: 50,
})
).body.values;
config.prList = prs.map(utils.prInfo);
logger.debug(`Retrieved Pull Requests, count: ${config.prList.length}`);
}
return config.prList;
return await BitbucketPrCache.getPrs(
bitbucketHttp,
config.repository,
renovateUserUuid,
);
}

export async function findPr({
Expand Down Expand Up @@ -328,15 +312,17 @@ export async function findPr({
(!prTitle || p.title.toUpperCase() === prTitle.toUpperCase()) &&
matchesState(p.state, state),
);
if (pr) {
logger.debug(`Found PR #${pr.number}`);

if (!pr) {
return null;
}
logger.debug(`Found PR #${pr.number}`);

/**
* Bitbucket doesn't support renaming or reopening declined PRs.
* Instead, we have to use comment-driven signals.
*/
if (pr?.state === 'closed') {
if (pr.state === 'closed') {
const reopenComments = await comments.reopenComments(config, pr.number);

if (is.nonEmptyArray(reopenComments)) {
Expand All @@ -359,7 +345,7 @@ export async function findPr({
}
}

return pr ?? null;
return pr;
}

// Gets details for a PR
Expand Down Expand Up @@ -913,10 +899,12 @@ export async function createPr({
)
).body;
const pr = utils.prInfo(prRes);
// istanbul ignore if
if (config.prList) {
config.prList.push(pr);
}
await BitbucketPrCache.addPr(
bitbucketHttp,
config.repository,
renovateUserUuid,
pr,
);
return pr;
} catch (err) /* istanbul ignore next */ {
// Try sanitizing reviewers
Expand All @@ -938,10 +926,12 @@ export async function createPr({
)
).body;
const pr = utils.prInfo(prRes);
// istanbul ignore if
if (config.prList) {
config.prList.push(pr);
}
await BitbucketPrCache.addPr(
bitbucketHttp,
config.repository,
renovateUserUuid,
pr,
);
return pr;
}
}
Expand Down
Loading

0 comments on commit e6a80f1

Please sign in to comment.