Skip to content

Commit c08cdff

Browse files
committed
Connects BitbucketServer cloud integration displays among connected integrations on the Home View
(#4107, #4146)
1 parent 850dfb7 commit c08cdff

File tree

11 files changed

+111
-14
lines changed

11 files changed

+111
-14
lines changed

docs/telemetry-events.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ or
378378
```typescript
379379
{
380380
'hostingProvider.key': string,
381-
'hostingProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'cloud-github-enterprise' | 'cloud-gitlab-self-hosted' | 'gitlab-self-hosted'
381+
'hostingProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'bitbucket-server' | 'github-enterprise' | 'cloud-github-enterprise' | 'cloud-gitlab-self-hosted' | 'gitlab-self-hosted'
382382
}
383383
```
384384

@@ -389,7 +389,7 @@ or
389389
```typescript
390390
{
391391
'hostingProvider.key': string,
392-
'hostingProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'cloud-github-enterprise' | 'cloud-gitlab-self-hosted' | 'gitlab-self-hosted'
392+
'hostingProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'bitbucket-server' | 'github-enterprise' | 'cloud-github-enterprise' | 'cloud-gitlab-self-hosted' | 'gitlab-self-hosted'
393393
}
394394
```
395395

@@ -400,7 +400,7 @@ or
400400
```typescript
401401
{
402402
'issueProvider.key': string,
403-
'issueProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'cloud-github-enterprise' | 'cloud-gitlab-self-hosted' | 'gitlab-self-hosted'
403+
'issueProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'bitbucket-server' | 'github-enterprise' | 'cloud-github-enterprise' | 'cloud-gitlab-self-hosted' | 'gitlab-self-hosted'
404404
}
405405
```
406406

@@ -411,7 +411,7 @@ or
411411
```typescript
412412
{
413413
'issueProvider.key': string,
414-
'issueProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'cloud-github-enterprise' | 'cloud-gitlab-self-hosted' | 'gitlab-self-hosted'
414+
'issueProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'bitbucket-server' | 'github-enterprise' | 'cloud-github-enterprise' | 'cloud-gitlab-self-hosted' | 'gitlab-self-hosted'
415415
}
416416
```
417417

@@ -432,7 +432,7 @@ or
432432
433433
```typescript
434434
{
435-
'integration.id': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'cloud-github-enterprise' | 'cloud-gitlab-self-hosted' | 'gitlab-self-hosted'
435+
'integration.id': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'bitbucket-server' | 'github-enterprise' | 'cloud-github-enterprise' | 'cloud-gitlab-self-hosted' | 'gitlab-self-hosted'
436436
}
437437
```
438438

@@ -1553,7 +1553,7 @@ void
15531553
```typescript
15541554
{
15551555
'hostingProvider.key': string,
1556-
'hostingProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'cloud-github-enterprise' | 'cloud-gitlab-self-hosted' | 'gitlab-self-hosted',
1556+
'hostingProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'bitbucket-server' | 'github-enterprise' | 'cloud-github-enterprise' | 'cloud-gitlab-self-hosted' | 'gitlab-self-hosted',
15571557
// @deprecated: true
15581558
'remoteProviders.key': string
15591559
}
@@ -1566,7 +1566,7 @@ void
15661566
```typescript
15671567
{
15681568
'hostingProvider.key': string,
1569-
'hostingProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'cloud-github-enterprise' | 'cloud-gitlab-self-hosted' | 'gitlab-self-hosted',
1569+
'hostingProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'bitbucket-server' | 'github-enterprise' | 'cloud-github-enterprise' | 'cloud-gitlab-self-hosted' | 'gitlab-self-hosted',
15701570
// @deprecated: true
15711571
'remoteProviders.key': string
15721572
}

src/constants.integrations.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export enum HostingIntegrationId {
66
}
77

88
export enum SelfHostedIntegrationId {
9+
BitbucketServer = 'bitbucket-server',
910
GitHubEnterprise = 'github-enterprise',
1011
CloudGitHubEnterprise = 'cloud-github-enterprise',
1112
CloudGitLabSelfHosted = 'cloud-gitlab-self-hosted',
@@ -14,6 +15,7 @@ export enum SelfHostedIntegrationId {
1415

1516
export type CloudSelfHostedIntegrationId =
1617
| SelfHostedIntegrationId.CloudGitHubEnterprise
18+
| SelfHostedIntegrationId.BitbucketServer
1719
| SelfHostedIntegrationId.CloudGitLabSelfHosted;
1820

1921
export enum IssueIntegrationId {
@@ -31,6 +33,7 @@ export const supportedOrderedCloudIntegrationIds = [
3133
SelfHostedIntegrationId.CloudGitLabSelfHosted,
3234
HostingIntegrationId.AzureDevOps,
3335
HostingIntegrationId.Bitbucket,
36+
SelfHostedIntegrationId.BitbucketServer,
3437
IssueIntegrationId.Jira,
3538
];
3639

@@ -92,6 +95,13 @@ export const supportedCloudIntegrationDescriptors: IntegrationDescriptor[] = [
9295
supports: ['prs', 'issues'],
9396
requiresPro: false,
9497
},
98+
{
99+
id: SelfHostedIntegrationId.BitbucketServer,
100+
name: 'Bitbucket Data Center',
101+
icon: 'gl-provider-bitbucket',
102+
supports: ['prs'],
103+
requiresPro: true,
104+
},
95105
{
96106
id: IssueIntegrationId.Jira,
97107
name: 'Jira',

src/git/remotes/remoteProviders.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ const builtInProviders: RemoteProviders = [
7676
},
7777
];
7878

79+
const cloudRemotesMap: { [key: string]: typeof GitHubRemote | typeof GitLabRemote | typeof BitbucketServerRemote } = {
80+
[SelfHostedIntegrationId.CloudGitHubEnterprise]: GitHubRemote,
81+
[SelfHostedIntegrationId.CloudGitLabSelfHosted]: GitLabRemote,
82+
[SelfHostedIntegrationId.BitbucketServer]: BitbucketServerRemote,
83+
};
84+
7985
export function loadRemoteProviders(
8086
cfg: RemotesConfig[] | null | undefined,
8187
configuredIntegrations?: ConfiguredIntegrationDescriptor[],
@@ -107,10 +113,8 @@ export function loadRemoteProviders(
107113
for (const ci of configuredIntegrations) {
108114
if (isCloudSelfHostedIntegrationId(ci.integrationId) && ci.domain) {
109115
const matcher = ci.domain.toLocaleLowerCase();
110-
const providerCreator = (_container: Container, domain: string, path: string) =>
111-
ci.integrationId === SelfHostedIntegrationId.CloudGitHubEnterprise
112-
? new GitHubRemote(domain, path)
113-
: new GitLabRemote(domain, path);
116+
const providerCreator = (_container: Container, domain: string, path: string): RemoteProvider =>
117+
new cloudRemotesMap[ci.integrationId](domain, path);
114118
const provider = {
115119
custom: false,
116120
matcher: matcher,
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
import { HostingIntegrationId } from '../../../constants.integrations';
1+
import { HostingIntegrationId, SelfHostedIntegrationId } from '../../../constants.integrations';
22
import { CloudIntegrationAuthenticationProvider } from './integrationAuthenticationProvider';
33

44
export class BitbucketAuthenticationProvider extends CloudIntegrationAuthenticationProvider<HostingIntegrationId.Bitbucket> {
55
protected override get authProviderId(): HostingIntegrationId.Bitbucket {
66
return HostingIntegrationId.Bitbucket;
77
}
88
}
9+
10+
export class BitbucketServerAuthenticationProvider extends CloudIntegrationAuthenticationProvider<SelfHostedIntegrationId.BitbucketServer> {
11+
protected override get authProviderId(): SelfHostedIntegrationId.BitbucketServer {
12+
return SelfHostedIntegrationId.BitbucketServer;
13+
}
14+
}

src/plus/integrations/authentication/integrationAuthenticationService.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ export class IntegrationAuthenticationService implements Disposable {
6868
await import(/* webpackChunkName: "integrations" */ './bitbucket')
6969
).BitbucketAuthenticationProvider(this.container, this, this.configuredIntegrationService);
7070
break;
71+
case SelfHostedIntegrationId.BitbucketServer:
72+
provider = new (
73+
await import(/* webpackChunkName: "integrations" */ './bitbucket')
74+
).BitbucketServerAuthenticationProvider(this.container, this, this.configuredIntegrationService);
75+
break;
7176
case HostingIntegrationId.GitHub:
7277
provider = isSupportedCloudIntegrationId(HostingIntegrationId.GitHub)
7378
? new (

src/plus/integrations/authentication/models.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export type CloudIntegrationType =
4747
| 'gitlab'
4848
| 'github'
4949
| 'bitbucket'
50+
| 'bitbucketServer'
5051
| 'azure'
5152
| 'githubEnterprise'
5253
| 'gitlabSelfHosted';
@@ -73,6 +74,7 @@ export const toIntegrationId: { [key in CloudIntegrationType]: IntegrationId } =
7374
githubEnterprise: SelfHostedIntegrationId.CloudGitHubEnterprise,
7475
gitlabSelfHosted: SelfHostedIntegrationId.CloudGitLabSelfHosted,
7576
bitbucket: HostingIntegrationId.Bitbucket,
77+
bitbucketServer: SelfHostedIntegrationId.BitbucketServer,
7678
azure: HostingIntegrationId.AzureDevOps,
7779
};
7880

@@ -85,6 +87,7 @@ export const toCloudIntegrationType: { [key in IntegrationId]: CloudIntegrationT
8587
[HostingIntegrationId.AzureDevOps]: 'azure',
8688
[SelfHostedIntegrationId.CloudGitHubEnterprise]: 'githubEnterprise',
8789
[SelfHostedIntegrationId.CloudGitLabSelfHosted]: 'gitlabSelfHosted',
90+
[SelfHostedIntegrationId.BitbucketServer]: 'bitbucketServer',
8891
[SelfHostedIntegrationId.GitHubEnterprise]: undefined,
8992
[SelfHostedIntegrationId.GitLabSelfHosted]: undefined,
9093
};

src/plus/integrations/integrationService.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,7 @@ export function remoteProviderIdToIntegrationId(
10511051
case 'gitlab':
10521052
return HostingIntegrationId.GitLab;
10531053
case 'bitbucket-server':
1054+
return SelfHostedIntegrationId.BitbucketServer;
10541055
default:
10551056
return undefined;
10561057
}

src/plus/integrations/providers/models.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type {
77
AzureProject,
88
AzureSetPullRequestInput,
99
Bitbucket,
10+
BitbucketServer,
1011
BitbucketWorkspaceStub,
1112
EnterpriseOptions,
1213
GetRepoInput,
@@ -18,6 +19,7 @@ import type {
1819
Jira,
1920
JiraProject,
2021
JiraResource,
22+
NumberedPageInput,
2123
Issue as ProviderApiIssue,
2224
PullRequestWithUniqueID,
2325
RequestFunction,
@@ -82,6 +84,7 @@ const selfHostedIntegrationIds: SelfHostedIntegrationId[] = [
8284
SelfHostedIntegrationId.GitHubEnterprise,
8385
SelfHostedIntegrationId.CloudGitLabSelfHosted,
8486
SelfHostedIntegrationId.GitLabSelfHosted,
87+
SelfHostedIntegrationId.BitbucketServer,
8588
] as const;
8689

8790
export const supportedIntegrationIds: IntegrationId[] = [
@@ -108,7 +111,11 @@ export function isHostingIntegrationId(id: IntegrationId): id is HostingIntegrat
108111
}
109112

110113
export function isCloudSelfHostedIntegrationId(id: IntegrationId): id is CloudSelfHostedIntegrationId {
111-
return id === SelfHostedIntegrationId.CloudGitHubEnterprise || id === SelfHostedIntegrationId.CloudGitLabSelfHosted;
114+
return (
115+
id === SelfHostedIntegrationId.CloudGitHubEnterprise ||
116+
id === SelfHostedIntegrationId.CloudGitLabSelfHosted ||
117+
id === SelfHostedIntegrationId.BitbucketServer
118+
);
112119
}
113120

114121
export enum PullRequestFilter {
@@ -342,14 +349,24 @@ export type GetBitbucketResourcesForUserFn = (
342349
input: { userId: string },
343350
options?: EnterpriseOptions,
344351
) => Promise<{ data: BitbucketWorkspaceStub[] }>;
352+
export type GetBitbucketServerPullRequestsForCurrentUserFn = (
353+
input: NumberedPageInput,
354+
options?: EnterpriseOptions,
355+
) => Promise<{
356+
pageInfo: {
357+
hasNextPage: boolean;
358+
nextPage: number | null;
359+
};
360+
data: GitPullRequest[];
361+
}>;
345362
export type GetIssuesForProjectFn = Jira['getIssuesForProject'];
346363
export type GetIssuesForResourceForCurrentUserFn = (
347364
input: { resourceId: string },
348365
options?: EnterpriseOptions,
349366
) => Promise<{ data: ProviderIssue[] }>;
350367

351368
export interface ProviderInfo extends ProviderMetadata {
352-
provider: GitHub | GitLab | Bitbucket | Jira | Trello | AzureDevOps;
369+
provider: GitHub | GitLab | Bitbucket | BitbucketServer | Jira | Trello | AzureDevOps;
353370
getPullRequestsForReposFn?: GetPullRequestsForReposFn;
354371
getPullRequestsForRepoFn?: GetPullRequestsForRepoFn;
355372
getPullRequestsForUserFn?: GetPullRequestsForUserFn;
@@ -364,6 +381,7 @@ export interface ProviderInfo extends ProviderMetadata {
364381
getJiraResourcesForCurrentUserFn?: GetJiraResourcesForCurrentUserFn;
365382
getAzureResourcesForUserFn?: GetAzureResourcesForUserFn;
366383
getBitbucketResourcesForUserFn?: GetBitbucketResourcesForUserFn;
384+
getBitbucketServerPullRequestsForCurrentUserFn?: GetBitbucketServerPullRequestsForCurrentUserFn;
367385
getJiraProjectsForResourcesFn?: GetJiraProjectsForResourcesFn;
368386
getAzureProjectsForResourceFn?: GetAzureProjectsForResourceFn;
369387
getIssuesForProjectFn?: GetIssuesForProjectFn;
@@ -511,6 +529,15 @@ export const providersMetadata: ProvidersMetadata = {
511529
supportedPullRequestFilters: [PullRequestFilter.Author],
512530
scopes: ['account:read', 'repository:read', 'pullrequest:read', 'issue:read'],
513531
},
532+
[SelfHostedIntegrationId.BitbucketServer]: {
533+
domain: '',
534+
id: SelfHostedIntegrationId.BitbucketServer,
535+
name: 'Bitbucket Data Center',
536+
type: 'hosting',
537+
iconKey: SelfHostedIntegrationId.BitbucketServer,
538+
supportedPullRequestFilters: [PullRequestFilter.Author, PullRequestFilter.ReviewRequested],
539+
scopes: ['Project (Read)', 'Repository (Write)'],
540+
},
514541
[HostingIntegrationId.AzureDevOps]: {
515542
domain: 'dev.azure.com',
516543
id: HostingIntegrationId.AzureDevOps,

src/plus/integrations/providers/providersApi.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,24 @@ export class ProvidersApi {
212212
providerApis.bitbucket,
213213
) as MergePullRequestFn,
214214
},
215+
[SelfHostedIntegrationId.BitbucketServer]: {
216+
...providersMetadata[SelfHostedIntegrationId.BitbucketServer],
217+
provider: providerApis.bitbucketServer,
218+
getCurrentUserFn: providerApis.bitbucketServer.getCurrentUser.bind(
219+
providerApis.bitbucketServer,
220+
) as GetCurrentUserFn,
221+
getBitbucketServerPullRequestsForCurrentUserFn:
222+
providerApis.bitbucketServer.getPullRequestsForCurrentUser.bind(providerApis.bitbucketServer),
223+
getPullRequestsForReposFn: providerApis.bitbucketServer.getPullRequestsForRepos.bind(
224+
providerApis.bitbucketServer,
225+
) as GetPullRequestsForReposFn,
226+
getPullRequestsForRepoFn: providerApis.bitbucketServer.getPullRequestsForRepo.bind(
227+
providerApis.bitbucketServer,
228+
) as GetPullRequestsForRepoFn,
229+
mergePullRequestFn: providerApis.bitbucketServer.mergePullRequest.bind(
230+
providerApis.bitbucketServer,
231+
) as MergePullRequestFn,
232+
},
215233
[HostingIntegrationId.AzureDevOps]: {
216234
...providersMetadata[HostingIntegrationId.AzureDevOps],
217235
provider: providerApis.azureDevOps,
@@ -564,6 +582,21 @@ export class ProvidersApi {
564582
}
565583
}
566584

585+
async getBitbucketServerPullRequestsForCurrentUser(options?: {
586+
accessToken?: string;
587+
}): Promise<ProviderPullRequest[] | undefined> {
588+
const { provider, token } = await this.ensureProviderTokenAndFunction(
589+
SelfHostedIntegrationId.BitbucketServer,
590+
'getBitbucketServerPullRequestsForCurrentUserFn',
591+
options?.accessToken,
592+
);
593+
try {
594+
return (await provider.getBitbucketServerPullRequestsForCurrentUserFn?.({}, { token: token }))?.data;
595+
} catch (e) {
596+
return this.handleProviderError(SelfHostedIntegrationId.BitbucketServer, token, e);
597+
}
598+
}
599+
567600
async getJiraProjectsForResources(
568601
resourceIds: string[],
569602
options?: { accessToken?: string },

src/plus/integrations/providers/utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ export function getProviderIdFromEntityIdentifier(
107107
return HostingIntegrationId.AzureDevOps;
108108
case EntityIdentifierProviderType.Bitbucket:
109109
return HostingIntegrationId.Bitbucket;
110+
case EntityIdentifierProviderType.BitbucketServer:
111+
return isGitConfigEntityIdentifier(entityIdentifier) && entityIdentifier.metadata.isCloudEnterprise
112+
? SelfHostedIntegrationId.BitbucketServer
113+
: undefined;
110114
default:
111115
return undefined;
112116
}
@@ -130,6 +134,8 @@ function fromStringToEntityIdentifierProviderType(str: string): EntityIdentifier
130134
return EntityIdentifierProviderType.Azure;
131135
case 'bitbucket':
132136
return EntityIdentifierProviderType.Bitbucket;
137+
case 'bitbucket-server':
138+
return EntityIdentifierProviderType.BitbucketServer;
133139
default:
134140
throw new Error(`Unknown provider type '${str}'`);
135141
}
@@ -231,6 +237,7 @@ export async function getIssueFromGitConfigEntityIdentifier(
231237
identifier.provider !== EntityIdentifierProviderType.GithubEnterprise &&
232238
identifier.provider !== EntityIdentifierProviderType.GitlabSelfHosted &&
233239
identifier.provider !== EntityIdentifierProviderType.Bitbucket &&
240+
identifier.provider !== EntityIdentifierProviderType.BitbucketServer &&
234241
identifier.provider !== EntityIdentifierProviderType.Azure
235242
) {
236243
return undefined;

0 commit comments

Comments
 (0)