Skip to content
This repository was archived by the owner on Apr 13, 2020. It is now read-only.

Commit 4fd7e27

Browse files
authored
[FEATURE] spk setup - create HLD to Manifest pipeline (#374)
* [FEATURE] spk setup - create HLD to Manifest pipeline * add jsDoc
1 parent ca3adb9 commit 4fd7e27

10 files changed

+511
-3
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,6 @@ jspm_packages/
9696

9797
# Local XUnit test results
9898
junit.xml
99+
100+
# quick-start-temp-folder
101+
quick-start-env/

src/commands/setup.test.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { createTempDir } from "../lib/ioUtil";
66
import { WORKSPACE } from "../lib/setup/constants";
77
import * as fsUtil from "../lib/setup/fsUtil";
88
import * as gitService from "../lib/setup/gitService";
9+
import * as pipelineService from "../lib/setup/pipelineService";
910
import * as projectService from "../lib/setup/projectService";
1011
import * as promptInstance from "../lib/setup/prompt";
1112
import * as scaffold from "../lib/setup/scaffold";
@@ -42,6 +43,9 @@ const testExecuteFunc = async (usePrompt = true, hasProject = true) => {
4243
jest.spyOn(fsUtil, "createDirectory").mockReturnValueOnce();
4344
jest.spyOn(scaffold, "hldRepo").mockReturnValueOnce(Promise.resolve());
4445
jest.spyOn(scaffold, "manifestRepo").mockReturnValueOnce(Promise.resolve());
46+
jest
47+
.spyOn(pipelineService, "createHLDtoManifestPipeline")
48+
.mockReturnValueOnce(Promise.resolve());
4549
jest.spyOn(setupLog, "create").mockReturnValueOnce();
4650

4751
const exitFn = jest.fn();
@@ -63,6 +67,9 @@ const testExecuteFunc = async (usePrompt = true, hasProject = true) => {
6367
}
6468
} as any)
6569
);
70+
jest
71+
.spyOn(azdoClient, "getBuildApi")
72+
.mockReturnValueOnce(Promise.resolve({} as any));
6673
if (hasProject) {
6774
jest
6875
.spyOn(projectService, "getProject")
@@ -117,7 +124,6 @@ describe("test execute function", () => {
117124
});
118125
it("negative test: 401 status code", async () => {
119126
const exitFn = jest.fn();
120-
121127
jest
122128
.spyOn(promptInstance, "prompt")
123129
.mockReturnValueOnce(Promise.resolve(mockRequestContext));

src/commands/setup.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ import commander from "commander";
22
import fs from "fs";
33
import yaml from "js-yaml";
44
import { defaultConfigFile } from "../config";
5-
import { getWebApi } from "../lib/azdoClient";
5+
import { getBuildApi, getWebApi } from "../lib/azdoClient";
66
import { build as buildCmd, exit as exitCmd } from "../lib/commandBuilder";
77
import { IRequestContext, WORKSPACE } from "../lib/setup/constants";
88
import { createDirectory } from "../lib/setup/fsUtil";
99
import { getGitApi } from "../lib/setup/gitService";
10+
import { createHLDtoManifestPipeline } from "../lib/setup/pipelineService";
1011
import { createProjectIfNotExist } from "../lib/setup/projectService";
1112
import { getAnswerFromFile, prompt } from "../lib/setup/prompt";
1213
import { hldRepo, manifestRepo } from "../lib/setup/scaffold";
@@ -78,10 +79,12 @@ export const execute = async (
7879
const webAPI = await getWebApi();
7980
const coreAPI = await webAPI.getCoreApi();
8081
const gitAPI = await getGitApi(webAPI);
82+
const buildAPI = await getBuildApi();
8183

8284
await createProjectIfNotExist(coreAPI, requestContext);
8385
await hldRepo(gitAPI, requestContext);
8486
await manifestRepo(gitAPI, requestContext);
87+
await createHLDtoManifestPipeline(buildAPI, requestContext);
8588

8689
createSetupLog(requestContext);
8790
await exitFn(0);

src/lib/setup/constants.ts

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export interface IRequestContext {
66
createdProject?: boolean;
77
scaffoldHLD?: boolean;
88
scaffoldManifest?: boolean;
9+
createdHLDtoManifestPipeline?: boolean;
910
error?: string;
1011
}
1112

src/lib/setup/gitService.test.ts

+9
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
createRepo,
77
createRepoInAzureOrg,
88
deleteRepo,
9+
getAzureRepoUrl,
910
getGitApi,
1011
getRepoInAzureOrg,
1112
getRepoURL
@@ -19,6 +20,14 @@ const mockRequestContext = {
1920
workspace: WORKSPACE
2021
};
2122

23+
describe("test getAzureRepoUrl function", () => {
24+
it("sanity test", () => {
25+
expect(getAzureRepoUrl("org", "project", "repo")).toBe(
26+
"https://dev.azure.com/org/project/_git/repo"
27+
);
28+
});
29+
});
30+
2231
describe("test getGitApi function", () => {
2332
it("mocked webAPI", async () => {
2433
await getGitApi({

src/lib/setup/gitService.ts

+15
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,21 @@ export const getGitApi = async (webAPI: WebApi): Promise<IGitApi> => {
1818
return gitAPI!;
1919
};
2020

21+
/**
22+
* Returns azure git URL.
23+
*
24+
* @param orgName Organization name
25+
* @param projectName Project name
26+
* @param repoName Repo name
27+
*/
28+
export const getAzureRepoUrl = (
29+
orgName: string,
30+
projectName: string,
31+
repoName: string
32+
): string => {
33+
return `https://dev.azure.com/${orgName}/${projectName}/_git/${repoName}`;
34+
};
35+
2136
/**
2237
* Creates git repo
2338
*

src/lib/setup/pipelineService.test.ts

+271
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
import { BuildStatus } from "azure-devops-node-api/interfaces/BuildInterfaces";
2+
import * as hldPipeline from "../../commands/hld/pipeline";
3+
import { deepClone } from "../util";
4+
import { IRequestContext, WORKSPACE } from "./constants";
5+
import {
6+
createHLDtoManifestPipeline,
7+
deletePipeline,
8+
getBuildStatusString,
9+
getPipelineBuild,
10+
getPipelineByName,
11+
pollForPipelineStatus
12+
} from "./pipelineService";
13+
import * as pipelineService from "./pipelineService";
14+
15+
const mockRequestContext: IRequestContext = {
16+
accessToken: "pat",
17+
orgName: "orgname",
18+
projectName: "project",
19+
workspace: WORKSPACE
20+
};
21+
22+
const getMockRequestContext = (): IRequestContext => {
23+
return deepClone(mockRequestContext);
24+
};
25+
26+
describe("test getBuildStatusString function", () => {
27+
it("sanity test", () => {
28+
const results = [
29+
"None",
30+
"In Progress",
31+
"Completed",
32+
"Cancelling",
33+
"Postponed",
34+
"Not Started"
35+
];
36+
37+
[
38+
BuildStatus.None,
39+
BuildStatus.InProgress,
40+
BuildStatus.Completed,
41+
BuildStatus.Cancelling,
42+
BuildStatus.Postponed,
43+
BuildStatus.NotStarted
44+
].forEach((s, i) => {
45+
expect(getBuildStatusString(s)).toBe(results[i]);
46+
});
47+
});
48+
it("sanity test: unknown", () => {
49+
expect(getBuildStatusString(BuildStatus.All)).toBe("Unknown");
50+
expect(getBuildStatusString(undefined)).toBe("Unknown");
51+
});
52+
});
53+
54+
describe("test getPipelineByName function", () => {
55+
it("sanity test: pipeline is not found", async () => {
56+
const p = await getPipelineByName(
57+
{
58+
getDefinitions: (projectName: string) => {
59+
return [];
60+
}
61+
} as any,
62+
"project",
63+
"pipeline"
64+
);
65+
expect(p).not.toBeDefined();
66+
});
67+
it("sanity test: pipeline exists", async () => {
68+
const p = await getPipelineByName(
69+
{
70+
getDefinitions: (projectName: string) => {
71+
return [
72+
{
73+
name: "pipeline"
74+
}
75+
];
76+
}
77+
} as any,
78+
"project",
79+
"pipeline"
80+
);
81+
expect(p).toBeDefined();
82+
});
83+
it("sanity test: multiple pipelines and none matches", async () => {
84+
const p = await getPipelineByName(
85+
{
86+
getDefinitions: (projectName: string) => {
87+
return [
88+
{
89+
name: "pipeline1"
90+
},
91+
{
92+
name: "pipeline2"
93+
},
94+
{
95+
name: "pipeline3"
96+
}
97+
];
98+
}
99+
} as any,
100+
"project",
101+
"pipeline"
102+
);
103+
expect(p).not.toBeDefined();
104+
});
105+
it("sanity test: multiple pipelines and one matches", async () => {
106+
const p = await getPipelineByName(
107+
{
108+
getDefinitions: (projectName: string) => {
109+
return [
110+
{
111+
name: "pipeline"
112+
},
113+
{
114+
name: "pipeline2"
115+
},
116+
{
117+
name: "pipeline3"
118+
}
119+
];
120+
}
121+
} as any,
122+
"project",
123+
"pipeline"
124+
);
125+
expect(p).toBeDefined();
126+
});
127+
it("negative test: exception thrown", async () => {
128+
await expect(
129+
getPipelineByName(
130+
{
131+
getDefinitions: (projectName: string) => {
132+
throw Error("fake");
133+
}
134+
} as any,
135+
"project",
136+
"pipeline"
137+
)
138+
).rejects.toThrow();
139+
});
140+
});
141+
142+
describe("test deletePipeline function", () => {
143+
it("sanity test", async () => {
144+
await deletePipeline(
145+
{
146+
deleteDefinition: jest.fn
147+
} as any,
148+
"project",
149+
"pipeline",
150+
1
151+
);
152+
});
153+
it("negative test: exception thrown", async () => {
154+
await expect(
155+
deletePipeline(
156+
{
157+
deleteDefinition: () => {
158+
throw Error("Fake");
159+
}
160+
} as any,
161+
"project",
162+
"pipeline",
163+
1
164+
)
165+
).rejects.toThrow();
166+
});
167+
});
168+
169+
describe("test getPipelineBuild function", () => {
170+
it("sanity test", async () => {
171+
const res = await getPipelineBuild(
172+
{
173+
getLatestBuild: () => {
174+
return {};
175+
}
176+
} as any,
177+
"project",
178+
"pipeline"
179+
);
180+
expect(res).toBeDefined();
181+
});
182+
it("negative test: exception thrown", async () => {
183+
await await expect(
184+
getPipelineBuild(
185+
{
186+
getLatestBuild: () => {
187+
throw Error("Fake");
188+
}
189+
} as any,
190+
"project",
191+
"pipeline"
192+
)
193+
).rejects.toThrow();
194+
});
195+
});
196+
197+
describe("test pollForPipelineStatus function", () => {
198+
it("sanity test", async () => {
199+
jest
200+
.spyOn(pipelineService, "getPipelineByName")
201+
.mockReturnValueOnce(Promise.resolve({}));
202+
jest.spyOn(pipelineService, "getPipelineBuild").mockReturnValueOnce(
203+
Promise.resolve({
204+
status: 1
205+
})
206+
);
207+
208+
await pollForPipelineStatus({} as any, "project", "pipeline", 10);
209+
});
210+
it("negative test: pipeline does not exits", async () => {
211+
jest
212+
.spyOn(pipelineService, "getPipelineByName")
213+
.mockReturnValueOnce(Promise.resolve(undefined));
214+
await expect(
215+
pollForPipelineStatus({} as any, "project", "pipeline", 10)
216+
).rejects.toThrow();
217+
});
218+
it("negative test: getPipelineByName function throws exception", async () => {
219+
jest
220+
.spyOn(pipelineService, "getPipelineByName")
221+
.mockReturnValueOnce(Promise.reject(Error("fake")));
222+
await expect(
223+
pollForPipelineStatus({} as any, "project", "pipeline", 1)
224+
).rejects.toThrow();
225+
});
226+
});
227+
228+
describe("test createHLDtoManifestPipeline function", () => {
229+
it("positive test: pipeline does not exist previously", async () => {
230+
jest
231+
.spyOn(pipelineService, "getPipelineByName")
232+
.mockReturnValueOnce(Promise.resolve(undefined));
233+
jest
234+
.spyOn(hldPipeline, "installHldToManifestPipeline")
235+
.mockReturnValueOnce(Promise.resolve());
236+
jest
237+
.spyOn(pipelineService, "pollForPipelineStatus")
238+
.mockReturnValueOnce(Promise.resolve());
239+
240+
const rc = getMockRequestContext();
241+
await createHLDtoManifestPipeline({} as any, rc);
242+
expect(rc.createdHLDtoManifestPipeline).toBeTruthy();
243+
});
244+
it("positive test: pipeline already exists previously", async () => {
245+
jest
246+
.spyOn(pipelineService, "getPipelineByName")
247+
.mockReturnValueOnce(Promise.resolve({}));
248+
const fnDeletePipeline = jest
249+
.spyOn(pipelineService, "deletePipeline")
250+
.mockReturnValueOnce(Promise.resolve());
251+
jest
252+
.spyOn(hldPipeline, "installHldToManifestPipeline")
253+
.mockReturnValueOnce(Promise.resolve());
254+
jest
255+
.spyOn(pipelineService, "pollForPipelineStatus")
256+
.mockReturnValueOnce(Promise.resolve());
257+
258+
const rc = getMockRequestContext();
259+
await createHLDtoManifestPipeline({} as any, rc);
260+
expect(rc.createdHLDtoManifestPipeline).toBeTruthy();
261+
expect(fnDeletePipeline).toBeCalledTimes(1);
262+
fnDeletePipeline.mockReset();
263+
});
264+
it("negative test", async () => {
265+
jest
266+
.spyOn(pipelineService, "getPipelineByName")
267+
.mockReturnValueOnce(Promise.reject(Error("fake")));
268+
const rc = getMockRequestContext();
269+
await expect(createHLDtoManifestPipeline({} as any, rc)).rejects.toThrow();
270+
});
271+
});

0 commit comments

Comments
 (0)