Skip to content

Commit f1e29dc

Browse files
committed
Conects and syncs to AzureDevOps
(#3976, #3984)
1 parent d1f6477 commit f1e29dc

File tree

2 files changed

+9
-106
lines changed

2 files changed

+9
-106
lines changed

src/constants.integrations.ts

+7
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export const supportedOrderedCloudIntegrationIds = [
2929
SelfHostedIntegrationId.CloudGitHubEnterprise,
3030
HostingIntegrationId.GitLab,
3131
SelfHostedIntegrationId.CloudGitLabSelfHosted,
32+
HostingIntegrationId.AzureDevOps,
3233
IssueIntegrationId.Jira,
3334
];
3435

@@ -71,6 +72,12 @@ export const supportedCloudIntegrationDescriptors: IntegrationDescriptor[] = [
7172
icon: 'gl-provider-gitlab',
7273
supports: ['prs', 'issues'],
7374
},
75+
{
76+
id: HostingIntegrationId.AzureDevOps,
77+
name: 'Azure DevOps',
78+
icon: 'gl-provider-azdo',
79+
supports: ['prs', 'issues'],
80+
},
7481
{
7582
id: IssueIntegrationId.Jira,
7683
name: 'Jira',
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,8 @@
1-
import type { Disposable, QuickInputButton } from 'vscode';
2-
import { env, ThemeIcon, Uri, window } from 'vscode';
31
import { HostingIntegrationId } from '../../../constants.integrations';
4-
import { base64 } from '../../../system/string';
5-
import type { IntegrationAuthenticationSessionDescriptor } from './integrationAuthenticationProvider';
6-
import { LocalIntegrationAuthenticationProvider } from './integrationAuthenticationProvider';
7-
import type { ProviderAuthenticationSession } from './models';
2+
import { CloudIntegrationAuthenticationProvider } from './integrationAuthenticationProvider';
83

9-
export class AzureDevOpsAuthenticationProvider extends LocalIntegrationAuthenticationProvider<HostingIntegrationId.AzureDevOps> {
4+
export class AzureDevOpsAuthenticationProvider extends CloudIntegrationAuthenticationProvider<HostingIntegrationId.AzureDevOps> {
105
protected override get authProviderId(): HostingIntegrationId.AzureDevOps {
116
return HostingIntegrationId.AzureDevOps;
127
}
13-
14-
override async createSession(
15-
descriptor: IntegrationAuthenticationSessionDescriptor,
16-
): Promise<ProviderAuthenticationSession | undefined> {
17-
let azureOrganization: string | undefined = descriptor.organization as string | undefined;
18-
if (!azureOrganization) {
19-
const orgInput = window.createInputBox();
20-
orgInput.ignoreFocusOut = true;
21-
const orgInputDisposables: Disposable[] = [];
22-
try {
23-
azureOrganization = await new Promise<string | undefined>(resolve => {
24-
orgInputDisposables.push(
25-
orgInput.onDidHide(() => resolve(undefined)),
26-
orgInput.onDidChangeValue(() => (orgInput.validationMessage = undefined)),
27-
orgInput.onDidAccept(() => {
28-
const value = orgInput.value.trim();
29-
if (!value) {
30-
orgInput.validationMessage = 'An organization is required';
31-
return;
32-
}
33-
34-
resolve(value);
35-
}),
36-
);
37-
38-
orgInput.title = `Azure DevOps Authentication \u2022 ${descriptor.domain}`;
39-
orgInput.placeholder = 'Organization';
40-
orgInput.prompt = 'Enter your Azure DevOps organization';
41-
orgInput.show();
42-
});
43-
} finally {
44-
orgInput.dispose();
45-
orgInputDisposables.forEach(d => void d.dispose());
46-
}
47-
}
48-
49-
if (!azureOrganization) return undefined;
50-
51-
const tokenInput = window.createInputBox();
52-
tokenInput.ignoreFocusOut = true;
53-
54-
const disposables: Disposable[] = [];
55-
56-
let token;
57-
try {
58-
const infoButton: QuickInputButton = {
59-
iconPath: new ThemeIcon(`link-external`),
60-
tooltip: 'Open the Azure DevOps Access Tokens Page',
61-
};
62-
63-
token = await new Promise<string | undefined>(resolve => {
64-
disposables.push(
65-
tokenInput.onDidHide(() => resolve(undefined)),
66-
tokenInput.onDidChangeValue(() => (tokenInput.validationMessage = undefined)),
67-
tokenInput.onDidAccept(() => {
68-
const value = tokenInput.value.trim();
69-
if (!value) {
70-
tokenInput.validationMessage = 'A personal access token is required';
71-
return;
72-
}
73-
74-
resolve(value);
75-
}),
76-
tokenInput.onDidTriggerButton(e => {
77-
if (e === infoButton) {
78-
void env.openExternal(
79-
Uri.parse(`https://${descriptor.domain}/${azureOrganization}/_usersSettings/tokens`),
80-
);
81-
}
82-
}),
83-
);
84-
85-
tokenInput.password = true;
86-
tokenInput.title = `Azure DevOps Authentication \u2022 ${descriptor.domain}`;
87-
tokenInput.placeholder = `Requires ${descriptor.scopes.join(', ') ?? 'all'} scopes`;
88-
tokenInput.prompt = `Paste your [Azure DevOps Personal Access Token](https://${descriptor.domain}/${azureOrganization}/_usersSettings/tokens "Get your Azure DevOps Access Token")`;
89-
tokenInput.buttons = [infoButton];
90-
91-
tokenInput.show();
92-
});
93-
} finally {
94-
tokenInput.dispose();
95-
disposables.forEach(d => void d.dispose());
96-
}
97-
98-
if (!token) return undefined;
99-
100-
return {
101-
id: this.configuredIntegrationService.getSessionId(descriptor),
102-
accessToken: base64(`:${token}`),
103-
scopes: descriptor.scopes,
104-
account: {
105-
id: '',
106-
label: '',
107-
},
108-
cloud: false,
109-
domain: descriptor.domain,
110-
};
111-
}
1128
}

0 commit comments

Comments
 (0)