Skip to content

Commit 0f22513

Browse files
committed
Retrieves Bitbucket PRs where a user is author or reviewer
(#4046)
1 parent 84e8e04 commit 0f22513

File tree

2 files changed

+62
-19
lines changed

2 files changed

+62
-19
lines changed

Diff for: src/plus/integrations/providers/bitbucket.ts

+29-19
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@ import type {
1212
SearchedPullRequest,
1313
} from '../../../git/models/pullRequest';
1414
import type { RepositoryMetadata } from '../../../git/models/repositoryMetadata';
15+
import { groupBy } from '../../../system/iterable';
16+
import { getSettledValue } from '../../../system/promise';
1517
import type { IntegrationAuthenticationProviderDescriptor } from '../authentication/integrationAuthenticationProvider';
1618
import type { ProviderAuthenticationSession } from '../authentication/models';
1719
import type { ResourceDescriptor } from '../integration';
1820
import { HostingIntegration } from '../integration';
19-
import type { ProviderPullRequest } from './models';
20-
import { fromProviderPullRequest, providersMetadata } from './models';
21+
import { providersMetadata } from './models';
2122

2223
const metadata = providersMetadata[HostingIntegrationId.Bitbucket];
2324
const authProvider = Object.freeze({ id: metadata.id, scopes: metadata.scopes });
@@ -268,7 +269,6 @@ export class BitbucketIntegration extends HostingIntegration<
268269
session: ProviderAuthenticationSession,
269270
requestedRepositories?: BitbucketRepositoryDescriptor[],
270271
): Promise<SearchedPullRequest[] | undefined> {
271-
const api = await this.getProvidersApi();
272272
if (requestedRepositories != null) {
273273
// TODO: implement repos version
274274
return undefined;
@@ -283,17 +283,35 @@ export class BitbucketIntegration extends HostingIntegration<
283283
const repos = await this.getProviderProjectsForResources(session, workspaces);
284284
if (repos == null || repos.length === 0) return undefined;
285285

286-
const prs = await api.getPullRequestsForRepos(
287-
HostingIntegrationId.Bitbucket,
288-
repos.map(repo => ({ namespace: repo.owner, name: repo.name })),
289-
{
290-
accessToken: session.accessToken,
291-
},
286+
const api = await this.container.bitbucket;
287+
if (!api) return undefined;
288+
const prsResult = await Promise.allSettled(
289+
repos.map(repo =>
290+
api.getUsersPullRequestsForRepo(
291+
this,
292+
session.accessToken,
293+
user.id,
294+
repo.owner,
295+
repo.name,
296+
this.apiBaseUrl,
297+
),
298+
),
292299
);
293-
return prs.values.map(pr => ({
294-
pullRequest: this.fromBitbucketProviderPullRequest(pr),
300+
const prs = prsResult
301+
.map(r => getSettledValue(r))
302+
.filter(r => r != null)
303+
.flat();
304+
305+
const groups = groupBy(prs, pr => (pr.author.id === user.id ? 'authored' : 'other'));
306+
const authoredPrs = groups.authored.map(pr => ({
307+
pullRequest: pr,
308+
reasons: ['authored'],
309+
}));
310+
const otherPrs = groups.other.map(pr => ({
311+
pullRequest: pr,
295312
reasons: [],
296313
}));
314+
return [...authoredPrs, ...otherPrs];
297315
}
298316

299317
protected override async searchProviderMyIssues(
@@ -303,14 +321,6 @@ export class BitbucketIntegration extends HostingIntegration<
303321
return Promise.resolve(undefined);
304322
}
305323

306-
private fromBitbucketProviderPullRequest(
307-
remotePullRequest: ProviderPullRequest,
308-
// repoDescriptors: BitbucketRemoteRepositoryDescriptor[],
309-
): PullRequest {
310-
remotePullRequest.graphQLId = remotePullRequest.id;
311-
return fromProviderPullRequest(remotePullRequest, this);
312-
}
313-
314324
protected override async providerOnConnect(): Promise<void> {
315325
if (this._session == null) return;
316326

Diff for: src/plus/integrations/providers/bitbucket/bitbucket.ts

+33
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,39 @@ export class BitbucketApi implements Disposable {
221221
}
222222
}
223223

224+
public async getUsersPullRequestsForRepo(
225+
provider: Provider,
226+
token: string,
227+
userUuid: string,
228+
owner: string,
229+
repo: string,
230+
baseUrl: string,
231+
): Promise<PullRequest[] | undefined> {
232+
const scope = getLogScope();
233+
234+
const query = encodeURIComponent(`reviewers.uuid="${userUuid}" OR author.uuid="${userUuid}"`);
235+
const response = await this.request<{
236+
values: BitbucketPullRequest[];
237+
pagelen: number;
238+
size: number;
239+
page: number;
240+
}>(
241+
provider,
242+
token,
243+
baseUrl,
244+
`repositories/${owner}/${repo}/pullrequests?q=${query}&state=OPEN&fields=%2Bvalues.reviewers,%2Bvalues.participants`,
245+
{
246+
method: 'GET',
247+
},
248+
scope,
249+
);
250+
251+
if (!response?.values?.length) {
252+
return undefined;
253+
}
254+
return response.values.map(pr => fromBitbucketPullRequest(pr, provider));
255+
}
256+
224257
private async request<T>(
225258
provider: Provider,
226259
token: string,

0 commit comments

Comments
 (0)