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

Commit 0c6cada

Browse files
authored
spk deployment get includes PR column (if available) (#450)
* First pass of getting pull request info in the table * Adding some jsdoc * Adding more data to mocks file * Trying to fix unit test and improve coverage * Add missing mock file * Improve unit test more * PR feedback * PR feedback
1 parent 55a43c8 commit 0c6cada

File tree

4 files changed

+177
-18
lines changed

4 files changed

+177
-18
lines changed

src/commands/deployment/get.test.ts

+12-3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
watchGetDeployments,
2929
} from "./get";
3030
import * as get from "./get";
31+
import { IPullRequest } from "spektate/lib/repository/IPullRequest";
3132

3233
const MOCKED_INPUT_VALUES: CommandOptions = {
3334
buildId: "",
@@ -49,7 +50,7 @@ const MOCKED_VALUES: ValidatedOptions = {
4950
imageTag: "",
5051
nTop: 0,
5152
output: "",
52-
outputFormat: OUTPUT_FORMAT.NORMAL,
53+
outputFormat: OUTPUT_FORMAT.WIDE,
5354
service: "",
5455
top: "",
5556
watch: false,
@@ -68,18 +69,25 @@ const data = require("./mocks/data.json");
6869
const fakeDeployments = data;
6970
// eslint-disable-next-line @typescript-eslint/no-var-requires
7071
const fakeClusterSyncs = require("./mocks/cluster-sync.json");
72+
// eslint-disable-next-line @typescript-eslint/no-var-requires
73+
const fakePR = require("./mocks/pr.json");
7174
const mockedDeps: IDeployment[] = fakeDeployments.data.map(
7275
(dep: IDeployment) => {
7376
return {
7477
commitId: dep.commitId,
7578
deploymentId: dep.deploymentId,
7679
dockerToHldRelease: dep.dockerToHldRelease,
80+
dockerToHldReleaseStage: dep.dockerToHldReleaseStage,
7781
environment: dep.environment,
7882
hldCommitId: dep.hldCommitId || "",
83+
hldRepo: dep.hldRepo,
7984
hldToManifestBuild: dep.hldToManifestBuild,
8085
imageTag: dep.imageTag,
8186
manifestCommitId: dep.manifestCommitId,
87+
manifestRepo: dep.manifestRepo,
88+
pr: dep.pr,
8289
service: dep.service,
90+
sourceRepo: dep.sourceRepo,
8391
srcToDockerBuild: dep.srcToDockerBuild,
8492
timeStamp: dep.timeStamp,
8593
};
@@ -95,6 +103,7 @@ jest
95103
jest
96104
.spyOn(AzureDevOpsRepo, "getManifestSyncState")
97105
.mockReturnValue(Promise.resolve(mockedClusterSyncs));
106+
jest.spyOn(Deployment, "fetchPR").mockReturnValue(Promise.resolve(fakePR));
98107

99108
let initObject: InitObject;
100109

@@ -338,7 +347,7 @@ describe("Print deployments", () => {
338347

339348
table = printDeployments(
340349
mockedDeps,
341-
processOutputFormat("normal"),
350+
processOutputFormat("wide"),
342351
3,
343352
mockedClusterSyncs
344353
);
@@ -380,7 +389,7 @@ describe("Output formats", () => {
380389
);
381390
expect(table).not.toBeUndefined();
382391
table!.forEach((field) => {
383-
expect(field).toHaveLength(18);
392+
expect(field).toHaveLength(20);
384393
});
385394
});
386395
});

src/commands/deployment/get.ts

+113-13
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import {
77
getDeploymentsBasedOnFilters,
88
IDeployment,
99
status as getDeploymentStatus,
10+
fetchPR,
11+
getRepositoryFromURL,
1012
} from "spektate/lib/IDeployment";
1113
import AzureDevOpsPipeline from "spektate/lib/pipeline/AzureDevOpsPipeline";
1214
import {
@@ -24,7 +26,10 @@ import { isIntegerString } from "../../lib/validator";
2426
import { logger } from "../../logger";
2527
import { ConfigYaml } from "../../types";
2628
import decorator from "./get.decorator.json";
29+
import { IPullRequest } from "spektate/lib/repository/IPullRequest";
2730

31+
const promises: Promise<IPullRequest | undefined>[] = [];
32+
const pullRequests: { [id: string]: IPullRequest } = {};
2833
/**
2934
* Output formats to display service details
3035
*/
@@ -184,25 +189,55 @@ export const getDeployments = (
184189
);
185190
return new Promise((resolve, reject) => {
186191
Promise.all([deploymentsPromise, syncStatusesPromise])
187-
.then((tuple: [IDeployment[] | undefined, ITag[] | undefined]) => {
192+
.then(async (tuple: [IDeployment[] | undefined, ITag[] | undefined]) => {
188193
const deployments: IDeployment[] | undefined = tuple[0];
189194
const syncStatuses: ITag[] | undefined = tuple[1];
190-
if (values.outputFormat === OUTPUT_FORMAT.JSON) {
191-
console.log(JSON.stringify(deployments, null, 2));
192-
resolve(deployments);
193-
} else {
195+
const displayedDeployments = await displayDeployments(
196+
values,
197+
deployments,
198+
syncStatuses
199+
);
200+
resolve(displayedDeployments);
201+
})
202+
.catch((e) => {
203+
reject(new Error(e));
204+
});
205+
});
206+
};
207+
208+
/**
209+
* Displays the deployments based on output format requested and top n
210+
* @param values validated command line values
211+
* @param deployments list of deployments to display
212+
* @param syncStatuses cluster sync statuses
213+
*/
214+
export const displayDeployments = (
215+
values: ValidatedOptions,
216+
deployments: IDeployment[] | undefined,
217+
syncStatuses: ITag[] | undefined
218+
): Promise<IDeployment[]> => {
219+
return new Promise((resolve, reject) => {
220+
if (values.outputFormat === OUTPUT_FORMAT.WIDE) {
221+
getPRs(deployments);
222+
}
223+
if (values.outputFormat === OUTPUT_FORMAT.JSON) {
224+
console.log(JSON.stringify(deployments, null, 2));
225+
resolve(deployments);
226+
} else {
227+
Promise.all(promises)
228+
.then(() => {
194229
printDeployments(
195230
deployments,
196231
values.outputFormat,
197232
values.nTop,
198233
syncStatuses
199234
);
200235
resolve(deployments);
201-
}
202-
})
203-
.catch((e) => {
204-
reject(new Error(e));
205-
});
236+
})
237+
.catch((e) => {
238+
reject(e);
239+
});
240+
}
206241
});
207242
};
208243

@@ -362,9 +397,16 @@ export const printDeployments = (
362397
"Env",
363398
"Hld Commit",
364399
"Result",
365-
"HLD to Manifest",
366-
"Result",
367400
];
401+
let prsExist = false;
402+
if (
403+
Object.keys(pullRequests).length > 0 &&
404+
outputFormat === OUTPUT_FORMAT.WIDE
405+
) {
406+
header = header.concat(["Approval PR", "Merged By"]);
407+
prsExist = true;
408+
}
409+
header = header.concat(["HLD to Manifest", "Result"]);
368410
if (outputFormat === OUTPUT_FORMAT.WIDE) {
369411
header = header.concat([
370412
"Duration",
@@ -403,6 +445,7 @@ export const printDeployments = (
403445

404446
toDisplay.forEach((deployment) => {
405447
const row = [];
448+
let deploymentStatus = getDeploymentStatus(deployment);
406449
row.push(
407450
deployment.srcToDockerBuild
408451
? deployment.srcToDockerBuild.startTime.toLocaleString()
@@ -445,6 +488,25 @@ export const printDeployments = (
445488
);
446489
row.push(deployment.hldCommitId || "-");
447490
row.push(dockerToHldStatus);
491+
492+
// Print PR if available
493+
if (
494+
prsExist &&
495+
deployment.pr &&
496+
deployment.pr.toString() in pullRequests
497+
) {
498+
row.push(deployment.pr);
499+
if (pullRequests[deployment.pr!.toString()].mergedBy) {
500+
row.push(pullRequests[deployment.pr!.toString()].mergedBy?.name);
501+
} else {
502+
deploymentStatus = "Waiting";
503+
row.push("-");
504+
}
505+
} else if (prsExist) {
506+
row.push("-");
507+
row.push("-");
508+
}
509+
448510
row.push(
449511
deployment.hldToManifestBuild ? deployment.hldToManifestBuild.id : "-"
450512
);
@@ -455,7 +517,7 @@ export const printDeployments = (
455517
);
456518
if (outputFormat === OUTPUT_FORMAT.WIDE) {
457519
row.push(duration(deployment) + " mins");
458-
row.push(getDeploymentStatus(deployment));
520+
row.push(deploymentStatus);
459521
row.push(deployment.manifestCommitId || "-");
460522
row.push(
461523
deployment.hldToManifestBuild &&
@@ -488,6 +550,44 @@ export const printDeployments = (
488550
}
489551
};
490552

553+
/**
554+
* Gets PR information for all the deployments
555+
* @param deployments all deployments to be displayed
556+
*/
557+
export const getPRs = (deployments: IDeployment[] | undefined) => {
558+
if (deployments && deployments.length > 0) {
559+
deployments.forEach((deployment: IDeployment) => {
560+
fetchPRInformation(deployment);
561+
});
562+
}
563+
};
564+
565+
/**
566+
* Fetches pull request data for deployments that complete merge into HLD
567+
* by merging a PR
568+
* @param deployment deployment for which PR has to be fetched
569+
*/
570+
export const fetchPRInformation = (deployment: IDeployment) => {
571+
const config = Config();
572+
if (!deployment.hldRepo || !deployment.pr) {
573+
return;
574+
}
575+
const repo: IAzureDevOpsRepo | IGitHub | undefined = getRepositoryFromURL(
576+
deployment.hldRepo!
577+
);
578+
const promise = fetchPR(
579+
repo!,
580+
deployment.pr!.toString(),
581+
config.introspection?.azure?.source_repo_access_token
582+
);
583+
promise.then((pr: IPullRequest | undefined) => {
584+
if (pr) {
585+
pullRequests[deployment.pr!.toString()] = pr;
586+
}
587+
});
588+
promises.push(promise);
589+
};
590+
491591
/**
492592
* Returns a matching sync status for a deployment
493593
* @param deployment Deployment object

src/commands/deployment/mocks/data.json

+38-2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@
5050
"registryURL": "hellorings.azurecr.io",
5151
"registryResourceGroup": "bedrock-rings"
5252
},
53+
"pr": "1123",
54+
"hldRepo": "https://github.com/samiyaakhtar/hello-bedrock-hld",
55+
"manifestRepo": "https://github.com/samiyaakhtar/hello-bedrock-manifest",
56+
"sourceRepo": "https://github.com/samiyaakhtar/hello-bedrock",
5357
"commitId": "c626394",
5458
"hldCommitId": "a3dc9a7",
5559
"imageTag": "hello-bedrock-master-6053",
@@ -108,6 +112,10 @@
108112
"registryURL": "hellorings.azurecr.io",
109113
"registryResourceGroup": "bedrock-rings"
110114
},
115+
"pr": "1133",
116+
"hldRepo": "https://github.com/samiyaakhtar/hello-bedrock-hld",
117+
"manifestRepo": "https://github.com/samiyaakhtar/hello-bedrock-manifest",
118+
"sourceRepo": "https://github.com/samiyaakhtar/hello-bedrock",
111119
"commitId": "a0bca78",
112120
"hldCommitId": "316abbc",
113121
"imageTag": "hello-spektate-master-6042",
@@ -166,6 +174,10 @@
166174
"registryURL": "hellorings.azurecr.io",
167175
"registryResourceGroup": "bedrock-rings"
168176
},
177+
"pr": "1173",
178+
"hldRepo": "https://github.com/samiyaakhtar/hello-bedrock-hld",
179+
"manifestRepo": "https://github.com/samiyaakhtar/hello-bedrock-manifest",
180+
"sourceRepo": "https://github.com/samiyaakhtar/hello-bedrock",
169181
"commitId": "c626394",
170182
"hldCommitId": "e4a2730",
171183
"imageTag": "hello-bedrock-master-5977",
@@ -224,6 +236,10 @@
224236
"registryURL": "hellorings.azurecr.io",
225237
"registryResourceGroup": "bedrock-rings"
226238
},
239+
"pr": "1125",
240+
"hldRepo": "https://github.com/samiyaakhtar/hello-bedrock-hld",
241+
"manifestRepo": "https://github.com/samiyaakhtar/hello-bedrock-manifest",
242+
"sourceRepo": "https://github.com/samiyaakhtar/hello-bedrock",
227243
"commitId": "5b54eb4",
228244
"hldCommitId": "18abc7a",
229245
"imageTag": "hello-bedrock-master-6074",
@@ -282,6 +298,10 @@
282298
"registryURL": "hellorings.azurecr.io",
283299
"registryResourceGroup": "bedrock-rings"
284300
},
301+
"pr": "1120",
302+
"hldRepo": "https://github.com/samiyaakhtar/hello-bedrock-hld",
303+
"manifestRepo": "https://github.com/samiyaakhtar/hello-bedrock-manifest",
304+
"sourceRepo": "https://github.com/samiyaakhtar/hello-bedrock",
285305
"commitId": "a0bca78",
286306
"hldCommitId": "863d50f",
287307
"imageTag": "hello-spektate-master-6049",
@@ -340,6 +360,10 @@
340360
"registryURL": "hellorings.azurecr.io",
341361
"registryResourceGroup": "bedrock-rings"
342362
},
363+
"pr": "1119",
364+
"hldRepo": "https://github.com/samiyaakhtar/hello-bedrock-hld",
365+
"manifestRepo": "https://github.com/samiyaakhtar/hello-bedrock-manifest",
366+
"sourceRepo": "https://github.com/samiyaakhtar/hello-bedrock",
343367
"commitId": "c626394",
344368
"hldCommitId": "706685f",
345369
"imageTag": "hello-bedrock-master-6046",
@@ -398,6 +422,10 @@
398422
"registryURL": "hellorings.azurecr.io",
399423
"registryResourceGroup": "bedrock-rings"
400424
},
425+
"pr": "1118",
426+
"hldRepo": "https://github.com/samiyaakhtar/hello-bedrock-hld",
427+
"manifestRepo": "https://github.com/samiyaakhtar/hello-bedrock-manifest",
428+
"sourceRepo": "https://github.com/samiyaakhtar/hello-bedrock",
401429
"commitId": "c626394",
402430
"hldCommitId": "bac890c",
403431
"imageTag": "hello-bedrock-master-6044",
@@ -456,6 +484,10 @@
456484
"registryURL": "hellorings.azurecr.io",
457485
"registryResourceGroup": "bedrock-rings"
458486
},
487+
"pr": "1115",
488+
"hldRepo": "https://github.com/samiyaakhtar/hello-bedrock-hld",
489+
"manifestRepo": "https://github.com/samiyaakhtar/hello-bedrock-manifest",
490+
"sourceRepo": "https://github.com/samiyaakhtar/hello-bedrock",
459491
"commitId": "a0bca78",
460492
"hldCommitId": "316abbc",
461493
"imageTag": "hello-spektate-master-6042",
@@ -514,6 +546,10 @@
514546
"registryURL": "hellorings.azurecr.io",
515547
"registryResourceGroup": "bedrock-rings"
516548
},
549+
"pr": "1111",
550+
"hldRepo": "https://github.com/samiyaakhtar/hello-bedrock-hld",
551+
"manifestRepo": "https://github.com/samiyaakhtar/hello-bedrock-manifest",
552+
"sourceRepo": "https://github.com/samiyaakhtar/hello-bedrock",
517553
"commitId": "8028a15",
518554
"hldCommitId": "0612e7a",
519555
"imageTag": "hello-spektate-master-6009",
@@ -560,10 +596,10 @@
560596
}
561597
},
562598
"deploymentId": "33733a9f4573",
563-
"dockerToHldRelease": {
599+
"dockerToHldReleaseStage": {
564600
"URL": "https://dev.azure.com/epicstuff/f8a98d9c-8f11-46ef-89e4-07b4a56d1ad5/_release?releaseId=173&_a=release-summary",
565601
"finishTime": "2019-08-28T20:14:30.093Z",
566-
"id": 173,
602+
"id": 5975,
567603
"queueTime": "2019-08-28T20:13:56.163Z",
568604
"releaseName": "Release-170",
569605
"startTime": "2019-08-28T20:14:08.787Z",

src/commands/deployment/mocks/pr.json

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"description": "Updating samiya.frontend to master-20200318.1.\nPR created by: samiya2019 with buildId: 14751 and buildNumber: 20200318.1",
3+
"id": 1371,
4+
"mergedBy": {
5+
"imageUrl": "https://dev.azure.com/epicstuff/_api/_common/identityImage?id=e8900b94-217f-4a51-9d86-6bbf5d82b6fb",
6+
"name": "Samiya Akhtar",
7+
"url": "https://dev.azure.com/epicstuff/e7236bd9-a6f9-4554-8dce-ad81ae94faf6/_apis/git/repositories/a491cdad-443c-4419-9726-95e7619673ae/pullRequests/1371",
8+
"username": "[email protected]"
9+
},
10+
"sourceBranch": "DEPLOY/samiya2019-samiya.frontend-master-20200318.1",
11+
"targetBranch": "master",
12+
"title": "Updating samiya.frontend image tag to master-20200318.1.",
13+
"url": "https://dev.azure.com/epicstuff/hellobedrockprivate/_git/samiya-hld/pullrequest/1371"
14+
}

0 commit comments

Comments
 (0)