Merge pull request #7854 from awanlin/topic/add-build-by-definition-name
Added getting builds by definition name
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-azure-devops-backend': patch
|
||||
'@backstage/plugin-azure-devops-common': patch
|
||||
---
|
||||
|
||||
Added getting builds by definition name
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
```ts
|
||||
import { Build } from 'azure-devops-node-api/interfaces/BuildInterfaces';
|
||||
import { BuildDefinitionReference } from 'azure-devops-node-api/interfaces/BuildInterfaces';
|
||||
import { BuildRun } from '@backstage/plugin-azure-devops-common';
|
||||
import { Config } from '@backstage/config';
|
||||
import { DashboardPullRequest } from '@backstage/plugin-azure-devops-common';
|
||||
import express from 'express';
|
||||
@@ -23,12 +25,31 @@ export class AzureDevOpsApi {
|
||||
// (undocumented)
|
||||
getAllTeams(): Promise<Team[]>;
|
||||
// (undocumented)
|
||||
getBuildDefinitions(
|
||||
projectName: string,
|
||||
definitionName: string,
|
||||
): Promise<BuildDefinitionReference[]>;
|
||||
// (undocumented)
|
||||
getBuildList(
|
||||
projectName: string,
|
||||
repoId: string,
|
||||
top: number,
|
||||
): Promise<Build[]>;
|
||||
// (undocumented)
|
||||
getBuildRuns(
|
||||
projectName: string,
|
||||
top: number,
|
||||
repoName?: string,
|
||||
definitionName?: string,
|
||||
): Promise<BuildRun[]>;
|
||||
// (undocumented)
|
||||
getBuilds(
|
||||
projectName: string,
|
||||
top: number,
|
||||
repoId?: string,
|
||||
definitions?: number[],
|
||||
): Promise<Build[]>;
|
||||
// (undocumented)
|
||||
getDashboardPullRequests(
|
||||
projectName: string,
|
||||
options: PullRequestOptions,
|
||||
|
||||
@@ -29,277 +29,510 @@ import {
|
||||
GitPullRequest,
|
||||
GitRepository,
|
||||
} from 'azure-devops-node-api/interfaces/GitInterfaces';
|
||||
import { mappedPullRequest, mappedRepoBuild } from './AzureDevOpsApi';
|
||||
import {
|
||||
mappedBuildRun,
|
||||
mappedPullRequest,
|
||||
mappedRepoBuild,
|
||||
} from './AzureDevOpsApi';
|
||||
|
||||
import { IdentityRef } from 'azure-devops-node-api/interfaces/common/VSSInterfaces';
|
||||
|
||||
describe('AzureDevOpsApi', () => {
|
||||
describe('mappedRepoBuild', () => {
|
||||
it('should return RepoBuild from Build', () => {
|
||||
const inputBuildDefinition: DefinitionReference = {
|
||||
name: 'My Build Definition',
|
||||
};
|
||||
describe('mappedRepoBuild happy path', () => {
|
||||
it('should return RepoBuild from Build', () => {
|
||||
const inputBuildDefinition: DefinitionReference = {
|
||||
name: 'My Build Definition',
|
||||
};
|
||||
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: inputBuildDefinition,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: inputBuildDefinition,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'My Build Definition - Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'My Build Definition - Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedRepoBuild with no Build definition name', () => {
|
||||
it('should return RepoBuild with only Build Number for title', () => {
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
describe('mappedRepoBuild with no Build definition name', () => {
|
||||
it('should return RepoBuild with only Build Number for title', () => {
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedRepoBuild with undefined status', () => {
|
||||
it('should return BuildStatus of None for status', () => {
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
describe('mappedRepoBuild with undefined status', () => {
|
||||
it('should return BuildStatus of None for status', () => {
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: undefined,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: undefined,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.None,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.None,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedRepoBuild with undefined result', () => {
|
||||
it('should return BuildResult of None for result', () => {
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
describe('mappedRepoBuild with undefined result', () => {
|
||||
it('should return BuildResult of None for result', () => {
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.InProgress,
|
||||
result: undefined,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.InProgress,
|
||||
result: undefined,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.InProgress,
|
||||
result: BuildResult.None,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.InProgress,
|
||||
result: BuildResult.None,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedRepoBuild with undefined link', () => {
|
||||
it('should return empty string for link', () => {
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
describe('mappedRepoBuild with undefined link', () => {
|
||||
it('should return empty string for link', () => {
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.InProgress,
|
||||
result: undefined,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: undefined,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.InProgress,
|
||||
result: undefined,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: undefined,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: '',
|
||||
status: BuildStatus.InProgress,
|
||||
result: BuildResult.None,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: '',
|
||||
status: BuildStatus.InProgress,
|
||||
result: BuildResult.None,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
expect(mappedRepoBuild(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedPullRequest', () => {
|
||||
it('should return PullRequest from GitPullRequest', () => {
|
||||
const inputGitRepository: GitRepository = {
|
||||
name: 'super-feature-repo',
|
||||
};
|
||||
describe('mappedPullRequest happy path', () => {
|
||||
it('should return PullRequest from GitPullRequest', () => {
|
||||
const inputGitRepository: GitRepository = {
|
||||
name: 'super-feature-repo',
|
||||
};
|
||||
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputPullRequest: GitPullRequest = {
|
||||
pullRequestId: 7181,
|
||||
repository: inputGitRepository,
|
||||
title: 'My Awesome New Feature',
|
||||
createdBy: inputIdentityRef,
|
||||
creationDate: new Date('2020-09-12T06:10:23.932Z'),
|
||||
sourceRefName: 'refs/heads/topic/super-awesome-feature',
|
||||
targetRefName: 'refs/heads/main',
|
||||
status: PullRequestStatus.Active,
|
||||
isDraft: false,
|
||||
};
|
||||
const inputPullRequest: GitPullRequest = {
|
||||
pullRequestId: 7181,
|
||||
repository: inputGitRepository,
|
||||
title: 'My Awesome New Feature',
|
||||
createdBy: inputIdentityRef,
|
||||
creationDate: new Date('2020-09-12T06:10:23.932Z'),
|
||||
sourceRefName: 'refs/heads/topic/super-awesome-feature',
|
||||
targetRefName: 'refs/heads/main',
|
||||
status: PullRequestStatus.Active,
|
||||
isDraft: false,
|
||||
};
|
||||
|
||||
const inputBaseUrl =
|
||||
'https://host.com/myOrg/_git/super-feature-repo/pullrequest';
|
||||
const inputBaseUrl =
|
||||
'https://host.com/myOrg/_git/super-feature-repo/pullrequest';
|
||||
|
||||
const outputPullRequest: PullRequest = {
|
||||
pullRequestId: 7181,
|
||||
repoName: 'super-feature-repo',
|
||||
title: 'My Awesome New Feature',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
createdBy: 'Jane Doe',
|
||||
creationDate: '2020-09-12T06:10:23.932Z',
|
||||
sourceRefName: 'refs/heads/topic/super-awesome-feature',
|
||||
targetRefName: 'refs/heads/main',
|
||||
status: PullRequestStatus.Active,
|
||||
isDraft: false,
|
||||
link: 'https://host.com/myOrg/_git/super-feature-repo/pullrequest/7181',
|
||||
};
|
||||
const outputPullRequest: PullRequest = {
|
||||
pullRequestId: 7181,
|
||||
repoName: 'super-feature-repo',
|
||||
title: 'My Awesome New Feature',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
createdBy: 'Jane Doe',
|
||||
creationDate: '2020-09-12T06:10:23.932Z',
|
||||
sourceRefName: 'refs/heads/topic/super-awesome-feature',
|
||||
targetRefName: 'refs/heads/main',
|
||||
status: PullRequestStatus.Active,
|
||||
isDraft: false,
|
||||
link: 'https://host.com/myOrg/_git/super-feature-repo/pullrequest/7181',
|
||||
};
|
||||
|
||||
expect(mappedPullRequest(inputPullRequest, inputBaseUrl)).toEqual(
|
||||
outputPullRequest,
|
||||
);
|
||||
expect(mappedPullRequest(inputPullRequest, inputBaseUrl)).toEqual(
|
||||
outputPullRequest,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedBuildRun', () => {
|
||||
describe('mappedBuildRun happy path', () => {
|
||||
it('should return RepoBuild from Build', () => {
|
||||
const inputBuildDefinition: DefinitionReference = {
|
||||
name: 'My Build Definition',
|
||||
};
|
||||
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: inputBuildDefinition,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'My Build Definition - Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedBuildRun(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedBuildRun with no Build definition name', () => {
|
||||
it('should return RepoBuild with only Build Number for title', () => {
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedBuildRun(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedBuildRun with undefined status', () => {
|
||||
it('should return BuildStatus of None for status', () => {
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: undefined,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.None,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedBuildRun(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedBuildRun with undefined result', () => {
|
||||
it('should return BuildResult of None for result', () => {
|
||||
const inputLinks: any = {
|
||||
web: {
|
||||
href: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
},
|
||||
};
|
||||
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.InProgress,
|
||||
result: undefined,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: inputLinks,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.InProgress,
|
||||
result: BuildResult.None,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedBuildRun(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mappedBuildRun with undefined link', () => {
|
||||
it('should return empty string for link', () => {
|
||||
const inputIdentityRef: IdentityRef = {
|
||||
displayName: 'Jane Doe',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
const inputBuild: Build = {
|
||||
id: 1,
|
||||
buildNumber: 'Build-1',
|
||||
status: BuildStatus.InProgress,
|
||||
result: undefined,
|
||||
queueTime: new Date('2020-09-12T06:10:23.932Z'),
|
||||
startTime: new Date('2020-09-12T06:15:23.932Z'),
|
||||
finishTime: new Date('2020-09-12T06:20:23.932Z'),
|
||||
sourceBranch: 'refs/heads/develop',
|
||||
sourceVersion: 'f4f78b3100b2923982bdf60c89c57ce6fd2d9a1c',
|
||||
definition: undefined,
|
||||
_links: undefined,
|
||||
requestedFor: inputIdentityRef,
|
||||
};
|
||||
|
||||
const outputRepoBuild: RepoBuild = {
|
||||
id: 1,
|
||||
title: 'Build-1',
|
||||
link: '',
|
||||
status: BuildStatus.InProgress,
|
||||
result: BuildResult.None,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
startTime: '2020-09-12T06:15:23.932Z',
|
||||
finishTime: '2020-09-12T06:20:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
uniqueName: 'DOMAIN\\jdoe',
|
||||
};
|
||||
|
||||
expect(mappedBuildRun(inputBuild)).toEqual(outputRepoBuild);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,8 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Build,
|
||||
BuildDefinitionReference,
|
||||
} from 'azure-devops-node-api/interfaces/BuildInterfaces';
|
||||
import {
|
||||
BuildResult,
|
||||
BuildRun,
|
||||
BuildStatus,
|
||||
DashboardPullRequest,
|
||||
Policy,
|
||||
@@ -35,7 +40,6 @@ import {
|
||||
getArtifactId,
|
||||
} from '../utils';
|
||||
|
||||
import { Build } from 'azure-devops-node-api/interfaces/BuildInterfaces';
|
||||
import { Logger } from 'winston';
|
||||
import { PolicyEvaluationRecord } from 'azure-devops-node-api/interfaces/PolicyInterfaces';
|
||||
import { TeamMember } from 'azure-devops-node-api/interfaces/common/VSSInterfaces';
|
||||
@@ -258,6 +262,85 @@ export class AzureDevOpsApi {
|
||||
.map(teamMember => teamMember.identity?.id)
|
||||
.filter((id): id is string => Boolean(id));
|
||||
}
|
||||
|
||||
public async getBuildDefinitions(
|
||||
projectName: string,
|
||||
definitionName: string,
|
||||
): Promise<BuildDefinitionReference[]> {
|
||||
this.logger?.debug(
|
||||
`Calling Azure DevOps REST API, getting Build Definitions for ${definitionName} in Project ${projectName}`,
|
||||
);
|
||||
|
||||
const client = await this.webApi.getBuildApi();
|
||||
return client.getDefinitions(projectName, definitionName);
|
||||
}
|
||||
|
||||
public async getBuilds(
|
||||
projectName: string,
|
||||
top: number,
|
||||
repoId?: string,
|
||||
definitions?: number[],
|
||||
): Promise<Build[]> {
|
||||
this.logger?.debug(
|
||||
`Calling Azure DevOps REST API, getting up to ${top} Builds for Repository Id ${repoId} for Project ${projectName}`,
|
||||
);
|
||||
|
||||
const client = await this.webApi.getBuildApi();
|
||||
return client.getBuilds(
|
||||
projectName,
|
||||
definitions,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
top,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
repoId,
|
||||
repoId ? 'TfsGit' : undefined,
|
||||
);
|
||||
}
|
||||
|
||||
public async getBuildRuns(
|
||||
projectName: string,
|
||||
top: number,
|
||||
repoName?: string,
|
||||
definitionName?: string,
|
||||
) {
|
||||
let repoId: string | undefined;
|
||||
let definitions: number[] | undefined;
|
||||
|
||||
if (repoName) {
|
||||
const gitRepository = await this.getGitRepository(projectName, repoName);
|
||||
repoId = gitRepository.id;
|
||||
}
|
||||
|
||||
if (definitionName) {
|
||||
const buildDefinitions = await this.getBuildDefinitions(
|
||||
projectName,
|
||||
definitionName,
|
||||
);
|
||||
definitions = buildDefinitions
|
||||
.map(bd => bd.id)
|
||||
.filter((bd): bd is number => Boolean(bd));
|
||||
}
|
||||
|
||||
const builds = await this.getBuilds(projectName, top, repoId, definitions);
|
||||
|
||||
const buildRuns: BuildRun[] = builds.map(mappedBuildRun);
|
||||
|
||||
return buildRuns;
|
||||
}
|
||||
}
|
||||
|
||||
export function mappedRepoBuild(build: Build): RepoBuild {
|
||||
@@ -295,3 +378,20 @@ export function mappedPullRequest(
|
||||
link: `${linkBaseUrl}/${pullRequest.pullRequestId}`,
|
||||
};
|
||||
}
|
||||
|
||||
export function mappedBuildRun(build: Build): BuildRun {
|
||||
return {
|
||||
id: build.id,
|
||||
title: [build.definition?.name, build.buildNumber]
|
||||
.filter(Boolean)
|
||||
.join(' - '),
|
||||
link: build._links?.web.href ?? '',
|
||||
status: build.status ?? BuildStatus.None,
|
||||
result: build.result ?? BuildResult.None,
|
||||
queueTime: build.queueTime?.toISOString(),
|
||||
startTime: build.startTime?.toISOString(),
|
||||
finishTime: build.finishTime?.toISOString(),
|
||||
source: `${build.sourceBranch} (${build.sourceVersion?.substr(0, 8)})`,
|
||||
uniqueName: build.requestedFor?.uniqueName ?? 'N/A',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -14,8 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Build,
|
||||
BuildDefinitionReference,
|
||||
} from 'azure-devops-node-api/interfaces/BuildInterfaces';
|
||||
import {
|
||||
BuildResult,
|
||||
BuildRun,
|
||||
BuildStatus,
|
||||
PullRequest,
|
||||
PullRequestStatus,
|
||||
@@ -23,7 +28,6 @@ import {
|
||||
} from '@backstage/plugin-azure-devops-common';
|
||||
|
||||
import { AzureDevOpsApi } from '../api';
|
||||
import { Build } from 'azure-devops-node-api/interfaces/BuildInterfaces';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { GitRepository } from 'azure-devops-node-api/interfaces/GitInterfaces';
|
||||
import { createRouter } from './router';
|
||||
@@ -39,8 +43,12 @@ describe('createRouter', () => {
|
||||
azureDevOpsApi = {
|
||||
getGitRepository: jest.fn(),
|
||||
getBuildList: jest.fn(),
|
||||
getBuildDefinitions: jest.fn(),
|
||||
getRepoBuilds: jest.fn(),
|
||||
getDefinitionBuilds: jest.fn(),
|
||||
getPullRequests: jest.fn(),
|
||||
getBuilds: jest.fn(),
|
||||
getBuildRuns: jest.fn(),
|
||||
} as any;
|
||||
const router = await createRouter({
|
||||
azureDevOpsApi,
|
||||
@@ -260,4 +268,142 @@ describe('createRouter', () => {
|
||||
expect(response.body).toEqual(pullRequests);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /build-definitions/:projectName/:definitionName', () => {
|
||||
it('fetches a list of build definitions', async () => {
|
||||
const inputDefinition: BuildDefinitionReference = {
|
||||
id: 1,
|
||||
name: 'myBuildDefinition',
|
||||
};
|
||||
|
||||
const inputDefinitions: BuildDefinitionReference[] = [inputDefinition];
|
||||
|
||||
azureDevOpsApi.getBuildDefinitions.mockResolvedValueOnce(
|
||||
inputDefinitions,
|
||||
);
|
||||
|
||||
const response = await request(app).get(
|
||||
'/build-definitions/myProject/myBuildDefinition',
|
||||
);
|
||||
|
||||
expect(azureDevOpsApi.getBuildDefinitions).toHaveBeenCalledWith(
|
||||
'myProject',
|
||||
'myBuildDefinition',
|
||||
);
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toEqual(inputDefinitions);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /builds/:projectName', () => {
|
||||
describe('GET /builds/:projectName with repoName', () => {
|
||||
it('fetches a list of build runs using repoName', async () => {
|
||||
const firstBuildRun: BuildRun = {
|
||||
id: 1,
|
||||
title: 'My Build Definition - Build 1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.PartiallySucceeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
};
|
||||
|
||||
const secondBuildRun: BuildRun = {
|
||||
id: 2,
|
||||
title: 'My Build Definition - Build 2',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=2',
|
||||
status: BuildStatus.InProgress,
|
||||
result: BuildResult.None,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
source: 'refs/heads/develop (13c988d4)',
|
||||
};
|
||||
|
||||
const thirdBuildRun: BuildRun = {
|
||||
id: 3,
|
||||
title: 'My Build Definition - Build 3',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=3',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
source: 'refs/heads/develop (9bedf678)',
|
||||
};
|
||||
|
||||
const buildRuns: BuildRun[] = [
|
||||
firstBuildRun,
|
||||
secondBuildRun,
|
||||
thirdBuildRun,
|
||||
];
|
||||
|
||||
azureDevOpsApi.getBuildRuns.mockResolvedValueOnce(buildRuns);
|
||||
|
||||
const response = await request(app)
|
||||
.get('/builds/myProject')
|
||||
.query({ top: '50', repoName: 'myRepo' });
|
||||
|
||||
expect(azureDevOpsApi.getBuildRuns).toHaveBeenCalledWith(
|
||||
'myProject',
|
||||
50,
|
||||
'myRepo',
|
||||
undefined,
|
||||
);
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toEqual(buildRuns);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /builds/:projectName with definitionName', () => {
|
||||
it('fetches a list of build runs using definitionName', async () => {
|
||||
const firstBuildRun: BuildRun = {
|
||||
id: 1,
|
||||
title: 'My Build Definition - Build 1',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=1',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.PartiallySucceeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
source: 'refs/heads/develop (f4f78b31)',
|
||||
};
|
||||
|
||||
const secondBuildRun: BuildRun = {
|
||||
id: 2,
|
||||
title: 'My Build Definition - Build 2',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=2',
|
||||
status: BuildStatus.InProgress,
|
||||
result: BuildResult.None,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
source: 'refs/heads/develop (13c988d4)',
|
||||
};
|
||||
|
||||
const thirdBuildRun: BuildRun = {
|
||||
id: 3,
|
||||
title: 'My Build Definition - Build 3',
|
||||
link: 'https://host.com/myOrg/0bcc0c0d-2d02/_build/results?buildId=3',
|
||||
status: BuildStatus.Completed,
|
||||
result: BuildResult.Succeeded,
|
||||
queueTime: '2020-09-12T06:10:23.932Z',
|
||||
source: 'refs/heads/develop (9bedf678)',
|
||||
};
|
||||
|
||||
const buildRuns: BuildRun[] = [
|
||||
firstBuildRun,
|
||||
secondBuildRun,
|
||||
thirdBuildRun,
|
||||
];
|
||||
|
||||
azureDevOpsApi.getBuildRuns.mockResolvedValueOnce(buildRuns);
|
||||
|
||||
const response = await request(app)
|
||||
.get('/builds/myProject')
|
||||
.query({ top: '50', definitionName: 'myDefinition' });
|
||||
|
||||
expect(azureDevOpsApi.getBuildRuns).toHaveBeenCalledWith(
|
||||
'myProject',
|
||||
50,
|
||||
undefined,
|
||||
'myDefinition',
|
||||
);
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toEqual(buildRuns);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -144,6 +144,32 @@ export async function createRouter(
|
||||
res.status(200).json(allTeams);
|
||||
});
|
||||
|
||||
router.get(
|
||||
'/build-definitions/:projectName/:definitionName',
|
||||
async (req, res) => {
|
||||
const { projectName, definitionName } = req.params;
|
||||
const buildDefinitionList = await azureDevOpsApi.getBuildDefinitions(
|
||||
projectName,
|
||||
definitionName,
|
||||
);
|
||||
res.status(200).json(buildDefinitionList);
|
||||
},
|
||||
);
|
||||
|
||||
router.get('/builds/:projectName', async (req, res) => {
|
||||
const { projectName } = req.params;
|
||||
const repoName = req.query.repoName?.toString();
|
||||
const definitionName = req.query.definitionName?.toString();
|
||||
const top = req.query.top ? Number(req.query.top) : DEFAULT_TOP;
|
||||
const builds = await azureDevOpsApi.getBuildRuns(
|
||||
projectName,
|
||||
top,
|
||||
repoName,
|
||||
definitionName,
|
||||
);
|
||||
res.status(200).json(builds);
|
||||
});
|
||||
|
||||
router.use(errorHandler());
|
||||
return router;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,29 @@ export enum BuildResult {
|
||||
Succeeded = 2,
|
||||
}
|
||||
|
||||
// Warning: (ae-missing-release-tag) "BuildRun" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export type BuildRun = {
|
||||
id?: number;
|
||||
title: string;
|
||||
link?: string;
|
||||
status?: BuildStatus;
|
||||
result?: BuildResult;
|
||||
queueTime?: string;
|
||||
startTime?: string;
|
||||
finishTime?: string;
|
||||
source: string;
|
||||
uniqueName?: string;
|
||||
};
|
||||
|
||||
// Warning: (ae-missing-release-tag) "BuildRunOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export type BuildRunOptions = {
|
||||
top?: number;
|
||||
};
|
||||
|
||||
// Warning: (ae-missing-release-tag) "BuildStatus" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
|
||||
@@ -251,3 +251,19 @@ export enum PullRequestVoteStatus {
|
||||
WaitingForAuthor = -5,
|
||||
Rejected = -10,
|
||||
}
|
||||
export type BuildRun = {
|
||||
id?: number;
|
||||
title: string;
|
||||
link?: string;
|
||||
status?: BuildStatus;
|
||||
result?: BuildResult;
|
||||
queueTime?: string;
|
||||
startTime?: string;
|
||||
finishTime?: string;
|
||||
source: string;
|
||||
uniqueName?: string;
|
||||
};
|
||||
|
||||
export type BuildRunOptions = {
|
||||
top?: number;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user