aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRahulGautamSingh <[email protected]>2024-12-18 10:43:53 +0530
committerGitHub <[email protected]>2024-12-18 05:13:53 +0000
commit3ee48571b0aa39d81ce13fb44f01404a7f6a3bc4 (patch)
treeafe742e9eb51cb093039d928a7c7386efbae2375
parent6857f95cc75885295e8692ec4978055be9e9e26f (diff)
downloadrenovate-3ee48571b0aa39d81ce13fb44f01404a7f6a3bc4.tar.gz
renovate-3ee48571b0aa39d81ce13fb44f01404a7f6a3bc4.zip
fix(platform/bitbucket): ensure `getPrList()` runtime integrity (#32970)39.72.4
-rw-r--r--lib/modules/platform/bitbucket/index.spec.ts137
-rw-r--r--lib/modules/platform/bitbucket/index.ts39
2 files changed, 158 insertions, 18 deletions
diff --git a/lib/modules/platform/bitbucket/index.spec.ts b/lib/modules/platform/bitbucket/index.spec.ts
index 86b482f0985..a4f372e15e3 100644
--- a/lib/modules/platform/bitbucket/index.spec.ts
+++ b/lib/modules/platform/bitbucket/index.spec.ts
@@ -1668,7 +1668,12 @@ describe('modules/platform/bitbucket/index', () => {
.get('/2.0/repositories/some/repo/pullrequests/5')
.reply(200, { reviewers: [reviewer] })
.put('/2.0/repositories/some/repo/pullrequests/5')
- .reply(200);
+ .reply(200, { id: 5 })
+ .get(`/2.0/repositories/some/repo/pullrequests`)
+ .query(true)
+ .reply(200, {
+ values: [{ id: 5 }],
+ });
await expect(
bitbucket.updatePr({
number: 5,
@@ -1736,7 +1741,12 @@ describe('modules/platform/bitbucket/index', () => {
account_status: 'inactive',
})
.put('/2.0/repositories/some/repo/pullrequests/5')
- .reply(200);
+ .reply(200, { id: 5 })
+ .get(`/2.0/repositories/some/repo/pullrequests`)
+ .query(true)
+ .reply(200, {
+ values: [{ id: 5 }],
+ });
await expect(
bitbucket.updatePr({ number: 5, prTitle: 'title', prBody: 'body' }),
).toResolve();
@@ -1779,7 +1789,12 @@ describe('modules/platform/bitbucket/index', () => {
)
.reply(200)
.put('/2.0/repositories/some/repo/pullrequests/5')
- .reply(200);
+ .reply(200, { id: 5 })
+ .get(`/2.0/repositories/some/repo/pullrequests`)
+ .query(true)
+ .reply(200, {
+ values: [{ id: 5 }],
+ });
await expect(
bitbucket.updatePr({ number: 5, prTitle: 'title', prBody: 'body' }),
@@ -1884,9 +1899,14 @@ describe('modules/platform/bitbucket/index', () => {
.get('/2.0/repositories/some/repo/pullrequests/5')
.reply(200, { values: [pr] })
.put('/2.0/repositories/some/repo/pullrequests/5')
- .reply(200)
+ .reply(200, { id: 5 })
.post('/2.0/repositories/some/repo/pullrequests/5/decline')
- .reply(200);
+ .reply(200)
+ .get(`/2.0/repositories/some/repo/pullrequests`)
+ .query(true)
+ .reply(200, {
+ values: [{ id: 5 }],
+ });
expect(
await bitbucket.updatePr({
@@ -1898,6 +1918,113 @@ describe('modules/platform/bitbucket/index', () => {
});
});
+ describe('maintains pr cache integrity at runtime', () => {
+ it('pr cache gets updated after a pr is created', async () => {
+ const projectReviewer = {
+ type: 'default_reviewer',
+ reviewer_type: 'project',
+ user: {
+ display_name: 'Bob Smith',
+ uuid: '{d2238482-2e9f-48b3-8630-de22ccb9e42f}',
+ account_id: '123',
+ },
+ };
+ const repoReviewer = {
+ type: 'default_reviewer',
+ reviewer_type: 'repository',
+ user: {
+ display_name: 'Jane Smith',
+ uuid: '{90b6646d-1724-4a64-9fd9-539515fe94e9}',
+ account_id: '456',
+ },
+ };
+
+ const scope = httpMock.scope(baseUrl);
+ scope.get('/2.0/user').reply(200, { uuid: '12345' });
+ await bitbucket.initPlatform({ username: 'renovate', password: 'pass' });
+ await initRepoMock(undefined, null, scope);
+ scope
+ .get(`/2.0/repositories/some/repo/pullrequests`)
+ .query(true)
+ .reply(200, {
+ values: [
+ {
+ id: 1,
+ author: { uuid: '12345' },
+ source: { branch: { name: 'branch-a' } },
+ destination: { branch: { name: 'branch-b' } },
+ state: 'OPEN',
+ },
+ ],
+ })
+ .get(
+ '/2.0/repositories/some/repo/effective-default-reviewers?pagelen=100',
+ )
+ .reply(200, {
+ values: [projectReviewer, repoReviewer],
+ })
+ .post('/2.0/repositories/some/repo/pullrequests')
+ .reply(200, { id: 5 });
+
+ await bitbucket.getPrList(); // cache is now initialized
+
+ await bitbucket.createPr({
+ sourceBranch: 'branch',
+ targetBranch: 'master',
+ prTitle: 'title',
+ prBody: 'body',
+ platformPrOptions: {
+ bbUseDefaultReviewers: true,
+ },
+ });
+
+ const newPrList = await bitbucket.getPrList();
+ expect(newPrList).toHaveLength(2);
+ });
+
+ it('pr cache gets updated after a pr is updated', async () => {
+ const reviewer = {
+ display_name: 'Jane Smith',
+ uuid: '{90b6646d-1724-4a64-9fd9-539515fe94e9}',
+ };
+ const scope = httpMock.scope(baseUrl);
+ scope.get('/2.0/user').reply(200, { uuid: '12345' });
+ await bitbucket.initPlatform({ username: 'renovate', password: 'pass' });
+ await initRepoMock(undefined, null, scope);
+ scope
+ .get(`/2.0/repositories/some/repo/pullrequests`)
+ .query(true)
+ .reply(200, {
+ values: [
+ {
+ id: 5,
+ author: { uuid: '12345' },
+ source: { branch: { name: 'branch-a' } },
+ destination: { branch: { name: 'branch-b' } },
+ state: 'OPEN',
+ title: 'title',
+ },
+ ],
+ })
+ .get('/2.0/repositories/some/repo/pullrequests/5')
+ .reply(200, { reviewers: [reviewer] })
+ .put('/2.0/repositories/some/repo/pullrequests/5')
+ .reply(200, { id: 5, title: 'newTitle' });
+
+ const oldPrList = await bitbucket.getPrList(); // cache is now initialized
+ expect(oldPrList.find((pr) => pr.title === 'title')).toBeDefined();
+ await bitbucket.updatePr({
+ number: 5,
+ prTitle: 'newTitle',
+ prBody: 'body',
+ targetBranch: 'new_base',
+ });
+
+ const newPrList = await bitbucket.getPrList();
+ expect(newPrList.find((pr) => pr.title === 'newTitle')).toBeDefined();
+ });
+ });
+
describe('mergePr()', () => {
it('posts Merge with optional merge strategy', async () => {
const scope = await initRepoMock();
diff --git a/lib/modules/platform/bitbucket/index.ts b/lib/modules/platform/bitbucket/index.ts
index 35d125ffda8..11594cd7bc2 100644
--- a/lib/modules/platform/bitbucket/index.ts
+++ b/lib/modules/platform/bitbucket/index.ts
@@ -1022,6 +1022,7 @@ export async function updatePr({
)
).body;
+ let updatedPrRes: PrResponse;
try {
const body: any = {
title,
@@ -1036,10 +1037,12 @@ export async function updatePr({
};
}
- await bitbucketHttp.putJson(
- `/2.0/repositories/${config.repository}/pullrequests/${prNo}`,
- { body },
- );
+ updatedPrRes = (
+ await bitbucketHttp.putJson<PrResponse>(
+ `/2.0/repositories/${config.repository}/pullrequests/${prNo}`,
+ { body },
+ )
+ ).body;
} catch (err) {
// Try sanitizing reviewers
const sanitizedReviewers = await sanitizeReviewers(pr.reviewers, err);
@@ -1047,16 +1050,18 @@ export async function updatePr({
if (sanitizedReviewers === undefined) {
throw err;
} else {
- await bitbucketHttp.putJson(
- `/2.0/repositories/${config.repository}/pullrequests/${prNo}`,
- {
- body: {
- title,
- description: sanitize(description),
- reviewers: sanitizedReviewers,
+ updatedPrRes = (
+ await bitbucketHttp.putJson<PrResponse>(
+ `/2.0/repositories/${config.repository}/pullrequests/${prNo}`,
+ {
+ body: {
+ title,
+ description: sanitize(description),
+ reviewers: sanitizedReviewers,
+ },
},
- },
- );
+ )
+ ).body;
}
}
@@ -1065,6 +1070,14 @@ export async function updatePr({
`/2.0/repositories/${config.repository}/pullrequests/${prNo}/decline`,
);
}
+
+ // update pr cache
+ await BitbucketPrCache.setPr(
+ bitbucketHttp,
+ config.repository,
+ renovateUserUuid,
+ utils.prInfo({ ...updatedPrRes, ...(state && { state }) }),
+ );
}
export async function mergePr({