Skip to content

Commit 97a1f4a

Browse files
sergeibbbaxosoft-ramint
authored andcommitted
Implements getAccountForCommit for AzureDevOps
(#4192, #4243)
1 parent 18f5d25 commit 97a1f4a

File tree

3 files changed

+100
-7
lines changed

3 files changed

+100
-7
lines changed

src/plus/integrations/providers/azure/azure.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
RequestClientError,
1414
RequestNotFoundError,
1515
} from '../../../../errors';
16+
import type { UnidentifiedAuthor } from '../../../../git/models/author';
1617
import type { Issue } from '../../../../git/models/issue';
1718
import type { IssueOrPullRequest } from '../../../../git/models/issueOrPullRequest';
1819
import type { PullRequest } from '../../../../git/models/pullRequest';
@@ -26,6 +27,7 @@ import { getLogScope } from '../../../../system/logger.scope';
2627
import { maybeStopWatch } from '../../../../system/stopwatch';
2728
import { base64 } from '../../../../system/string';
2829
import type {
30+
AzureGitCommit,
2931
AzureProjectDescriptor,
3032
AzurePullRequest,
3133
AzurePullRequestWithLinks,
@@ -313,6 +315,56 @@ export class AzureDevOpsApi implements Disposable {
313315
return undefined;
314316
}
315317

318+
@debug<AzureDevOpsApi['getAccountForCommit']>({ args: { 0: p => p.name, 1: '<token>' } })
319+
async getAccountForCommit(
320+
provider: Provider,
321+
token: string,
322+
owner: string,
323+
repo: string,
324+
rev: string,
325+
baseUrl: string,
326+
_options?: {
327+
avatarSize?: number;
328+
},
329+
): Promise<UnidentifiedAuthor | undefined> {
330+
const scope = getLogScope();
331+
const [projectName, _, repoName] = repo.split('/');
332+
333+
try {
334+
// Try to get the Work item (wit) first with specific fields
335+
const commit = await this.request<AzureGitCommit>(
336+
provider,
337+
token,
338+
baseUrl,
339+
`${owner}/${projectName}/_apis/git/repositories/${repoName}/commits/${rev}`,
340+
{
341+
method: 'GET',
342+
},
343+
scope,
344+
);
345+
const author = commit?.author;
346+
if (!author) {
347+
return undefined;
348+
}
349+
// Azure API never gives us an id/username we can use, therefore we always return UnidentifiedAuthor
350+
return {
351+
provider: provider,
352+
id: undefined,
353+
username: undefined,
354+
name: author?.name,
355+
email: author?.email,
356+
avatarUrl: undefined,
357+
} satisfies UnidentifiedAuthor;
358+
} catch (ex) {
359+
if (ex.original?.status !== 404) {
360+
Logger.error(ex, scope);
361+
return undefined;
362+
}
363+
}
364+
365+
return undefined;
366+
}
367+
316368
async getWorkItemStateCategory(
317369
issueType: string,
318370
state: string,

src/plus/integrations/providers/azure/models.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,11 +202,44 @@ export interface AzureRepository {
202202
isInMaintenance: boolean;
203203
}
204204

205+
export interface AzureGitUser {
206+
date?: string;
207+
email?: string;
208+
imageUrl?: string;
209+
name: string;
210+
}
211+
205212
export interface AzureGitCommitRef {
206213
commitId: string;
207214
url: string;
208215
}
209216

217+
export interface AzureGitCommit {
218+
_links: {
219+
changes: AzureLink;
220+
repository: AzureLink;
221+
self: AzureLink;
222+
web: AzureLink;
223+
};
224+
author: AzureGitUser;
225+
comment: string;
226+
commentTruncated?: boolean;
227+
commitId: string;
228+
commitTooManyChanges?: boolean;
229+
committer: AzureGitUser;
230+
parents: string[];
231+
push: {
232+
date: string;
233+
pushedBy: AzureUser;
234+
pushId: number;
235+
};
236+
remoteUrl: string;
237+
statuses?: AzureGitStatus[];
238+
treeId: string;
239+
url: string;
240+
workItems?: AzureResourceRef[];
241+
}
242+
210243
export interface AzureResourceRef {
211244
id: string;
212245
url: string;

src/plus/integrations/providers/azureDevOps.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { AuthenticationSession, CancellationToken } from 'vscode';
22
import { window } from 'vscode';
33
import { HostingIntegrationId } from '../../../constants.integrations';
4-
import type { Account } from '../../../git/models/author';
4+
import type { Account, UnidentifiedAuthor } from '../../../git/models/author';
55
import type { DefaultBranch } from '../../../git/models/defaultBranch';
66
import type { Issue, IssueShape } from '../../../git/models/issue';
77
import type { IssueOrPullRequest } from '../../../git/models/issueOrPullRequest';
@@ -227,14 +227,22 @@ export class AzureDevOpsIntegration extends HostingIntegration<
227227
}
228228

229229
protected override async getProviderAccountForCommit(
230-
_session: AuthenticationSession,
231-
_repo: AzureRepositoryDescriptor,
232-
_rev: string,
233-
_options?: {
230+
{ accessToken }: AuthenticationSession,
231+
repo: AzureRepositoryDescriptor,
232+
rev: string,
233+
options?: {
234234
avatarSize?: number;
235235
},
236-
): Promise<Account | undefined> {
237-
return Promise.resolve(undefined);
236+
): Promise<UnidentifiedAuthor | undefined> {
237+
return (await this.container.azure)?.getAccountForCommit(
238+
this,
239+
accessToken,
240+
repo.owner,
241+
repo.name,
242+
rev,
243+
this.apiBaseUrl,
244+
options,
245+
);
238246
}
239247

240248
protected override async getProviderAccountForEmail(

0 commit comments

Comments
 (0)