@squiz/component-cli-lib 1.39.0 → 1.39.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +1 -0
- package/.npm/_logs/{2023-06-21T06_20_44_251Z-debug-0.log → 2023-06-22T05_24_46_739Z-debug-0.log} +16 -16
- package/lib/index.d.ts +1 -0
- package/lib/index.js +139 -139
- package/lib/index.js.map +4 -4
- package/lib/integration-tests/helper.d.ts +5 -0
- package/lib/upload-job.d.ts +4 -0
- package/lib/utils.d.ts +7 -0
- package/lib/utils.spec.d.ts +1 -0
- package/package.json +9 -9
- package/src/index.ts +1 -0
- package/src/integration-tests/__jobs__/invalid-manifest/main.js +3 -0
- package/src/integration-tests/__jobs__/invalid-manifest/manifest.json +28 -0
- package/src/integration-tests/__jobs__/invalid-upload/main.js +3 -0
- package/src/integration-tests/__jobs__/simple-job/main.js +3 -0
- package/src/integration-tests/__jobs__/simple-job/manifest.json +25 -0
- package/src/integration-tests/helper.ts +33 -0
- package/src/upload-component-folder.ts +26 -103
- package/src/upload-job.ts +101 -0
- package/src/utils.spec.ts +199 -0
- package/src/utils.ts +97 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -5,6 +5,7 @@ interface Config {
|
|
|
5
5
|
renderServiceUrl: string;
|
|
6
6
|
contentServiceUrl: string;
|
|
7
7
|
tenantId: string;
|
|
8
|
+
jobServiceUrl: string;
|
|
8
9
|
ci_buildVersion: string;
|
|
9
10
|
ci_buildBranch: string;
|
|
10
11
|
}
|
|
@@ -15,9 +16,11 @@ export declare const managementService: import("axios").AxiosInstance;
|
|
|
15
16
|
export declare const managementServiceRoot: import("axios").AxiosInstance;
|
|
16
17
|
export declare const renderService: import("axios").AxiosInstance;
|
|
17
18
|
export declare const contentService: import("axios").AxiosInstance;
|
|
19
|
+
export declare const jobService: import("axios").AxiosInstance;
|
|
18
20
|
export declare const ci_buildVersion: string;
|
|
19
21
|
export declare const ci_buildBranch: string;
|
|
20
22
|
export declare function getTestComponents(): Promise<import("@squiz/component-lib").ManifestV1[]>;
|
|
23
|
+
export declare function getTestJobs(): Promise<import("@squiz/component-lib").ManifestV1[]>;
|
|
21
24
|
export declare function createFile(filePath: string, sizeInMB: number): Promise<void>;
|
|
22
25
|
export declare function removeFile(filePath: string): void;
|
|
23
26
|
export declare function deleteComponentSet(webPath: string): Promise<void>;
|
|
@@ -26,3 +29,5 @@ export declare function addContentItem(contentItem: ContentApi.ContentItemWebMod
|
|
|
26
29
|
export declare function deleteContentItem(contentItemId: string): Promise<void>;
|
|
27
30
|
export declare function deleteComponent(manifest: Manifest): Promise<void>;
|
|
28
31
|
export declare function deleteComponents(manifests: Manifest[]): Promise<void>;
|
|
32
|
+
export declare function deleteJob(manifest: Manifest): Promise<void>;
|
|
33
|
+
export declare function deleteJobs(manifests: Manifest[]): Promise<void>;
|
package/lib/utils.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AxiosResponse, AxiosError, AxiosInstance } from 'axios';
|
|
2
|
+
export declare function watchAndWaitForUploadAndScanComplete(apiClient: AxiosInstance, endpoint: string, id: string, managementURL?: string): Promise<void>;
|
|
3
|
+
export declare function checkIfVersionExists(apiClient: AxiosInstance, endpoint: string, managementURL?: string): Promise<boolean>;
|
|
4
|
+
export declare function handleResponse<T>(axiosInstance: Promise<AxiosResponse<T>>): Promise<T>;
|
|
5
|
+
export declare function handleError(error: any): Error;
|
|
6
|
+
export declare function isAxiosError(error: any): error is AxiosError;
|
|
7
|
+
export declare function isAxiosResponse(response: unknown): response is AxiosResponse;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@squiz/component-cli-lib",
|
|
3
|
-
"version": "1.39.
|
|
3
|
+
"version": "1.39.1-alpha.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
"author": "",
|
|
14
14
|
"license": "ISC",
|
|
15
15
|
"devDependencies": {
|
|
16
|
-
"@squiz/component-lib": "1.39.
|
|
17
|
-
"@squiz/component-web-api-lib": "1.39.
|
|
18
|
-
"@squiz/dx-common-lib": "1.39.
|
|
19
|
-
"@squiz/dx-json-schema-lib": "1.39.
|
|
20
|
-
"@squiz/dx-logger-lib": "1.39.
|
|
21
|
-
"@squiz/virus-scanner-lib": "1.39.
|
|
16
|
+
"@squiz/component-lib": "1.39.1-alpha.1",
|
|
17
|
+
"@squiz/component-web-api-lib": "1.39.1-alpha.1",
|
|
18
|
+
"@squiz/dx-common-lib": "1.39.1-alpha.1",
|
|
19
|
+
"@squiz/dx-json-schema-lib": "1.39.1-alpha.1",
|
|
20
|
+
"@squiz/dx-logger-lib": "1.39.1-alpha.1",
|
|
21
|
+
"@squiz/virus-scanner-lib": "1.39.1-alpha.1",
|
|
22
22
|
"@types/cli-color": "2.0.2",
|
|
23
23
|
"@types/express": "4.17.17",
|
|
24
24
|
"@types/jest": "28.1.8",
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
"typescript": "4.9.4"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@squiz/render-runtime-lib": "1.39.
|
|
35
|
+
"@squiz/render-runtime-lib": "1.39.1-alpha.1",
|
|
36
36
|
"archiver": "5.3.1",
|
|
37
37
|
"axios": "1.3.2",
|
|
38
38
|
"cli-color": "^2.0.2",
|
|
39
39
|
"open": "^8.4.0",
|
|
40
40
|
"supertest": "^6.2.3"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "16b9f02b751a923a71f96684bd46c781fc97dcbc"
|
|
43
43
|
}
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://localhost:3040/schemas/JobV1.json#",
|
|
3
|
+
"name": "invalid manif@st",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"mainFunction": "main",
|
|
6
|
+
"displayName": "some-displayName",
|
|
7
|
+
"description": "some-description",
|
|
8
|
+
"concurrency": 1,
|
|
9
|
+
"timeout": 10000,
|
|
10
|
+
"functions": [
|
|
11
|
+
{
|
|
12
|
+
"entry": "main.js",
|
|
13
|
+
"name": "main",
|
|
14
|
+
"input": {
|
|
15
|
+
"type": "object",
|
|
16
|
+
"properties": {
|
|
17
|
+
"something": {
|
|
18
|
+
"type": "string"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"required": ["something"]
|
|
22
|
+
},
|
|
23
|
+
"output": {
|
|
24
|
+
"responseType": "html"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://localhost:3040/schemas/JobV1.json#",
|
|
3
|
+
"name": "simple-job",
|
|
4
|
+
"displayName": "Simple Job",
|
|
5
|
+
"version": "1.0.2",
|
|
6
|
+
"mainFunction": "main",
|
|
7
|
+
"description": "some-description",
|
|
8
|
+
"concurrency": 1,
|
|
9
|
+
"timeout": 10000,
|
|
10
|
+
"functions": [
|
|
11
|
+
{
|
|
12
|
+
"entry": "main.js",
|
|
13
|
+
"name": "main",
|
|
14
|
+
"input": {
|
|
15
|
+
"type": "object",
|
|
16
|
+
"properties": {
|
|
17
|
+
"something": {
|
|
18
|
+
"type": "string"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"required": ["something"]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -17,6 +17,7 @@ interface Config {
|
|
|
17
17
|
renderServiceUrl: string;
|
|
18
18
|
contentServiceUrl: string;
|
|
19
19
|
tenantId: string;
|
|
20
|
+
jobServiceUrl: string;
|
|
20
21
|
ci_buildVersion: string;
|
|
21
22
|
ci_buildBranch: string;
|
|
22
23
|
}
|
|
@@ -26,6 +27,7 @@ const configObj: Config = {
|
|
|
26
27
|
renderServiceUrl: parseEnvVarForVar('COMPONENT_RENDER_SERVICE_URL').replace(/\/+$/, ''),
|
|
27
28
|
contentServiceUrl: parseEnvVarForVar('CONTENT_API_URL').replace(/\/+$/, ''),
|
|
28
29
|
tenantId: parseEnvVarForVar('TENANT_ID'),
|
|
30
|
+
jobServiceUrl: parseEnvVarForVar('JOB_SERVICE_URL').replace(/\/+$/, ''),
|
|
29
31
|
ci_buildVersion: parseEnvVarForVar('CI_COMMIT_SHORT_SHA'),
|
|
30
32
|
ci_buildBranch: parseEnvVarForVar('CI_COMMIT_REF_NAME'),
|
|
31
33
|
};
|
|
@@ -109,6 +111,13 @@ export const contentService = axios.create({
|
|
|
109
111
|
},
|
|
110
112
|
});
|
|
111
113
|
|
|
114
|
+
export const jobService = axios.create({
|
|
115
|
+
baseURL: configObj.jobServiceUrl,
|
|
116
|
+
headers: {
|
|
117
|
+
authorization: authToken,
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
|
|
112
121
|
export const ci_buildVersion = configObj.ci_buildVersion;
|
|
113
122
|
export const ci_buildBranch = configObj.ci_buildBranch;
|
|
114
123
|
|
|
@@ -117,6 +126,13 @@ export async function getTestComponents() {
|
|
|
117
126
|
const manifestService = new ManifestServiceForDev(componentsDir, getLogger({ name: 'getTestComponents' }));
|
|
118
127
|
return await manifestService.listAllComponentManifests();
|
|
119
128
|
}
|
|
129
|
+
|
|
130
|
+
export async function getTestJobs() {
|
|
131
|
+
const jobsDir = path.join(__dirname, '/__jobs__/');
|
|
132
|
+
const manifestService = new ManifestServiceForDev(jobsDir, getLogger({ name: 'getTestJobs' }));
|
|
133
|
+
return await manifestService.listAllComponentManifests();
|
|
134
|
+
}
|
|
135
|
+
|
|
120
136
|
export async function createFile(filePath: string, sizeInMB: number) {
|
|
121
137
|
const content = randomBytes(sizeInMB * 1000000);
|
|
122
138
|
await fsp.writeFile(`${filePath}`, content);
|
|
@@ -174,3 +190,20 @@ export async function deleteComponent(manifest: Manifest) {
|
|
|
174
190
|
export async function deleteComponents(manifests: Manifest[]) {
|
|
175
191
|
await Promise.all(manifests.map((manifest) => deleteComponent(manifest)));
|
|
176
192
|
}
|
|
193
|
+
|
|
194
|
+
export async function deleteJob(manifest: Manifest) {
|
|
195
|
+
try {
|
|
196
|
+
await jobService.delete(`/job/${manifest.getName()}/${manifest.getVersion()}`);
|
|
197
|
+
} catch (error) {
|
|
198
|
+
if ((error as AxiosError).response?.status === 404) {
|
|
199
|
+
const logger = getLogger({ name: 'delete job' });
|
|
200
|
+
logger.info('job not found');
|
|
201
|
+
} else {
|
|
202
|
+
throw error;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export async function deleteJobs(manifests: Manifest[]) {
|
|
208
|
+
await Promise.all(manifests.map((manifest) => deleteJob(manifest)));
|
|
209
|
+
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { uploadFile } from '@squiz/virus-scanner-lib';
|
|
2
2
|
|
|
3
3
|
import { zipDirectory } from '@squiz/dx-common-lib';
|
|
4
|
-
import {
|
|
4
|
+
import { ManifestServiceForDev } from '@squiz/component-lib';
|
|
5
5
|
import fsp from 'fs/promises';
|
|
6
6
|
import path from 'path';
|
|
7
|
-
import {
|
|
7
|
+
import { AxiosInstance } from 'axios';
|
|
8
8
|
import color from 'cli-color';
|
|
9
9
|
import { getLogger, Logger } from '@squiz/dx-logger-lib';
|
|
10
|
+
import { watchAndWaitForUploadAndScanComplete, checkIfVersionExists, handleResponse, isAxiosResponse } from './utils';
|
|
10
11
|
|
|
11
12
|
export const logger: Logger = getLogger({ name: 'upload-component', format: 'human' });
|
|
12
13
|
|
|
@@ -24,7 +25,15 @@ export async function uploadComponentFolder(
|
|
|
24
25
|
const manifest = await manifestService.readManifest(manifestPath);
|
|
25
26
|
await manifestService.assertManifestIsValid(manifestPath, manifest.getModel());
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
if (
|
|
29
|
+
await checkIfVersionExists(
|
|
30
|
+
apiClient,
|
|
31
|
+
`/v1/component/${manifest.getName()}/${manifest.getVersion()}`,
|
|
32
|
+
componentServiceManagementUrl,
|
|
33
|
+
)
|
|
34
|
+
) {
|
|
35
|
+
throw new Error(`Cannot upload component version, ${manifest.getName()} ${manifest.getVersion()} already exists`);
|
|
36
|
+
}
|
|
28
37
|
logger.info('Initial scanning');
|
|
29
38
|
const zip = await zipDirectory(folderPath, tmpDir);
|
|
30
39
|
|
|
@@ -35,7 +44,12 @@ export async function uploadComponentFolder(
|
|
|
35
44
|
logger.info(`deployment id: ${initialUpload.id} status: transferring`);
|
|
36
45
|
await uploadFile(initialUpload, zip);
|
|
37
46
|
|
|
38
|
-
await watchAndWaitForUploadAndScanComplete(
|
|
47
|
+
await watchAndWaitForUploadAndScanComplete(
|
|
48
|
+
apiClient,
|
|
49
|
+
'/v1/upload-component/status/',
|
|
50
|
+
initialUpload.id,
|
|
51
|
+
componentServiceManagementUrl,
|
|
52
|
+
);
|
|
39
53
|
|
|
40
54
|
logger.info(`deployment id: ${initialUpload.id} status: deploying component folder`);
|
|
41
55
|
|
|
@@ -52,7 +66,13 @@ export async function uploadComponentFolder(
|
|
|
52
66
|
`unknown, retrying to check the upload status ${retriesAllowed} more times`,
|
|
53
67
|
)}`,
|
|
54
68
|
);
|
|
55
|
-
if (
|
|
69
|
+
if (
|
|
70
|
+
await checkIfVersionExists(
|
|
71
|
+
apiClient,
|
|
72
|
+
`/v1/component/${manifest.getName()}/${manifest.getVersion()}`,
|
|
73
|
+
componentServiceManagementUrl,
|
|
74
|
+
)
|
|
75
|
+
) {
|
|
56
76
|
result = {
|
|
57
77
|
status: 'successful',
|
|
58
78
|
accessLink: 'unknown',
|
|
@@ -89,100 +109,3 @@ export async function uploadComponentFolder(
|
|
|
89
109
|
throw e;
|
|
90
110
|
}
|
|
91
111
|
}
|
|
92
|
-
|
|
93
|
-
async function preUploadChecks(apiClient: AxiosInstance, managementURL: string, manifest: Manifest) {
|
|
94
|
-
if (await checkIfVersionExists(apiClient, managementURL, manifest)) {
|
|
95
|
-
throw new Error(`Cannot upload component version, ${manifest.getName()} ${manifest.getVersion()} already exists`);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
async function checkIfVersionExists(apiClient: AxiosInstance, managementURL: string, inputManifest: Manifest) {
|
|
100
|
-
try {
|
|
101
|
-
const response = await apiClient.get(`/v1/component/${inputManifest.getName()}/${inputManifest.getVersion()}`, {
|
|
102
|
-
validateStatus: null,
|
|
103
|
-
baseURL: managementURL,
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
if (response.status === 200) {
|
|
107
|
-
return true;
|
|
108
|
-
} else if (response.status === 404) {
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const error = new AxiosError(
|
|
113
|
-
response?.data?.message || response.statusText,
|
|
114
|
-
response.status.toString(),
|
|
115
|
-
undefined,
|
|
116
|
-
undefined,
|
|
117
|
-
response,
|
|
118
|
-
);
|
|
119
|
-
|
|
120
|
-
throw handleError(error);
|
|
121
|
-
} catch (error) {
|
|
122
|
-
throw handleError(error);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
async function watchAndWaitForUploadAndScanComplete(
|
|
127
|
-
apiClient: AxiosInstance,
|
|
128
|
-
managementURL: string,
|
|
129
|
-
id: string,
|
|
130
|
-
): Promise<void> {
|
|
131
|
-
const poll = () =>
|
|
132
|
-
handleResponse<ScanStatus>(apiClient.get('/v1/upload-component/status/' + id, { baseURL: managementURL }));
|
|
133
|
-
|
|
134
|
-
return new Promise((resolve, reject) => {
|
|
135
|
-
const recurse = () =>
|
|
136
|
-
poll().then(async (req) => {
|
|
137
|
-
if (req.status == 'Success') {
|
|
138
|
-
resolve();
|
|
139
|
-
} else if (req.status == 'Flagged') {
|
|
140
|
-
reject(new Error('upload has been flagged as a virus'));
|
|
141
|
-
} else if (req.status == 'Error') {
|
|
142
|
-
reject(new Error('there has been an error'));
|
|
143
|
-
} else {
|
|
144
|
-
setTimeout(async () => {
|
|
145
|
-
await recurse();
|
|
146
|
-
}, 1000);
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
recurse();
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
async function handleResponse<T>(axiosInstance: Promise<AxiosResponse<T>>): Promise<T> {
|
|
155
|
-
try {
|
|
156
|
-
const response = await axiosInstance;
|
|
157
|
-
return response.data;
|
|
158
|
-
} catch (error) {
|
|
159
|
-
throw handleError(error);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
function handleError(error: any): Error {
|
|
164
|
-
const { response } = error;
|
|
165
|
-
const errorMessage = error.message;
|
|
166
|
-
const newError = new Error(errorMessage || 'An error has occurred');
|
|
167
|
-
|
|
168
|
-
if (isAxiosError(error)) {
|
|
169
|
-
const errorCode = response.status ?? 'unknown';
|
|
170
|
-
if (response?.data?.message) {
|
|
171
|
-
newError.message = `Unexpected response code ${errorCode}. ${response.data.message}`.trim();
|
|
172
|
-
} else {
|
|
173
|
-
newError.message = `${errorMessage} (code: ${errorCode})`;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
newError.stack = error.stack;
|
|
178
|
-
|
|
179
|
-
return newError;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
function isAxiosError(error: any): error is AxiosError {
|
|
183
|
-
return error && error.isAxiosError === true;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function isAxiosResponse(response: unknown): response is AxiosResponse {
|
|
187
|
-
return response instanceof Object && Object.prototype.hasOwnProperty.call(response, 'status');
|
|
188
|
-
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { uploadFile } from '@squiz/virus-scanner-lib';
|
|
2
|
+
|
|
3
|
+
import { zipDirectory } from '@squiz/dx-common-lib';
|
|
4
|
+
import { ManifestServiceForDev, JobManifestV1Model } from '@squiz/component-lib';
|
|
5
|
+
import fsp from 'fs/promises';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { AxiosInstance } from 'axios';
|
|
8
|
+
import color from 'cli-color';
|
|
9
|
+
import { getLogger, Logger } from '@squiz/dx-logger-lib';
|
|
10
|
+
import { watchAndWaitForUploadAndScanComplete, handleResponse, checkIfVersionExists, isAxiosResponse } from './utils';
|
|
11
|
+
|
|
12
|
+
export const logger: Logger = getLogger({ name: 'upload-job', format: 'human' });
|
|
13
|
+
|
|
14
|
+
export async function uploadJobFolder(
|
|
15
|
+
apiClient: AxiosInstance,
|
|
16
|
+
folderPath: string,
|
|
17
|
+
baseTempDir: string = '',
|
|
18
|
+
): Promise<void> {
|
|
19
|
+
const tmpDir = await fsp.mkdtemp(path.resolve(baseTempDir, 'job-upload'));
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
const manifest = await getAndValidateManifest(apiClient, folderPath);
|
|
23
|
+
|
|
24
|
+
const initialUpload = await initializeUpload(apiClient, folderPath, tmpDir);
|
|
25
|
+
|
|
26
|
+
await uploadFile(initialUpload.upload, initialUpload.zip);
|
|
27
|
+
|
|
28
|
+
await watchAndWaitForUploadAndScanComplete(apiClient, '/upload-job/status/', initialUpload.upload.id);
|
|
29
|
+
|
|
30
|
+
logger.info(`deployment id: ${initialUpload.upload.id} status: deploying job folder`);
|
|
31
|
+
|
|
32
|
+
const result = await pollForResult(apiClient, initialUpload.upload.id, manifest.getModel());
|
|
33
|
+
|
|
34
|
+
await cleanupTmpDir(tmpDir);
|
|
35
|
+
|
|
36
|
+
if (result.status === 'successful') {
|
|
37
|
+
logger.info(`deployment id: ${initialUpload.upload.id} status: ${color.green('success')}`);
|
|
38
|
+
} else {
|
|
39
|
+
const message = result?.message ?? 'unknown';
|
|
40
|
+
logger.error(`failed due an unexpected reason: ${message}`);
|
|
41
|
+
await cleanupTmpDir(tmpDir);
|
|
42
|
+
}
|
|
43
|
+
} catch (e) {
|
|
44
|
+
await cleanupTmpDir(tmpDir);
|
|
45
|
+
throw e;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function initializeUpload(apiClient: AxiosInstance, folderPath: string, tmpDir: string) {
|
|
50
|
+
logger.info('Initial scanning');
|
|
51
|
+
const zip = await zipDirectory(folderPath, tmpDir);
|
|
52
|
+
const initialUpload = { zip: zip, upload: await handleResponse<any>(apiClient.post('/upload-job', {})) };
|
|
53
|
+
logger.info(`deployment id: ${initialUpload.upload.id} status: transferring`);
|
|
54
|
+
return initialUpload;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function getAndValidateManifest(apiClient: AxiosInstance, folderPath: string) {
|
|
58
|
+
const manifestService = new ManifestServiceForDev(folderPath, logger);
|
|
59
|
+
const manifestPath = path.join(folderPath, `manifest.json`);
|
|
60
|
+
|
|
61
|
+
const manifest = await manifestService.readJobManifest(manifestPath);
|
|
62
|
+
|
|
63
|
+
if (await checkIfVersionExists(apiClient, `/job/${manifest.getName()}/${manifest.getVersion()}`)) {
|
|
64
|
+
throw new Error(`Cannot upload job version, ${manifest.getName()} ${manifest.getVersion()} already exists`);
|
|
65
|
+
}
|
|
66
|
+
return manifest;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function pollForResult(apiClient: AxiosInstance, uploadId: string, manifest: JobManifestV1Model) {
|
|
70
|
+
let result = await handleResponse<any>(apiClient.post(`/upload-job/next`, { id: uploadId, manifest: manifest }));
|
|
71
|
+
|
|
72
|
+
if (!isAxiosResponse(result)) {
|
|
73
|
+
let retriesAllowed = 12;
|
|
74
|
+
while (retriesAllowed > 0) {
|
|
75
|
+
logger.info(
|
|
76
|
+
`deployment id: ${uploadId} status: ${color.yellow(
|
|
77
|
+
`unknown, retrying to check the upload status ${retriesAllowed} more times`,
|
|
78
|
+
)}`,
|
|
79
|
+
);
|
|
80
|
+
if (await checkIfVersionExists(apiClient, `/job/${manifest.name}/${manifest.version}`)) {
|
|
81
|
+
result = {
|
|
82
|
+
status: 'successful',
|
|
83
|
+
};
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
await new Promise((r) => setTimeout(r, 10000));
|
|
87
|
+
retriesAllowed--;
|
|
88
|
+
}
|
|
89
|
+
if (retriesAllowed === 0) {
|
|
90
|
+
logger.error(`deployment id: ${uploadId} status: ${color.red('failed to check the upload status')}`);
|
|
91
|
+
throw new Error(result.toString());
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function cleanupTmpDir(tmpDir: string) {
|
|
98
|
+
await fsp.rm(tmpDir, { force: true, recursive: true }).catch((error: any) => {
|
|
99
|
+
logger.error('failed to remove temp directory', error);
|
|
100
|
+
});
|
|
101
|
+
}
|