Skip to content

Commit 1a8975c

Browse files
Enriches Azure autolinks on commits: issues and pull requests (#3996)
* Makes UI to request Auzure autolinks properly * Retrieves an issue from Azure * Retrieves and caches state-map for the current Azure project. * Retrieves a pull request from Azure * Provides more information about azure PR and issue types * Retrieves pull request for a branch in Azure DevOps to show in Home * Provides more information about azure PR and issue types * Improves pull request conversion and models * Updates typing * Updates isVSTS check --------- Co-authored-by: Ramin Tadayon <[email protected]>
1 parent c982edb commit 1a8975c

File tree

6 files changed

+952
-16
lines changed

6 files changed

+952
-16
lines changed

src/autolinks/autolinks.ts

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ import type { IntegrationId } from '../constants.integrations';
55
import { IssueIntegrationId } from '../constants.integrations';
66
import type { Container } from '../container';
77
import type { GitRemote } from '../git/models/remote';
8+
import type { RemoteProviderId } from '../git/remotes/remoteProvider';
89
import { getIssueOrPullRequestHtmlIcon, getIssueOrPullRequestMarkdownIcon } from '../git/utils/-webview/icons';
9-
import type { HostingIntegration, IssueIntegration } from '../plus/integrations/integration';
10+
import type { HostingIntegration, Integration, IssueIntegration } from '../plus/integrations/integration';
11+
import { IntegrationBase } from '../plus/integrations/integration';
12+
import { remoteProviderIdToIntegrationId } from '../plus/integrations/integrationService';
1013
import { configuration } from '../system/-webview/configuration';
1114
import { fromNow } from '../system/date';
1215
import { debug } from '../system/decorators/log';
@@ -214,9 +217,29 @@ export class Autolinks implements Disposable {
214217

215218
const enrichedAutolinks = new Map<string, EnrichedAutolink>();
216219
for (const [id, link] of messageOrAutolinks) {
217-
let linkIntegration = link.provider
218-
? await this.container.integrations.get(link.provider.id as IntegrationId)
219-
: undefined;
220+
let integrationId: IntegrationId | undefined;
221+
let linkIntegration: Integration | undefined;
222+
if (link.provider != null) {
223+
// Try to make a smart choice
224+
integrationId =
225+
link.provider instanceof IntegrationBase
226+
? link.provider.id
227+
: // TODO: Tighten the typing on ProviderReference to be specific to a remote provider, and then have a separate "integration" property (on autolinks and elsewhere)
228+
// that is of a new type IntegrationReference specific to integrations. Otherwise, make remote provider ids line up directly with integration ids.
229+
// Either way, this converting/casting hackery needs to go away.
230+
remoteProviderIdToIntegrationId(link.provider.id as RemoteProviderId);
231+
if (integrationId == null) {
232+
// Fall back to the old logic assuming that integration id might be saved as provider id.
233+
// TODO: it should be removed when we put providers and integrations in order. Conversation: https://github.com/gitkraken/vscode-gitlens/pull/3996#discussion_r1936422826
234+
integrationId = link.provider.id as IntegrationId;
235+
}
236+
try {
237+
linkIntegration = await this.container.integrations.get(integrationId);
238+
} catch (e) {
239+
Logger.error(e, `Failed to get integration for ${link.provider.id}`);
240+
linkIntegration = undefined;
241+
}
242+
}
220243
if (linkIntegration != null) {
221244
const connected = linkIntegration.maybeConnected ?? (await linkIntegration.isConnected());
222245
if (!connected || !(await linkIntegration.access())) {
@@ -226,7 +249,7 @@ export class Autolinks implements Disposable {
226249
const issueOrPullRequestPromise =
227250
remote?.provider != null &&
228251
integration != null &&
229-
link.provider?.id === integration.id &&
252+
integrationId === integration.id &&
230253
link.provider?.domain === integration.domain
231254
? integration.getIssueOrPullRequest(
232255
link.descriptor ?? remote.provider.repoDesc,

src/container.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import type { CloudIntegrationService } from './plus/integrations/authentication
3535
import { ConfiguredIntegrationService } from './plus/integrations/authentication/configuredIntegrationService';
3636
import { IntegrationAuthenticationService } from './plus/integrations/authentication/integrationAuthenticationService';
3737
import { IntegrationService } from './plus/integrations/integrationService';
38+
import type { AzureDevOpsApi } from './plus/integrations/providers/azure/azure';
3839
import type { GitHubApi } from './plus/integrations/providers/github/github';
3940
import type { GitLabApi } from './plus/integrations/providers/gitlab/gitlab';
4041
import { EnrichmentService } from './plus/launchpad/enrichmentService';
@@ -477,6 +478,28 @@ export class Container {
477478
return this._git;
478479
}
479480

481+
private _azure: Promise<AzureDevOpsApi | undefined> | undefined;
482+
get azure(): Promise<AzureDevOpsApi | undefined> {
483+
if (this._azure == null) {
484+
async function load(this: Container) {
485+
try {
486+
const azure = new (
487+
await import(/* webpackChunkName: "integrations" */ './plus/integrations/providers/azure/azure')
488+
).AzureDevOpsApi(this);
489+
this._disposables.push(azure);
490+
return azure;
491+
} catch (ex) {
492+
Logger.error(ex);
493+
return undefined;
494+
}
495+
}
496+
497+
this._azure = load.call(this);
498+
}
499+
500+
return this._azure;
501+
}
502+
480503
private _github: Promise<GitHubApi | undefined> | undefined;
481504
get github(): Promise<GitHubApi | undefined> {
482505
if (this._github == null) {

src/plus/integrations/integrationService.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,9 +1033,6 @@ export function remoteProviderIdToIntegrationId(
10331033
remoteProviderId: RemoteProviderId,
10341034
): SupportedCloudIntegrationIds | undefined {
10351035
switch (remoteProviderId) {
1036-
// TODO: Uncomment when we support these integrations
1037-
// case 'bitbucket':
1038-
// return HostingIntegrationId.Bitbucket;
10391036
case 'azure-devops':
10401037
return HostingIntegrationId.AzureDevOps;
10411038
case 'github':

0 commit comments

Comments
 (0)