Skip to content

Commit cb7e263

Browse files
sergeibbbeamodioaxosoft-ramint
authored
Integrations support self hosted providers from gkdev (#3901) (#3922)
* Adds support for GKDev Cloud GitHub Enterprise integration (#3901, #3922) * Associates a Cloud GitHub Enterprise provider with remote by its domain (#3901, #3922) * Adds GitHub Enterprize menu item (#3901, #3922) * Filters out GitHub's icon in the bar (#3901, #3922) * Makes sure that cloud version of GitHubEnterprise is used when needed (#3901, #3922) * Updates (minor) from code review * Stores and uses stored values for configured integration descriptors * Rename config integration descriptor (#3901, #3922) * Adds a todo for a follow-up ticket (#3901, #3922) --------- Co-authored-by: Eric Amodio <[email protected]> Co-authored-by: Ramin Tadayon <[email protected]>
1 parent 3ebae2f commit cb7e263

File tree

17 files changed

+415
-61
lines changed

17 files changed

+415
-61
lines changed

Diff for: docs/telemetry-events.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ or
319319
```typescript
320320
{
321321
'hostingProvider.key': string,
322-
'hostingProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'gitlab-self-hosted'
322+
'hostingProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'cloud-github-enterprise' | 'gitlab-self-hosted'
323323
}
324324
```
325325

@@ -330,7 +330,7 @@ or
330330
```typescript
331331
{
332332
'hostingProvider.key': string,
333-
'hostingProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'gitlab-self-hosted'
333+
'hostingProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'cloud-github-enterprise' | 'gitlab-self-hosted'
334334
}
335335
```
336336

@@ -341,7 +341,7 @@ or
341341
```typescript
342342
{
343343
'issueProvider.key': string,
344-
'issueProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'gitlab-self-hosted'
344+
'issueProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'cloud-github-enterprise' | 'gitlab-self-hosted'
345345
}
346346
```
347347

@@ -352,7 +352,7 @@ or
352352
```typescript
353353
{
354354
'issueProvider.key': string,
355-
'issueProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'gitlab-self-hosted'
355+
'issueProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'cloud-github-enterprise' | 'gitlab-self-hosted'
356356
}
357357
```
358358

@@ -373,7 +373,7 @@ or
373373
374374
```typescript
375375
{
376-
'integration.id': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello'
376+
'integration.id': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'cloud-github-enterprise' | 'gitlab-self-hosted'
377377
}
378378
```
379379

@@ -1465,7 +1465,7 @@ void
14651465
```typescript
14661466
{
14671467
'hostingProvider.key': string,
1468-
'hostingProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'gitlab-self-hosted',
1468+
'hostingProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'cloud-github-enterprise' | 'gitlab-self-hosted',
14691469
// @deprecated: true
14701470
'remoteProviders.key': string
14711471
}
@@ -1478,7 +1478,7 @@ void
14781478
```typescript
14791479
{
14801480
'hostingProvider.key': string,
1481-
'hostingProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'gitlab-self-hosted',
1481+
'hostingProvider.provider': 'github' | 'gitlab' | 'bitbucket' | 'azureDevOps' | 'jira' | 'trello' | 'github-enterprise' | 'cloud-github-enterprise' | 'gitlab-self-hosted',
14821482
// @deprecated: true
14831483
'remoteProviders.key': string
14841484
}

Diff for: src/constants.integrations.ts

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export enum HostingIntegrationId {
77

88
export enum SelfHostedIntegrationId {
99
GitHubEnterprise = 'github-enterprise',
10+
CloudGitHubEnterprise = 'cloud-github-enterprise',
1011
GitLabSelfHosted = 'gitlab-self-hosted',
1112
}
1213

@@ -20,6 +21,7 @@ export type IntegrationId = HostingIntegrationId | IssueIntegrationId | SelfHost
2021
export const supportedOrderedCloudIssueIntegrationIds = [IssueIntegrationId.Jira];
2122
export const supportedOrderedCloudIntegrationIds = [
2223
HostingIntegrationId.GitHub,
24+
SelfHostedIntegrationId.CloudGitHubEnterprise,
2325
HostingIntegrationId.GitLab,
2426
IssueIntegrationId.Jira,
2527
];
@@ -45,6 +47,12 @@ export const supportedCloudIntegrationDescriptors: IntegrationDescriptor[] = [
4547
icon: 'gl-provider-github',
4648
supports: ['prs', 'issues'],
4749
},
50+
{
51+
id: SelfHostedIntegrationId.CloudGitHubEnterprise,
52+
name: 'GitHub Enterprise',
53+
icon: 'gl-provider-github',
54+
supports: ['prs', 'issues'],
55+
},
4856
{
4957
id: HostingIntegrationId.GitLab,
5058
name: 'GitLab',

Diff for: src/constants.storage.ts

+11
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export type GlobalStorage = {
7878
'launchpadView:groups:expanded': StoredLaunchpadGroup[];
7979
'graph:searchMode': StoredGraphSearchMode;
8080
'views:scm:grouped:welcome:dismissed': boolean;
81+
'integrations:configured': StoredIntegrationConfigurations;
8182
} & { [key in `plus:preview:${FeaturePreviews}:usages`]: StoredFeaturePreviewUsagePeriod[] } & {
8283
[key in `confirm:ai:tos:${AIProviders}`]: boolean;
8384
} & {
@@ -88,6 +89,16 @@ export type GlobalStorage = {
8889
[key in `jira:${string}:projects`]: Stored<StoredJiraProject[] | undefined>;
8990
};
9091

92+
export type StoredIntegrationConfigurations = Record<string, StoredConfiguredIntegrationDescriptor[] | undefined>;
93+
94+
export interface StoredConfiguredIntegrationDescriptor {
95+
cloud: boolean;
96+
integrationId: IntegrationId;
97+
domain?: string;
98+
expiresAt?: string;
99+
scopes: string;
100+
}
101+
91102
export type DeprecatedWorkspaceStorage = {
92103
/** @deprecated use `confirm:ai:tos:${AIProviders}` */
93104
'confirm:sendToOpenAI': boolean;

Diff for: src/env/node/git/sub-providers/remotes.ts

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export class RemotesGitSubProvider extends RemotesGitProviderBase implements Git
4040
async function load(this: RemotesGitSubProvider): Promise<GitRemote[]> {
4141
const providers = loadRemoteProviders(
4242
configuration.get('remotes', this.container.git.getRepository(repoPath!)?.folder?.uri ?? null),
43+
this.container.integrations.getConfiguredIntegrationDescriptors(),
4344
);
4445

4546
try {

Diff for: src/git/remotes/remoteProviders.ts

+33-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import type { RemotesConfig } from '../../config';
2+
import { SelfHostedIntegrationId } from '../../constants.integrations';
23
import type { Container } from '../../container';
4+
import type { ConfiguredIntegrationDescriptor } from '../../plus/integrations/authentication/models';
35
import { Logger } from '../../system/logger';
46
import { configuration } from '../../system/vscode/configuration';
57
import { AzureDevOpsRemote } from './azure-devops';
@@ -73,7 +75,10 @@ const builtInProviders: RemoteProviders = [
7375
},
7476
];
7577

76-
export function loadRemoteProviders(cfg: RemotesConfig[] | null | undefined): RemoteProviders {
78+
export function loadRemoteProviders(
79+
cfg: RemotesConfig[] | null | undefined,
80+
configuredIntegrations?: ConfiguredIntegrationDescriptor[],
81+
): RemoteProviders {
7782
const providers: RemoteProviders = [];
7883

7984
if (cfg?.length) {
@@ -97,6 +102,29 @@ export function loadRemoteProviders(cfg: RemotesConfig[] | null | undefined): Re
97102
}
98103
}
99104

105+
if (configuredIntegrations?.length) {
106+
for (const ci of configuredIntegrations) {
107+
if (ci.integrationId === SelfHostedIntegrationId.CloudGitHubEnterprise && ci.domain) {
108+
const matcher = ci.domain.toLocaleLowerCase();
109+
const providerCreator = (_container: Container, domain: string, path: string) =>
110+
new GitHubRemote(domain, path);
111+
const provider = {
112+
custom: false,
113+
matcher: matcher,
114+
creator: providerCreator,
115+
};
116+
117+
const indexOfCustomDuplication: number = providers.findIndex(p => p.matcher === matcher);
118+
119+
if (indexOfCustomDuplication !== -1) {
120+
providers[indexOfCustomDuplication] = provider;
121+
} else {
122+
providers.push(provider);
123+
}
124+
}
125+
}
126+
}
127+
100128
providers.push(...builtInProviders);
101129

102130
return providers;
@@ -141,7 +169,10 @@ export function getRemoteProviderMatcher(
141169
providers?: RemoteProviders,
142170
): (url: string, domain: string, path: string) => RemoteProvider | undefined {
143171
if (providers == null) {
144-
providers = loadRemoteProviders(configuration.get('remotes', null));
172+
providers = loadRemoteProviders(
173+
configuration.get('remotes', null),
174+
container.integrations.getConfiguredIntegrationDescriptors(),
175+
);
145176
}
146177

147178
return (url: string, domain: string, path: string) =>

Diff for: src/plus/integrations/authentication/github.ts

+16-3
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,19 @@ import { wrapForForcedInsecureSSL } from '@env/fetch';
44
import { HostingIntegrationId, SelfHostedIntegrationId } from '../../../constants.integrations';
55
import type { Sources } from '../../../constants.telemetry';
66
import type { Container } from '../../../container';
7-
import type { IntegrationAuthenticationSessionDescriptor } from './integrationAuthentication';
7+
import type {
8+
IntegrationAuthenticationService,
9+
IntegrationAuthenticationSessionDescriptor,
10+
} from './integrationAuthentication';
811
import {
912
CloudIntegrationAuthenticationProvider,
1013
LocalIntegrationAuthenticationProvider,
1114
} from './integrationAuthentication';
1215
import type { ProviderAuthenticationSession } from './models';
1316

1417
export class GitHubAuthenticationProvider extends CloudIntegrationAuthenticationProvider<HostingIntegrationId.GitHub> {
15-
constructor(container: Container) {
16-
super(container);
18+
constructor(container: Container, authenticationService: IntegrationAuthenticationService) {
19+
super(container, authenticationService);
1720
this.disposables.push(
1821
authentication.onDidChangeSessions(e => {
1922
if (e.provider.id === this.authProviderId) {
@@ -69,6 +72,16 @@ export class GitHubAuthenticationProvider extends CloudIntegrationAuthentication
6972
}
7073
}
7174

75+
export class GitHubEnterpriseCloudAuthenticationProvider extends CloudIntegrationAuthenticationProvider<SelfHostedIntegrationId.CloudGitHubEnterprise> {
76+
protected override getCompletionInputTitle(): string {
77+
throw new Error('Connect to GitHub Enterprise');
78+
}
79+
80+
protected override get authProviderId(): SelfHostedIntegrationId.CloudGitHubEnterprise {
81+
return SelfHostedIntegrationId.CloudGitHubEnterprise;
82+
}
83+
}
84+
7285
export class GitHubEnterpriseAuthenticationProvider extends LocalIntegrationAuthenticationProvider<SelfHostedIntegrationId.GitHubEnterprise> {
7386
protected override get authProviderId(): SelfHostedIntegrationId.GitHubEnterprise {
7487
return SelfHostedIntegrationId.GitHubEnterprise;

Diff for: src/plus/integrations/authentication/gitlab.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import { env, ThemeIcon, Uri, window } from 'vscode';
33
import type { SelfHostedIntegrationId } from '../../../constants.integrations';
44
import { HostingIntegrationId } from '../../../constants.integrations';
55
import type { Container } from '../../../container';
6-
import type { IntegrationAuthenticationSessionDescriptor } from './integrationAuthentication';
6+
import type {
7+
IntegrationAuthenticationService,
8+
IntegrationAuthenticationSessionDescriptor,
9+
} from './integrationAuthentication';
710
import {
811
CloudIntegrationAuthenticationProvider,
912
LocalIntegrationAuthenticationProvider,
@@ -15,9 +18,10 @@ type GitLabId = HostingIntegrationId.GitLab | SelfHostedIntegrationId.GitLabSelf
1518
export class GitLabLocalAuthenticationProvider extends LocalIntegrationAuthenticationProvider<GitLabId> {
1619
constructor(
1720
container: Container,
21+
authenticationService: IntegrationAuthenticationService,
1822
protected readonly authProviderId: GitLabId,
1923
) {
20-
super(container);
24+
super(container, authenticationService);
2125
}
2226

2327
override async createSession(

0 commit comments

Comments
 (0)