@corva/create-app 0.40.0-0 → 0.41.0-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.
Files changed (49) hide show
  1. package/README.md +19 -17
  2. package/bin/cca.js +5 -0
  3. package/bin/create-corva-app.cjs +14 -0
  4. package/lib/bump-version.option.js +17 -8
  5. package/lib/constants/cli.js +5 -11
  6. package/lib/constants/manifest.js +15 -22
  7. package/lib/constants/messages.js +4 -10
  8. package/lib/constants/package.js +6 -8
  9. package/lib/flow.js +16 -13
  10. package/lib/flows/lib/api.js +153 -84
  11. package/lib/flows/lib/create-zip-archive.js +7 -7
  12. package/lib/flows/lib/json.js +8 -8
  13. package/lib/flows/lib/manifest.js +5 -7
  14. package/lib/flows/lib/step-error.js +1 -3
  15. package/lib/flows/prepare.js +2 -4
  16. package/lib/flows/release.js +18 -10
  17. package/lib/flows/rerun.js +5 -7
  18. package/lib/flows/steps/prepare-load-app-files.js +3 -7
  19. package/lib/flows/steps/release/add-label.js +11 -0
  20. package/lib/flows/steps/release/add-notes.js +10 -0
  21. package/lib/flows/steps/release/get-config.js +37 -0
  22. package/lib/flows/steps/release/prepare-data.js +10 -0
  23. package/lib/flows/steps/release/publish.js +9 -0
  24. package/lib/flows/steps/release/remove-failed-upload.js +20 -0
  25. package/lib/flows/steps/release/upload-zip-to-corva.js +25 -0
  26. package/lib/flows/steps/release/wait-for-build.js +29 -0
  27. package/lib/flows/steps/rerun-create-task.js +22 -15
  28. package/lib/flows/steps/rerun-prepare-data.js +150 -127
  29. package/lib/flows/steps/rerun.js +3 -7
  30. package/lib/flows/steps/zip-cleanup.js +6 -6
  31. package/lib/flows/steps/zip-create-archive.js +5 -5
  32. package/lib/flows/steps/zip-file-list-resolve.js +34 -29
  33. package/lib/flows/steps/zip-prepare.js +7 -8
  34. package/lib/flows/steps/zip.js +5 -9
  35. package/lib/flows/zip-simple.js +2 -4
  36. package/lib/flows/zip.js +3 -5
  37. package/lib/helpers/logger.js +35 -0
  38. package/lib/helpers/manifest.js +6 -10
  39. package/lib/helpers/resolve-app-runtime.js +47 -45
  40. package/lib/helpers/utils.js +4 -9
  41. package/lib/helpers/versioning.js +8 -13
  42. package/lib/{index.js → main.js} +118 -116
  43. package/lib/scripts/utils/version.js +12 -13
  44. package/package.json +5 -3
  45. package/bin/create-corva-app.js +0 -5
  46. package/lib/app.js +0 -9
  47. package/lib/flows/steps/release-get-app-key.js +0 -16
  48. package/lib/flows/steps/release-get-config.js +0 -37
  49. package/lib/flows/steps/release-upload-zip-to-corva.js +0 -25
@@ -1,50 +1,35 @@
1
- const axios = require('axios');
1
+ import got from 'got';
2
+ import Debug from 'debug';
3
+ import { StepError } from './step-error.js';
4
+ import _ from 'lodash/fp.js';
5
+
6
+ const debug = Debug('cca:api');
7
+
8
+ /**
9
+ * Connect to Corva API
10
+ *
11
+ */
12
+ export class Api {
13
+ /**
14
+ * @type {import('got').Got}
15
+ */
16
+ #api;
2
17
 
3
- /**
4
- * Connect to Corva API
5
- *
6
- */
7
- class Api {
8
18
  constructor(envName, apiKey, authToken = null) {
9
- this.baseURL = `https://api${
10
- envName === 'production' ? '' : `.${envName}`
11
- }.corva.ai`;
19
+ const prefixUrl = `https://api${envName === 'production' ? '' : `.${envName}`}.corva.ai`;
12
20
 
13
- this.config = {
21
+ this.#api = got.extend({
22
+ prefixUrl,
23
+ retry: { limit: 0 },
14
24
  headers: {
15
- 'Authorization': authToken ? `Bearer ${authToken}` :`API ${apiKey}`,
25
+ 'Authorization': authToken ? `Bearer ${authToken}` : `API ${apiKey}`,
16
26
  'Content-Type': 'application/json',
17
27
  'Accept': 'application/json',
18
28
  },
19
- };
20
- }
21
-
22
- /**
23
- * Get api url
24
- *
25
- * @private
26
- *
27
- * @param {string} path
28
- *
29
- * @returns {string}
30
- */
31
- getUrl(path) {
32
- return `${this.baseURL}${path}`;
33
- }
34
-
35
- /**
36
- * Send api request
37
- *
38
- * @private
39
- *
40
- * @param {string} path
41
- * @param {string} method
42
- * @param {object} data
43
- *
44
- * @returns {object}
45
- */
46
- sendRequest(method, url, data = null) {
47
- return data ? axios[method](url, data, this.config) : axios[method](url, this.config);
29
+ hooks: {
30
+ beforeRequest: [debug]
31
+ }
32
+ })
48
33
  }
49
34
 
50
35
  /**
@@ -57,10 +42,10 @@ class Api {
57
42
  * @returns {object}
58
43
  */
59
44
  async getAppByKey(appKey) {
60
- const url = this.getUrl(`/v2/apps?per_page=2&search=${appKey}`);
61
- const response = await this.sendRequest('get', url);
45
+ const { data: [app] } = await this.#api.get('v2/apps', {
46
+ searchParams: { per_page: 2, search: appKey }
47
+ }).json();
62
48
 
63
- const app = response.data.data[0];
64
49
  if (!app || app.attributes.app_key != appKey) {
65
50
  throw new Error(`App with key - ${appKey}, not exist`);
66
51
  }
@@ -78,16 +63,13 @@ class Api {
78
63
  * @returns {object}
79
64
  */
80
65
  async getAppDatasetsOperationWrite(appId) {
81
- const url = this.getUrl(
82
- `/v2/apps/${appId}/app_datasets?dataset_operation=write&fields[]=app_dataset.dataset_name`
83
- );
84
- const response = await this.sendRequest('get', url);
66
+ const { data } = await this.#api.get(`v2/apps/${appId}/app_datasets?dataset_operation=write&fields[]=app_dataset.dataset_name`).json();
85
67
 
86
- if (!response.data.data.length) {
87
- throw new Error(`App with ID - ${appId}, has not any datasets`);
68
+ if (!data.length) {
69
+ throw new Error(`App with ID - ${appId}, has no datasets`);
88
70
  }
89
71
 
90
- return response.data.data;
72
+ return data;
91
73
  }
92
74
 
93
75
  /**
@@ -97,16 +79,14 @@ class Api {
97
79
  *
98
80
  * @param {string} assetId
99
81
  *
100
- * @returns {object[]}
82
+ * @returns {Promise<object[]>}
101
83
  */
102
84
  async getAssetById(assetId) {
103
- const url = this.getUrl(`/v2/assets/${assetId}`);
104
- const response = await this.sendRequest('get', url);
85
+ const { data } = await this.#api.get(`v2/assets/${assetId}`).json();
105
86
 
106
- return response.data.data;
87
+ return data;
107
88
  }
108
89
 
109
-
110
90
  /**
111
91
  * Get asset streams
112
92
  *
@@ -116,15 +96,20 @@ class Api {
116
96
  *
117
97
  * @returns {object[]}
118
98
  */
119
- async getStreamByAssetId(assetId) {
120
- const url = this.getUrl(`/v1/app_streams?asset_id=${assetId}&segment=drilling&status=complete`);
121
- const response = await this.sendRequest('get', url);
99
+ async getStreamByAssetId(assetId) {
100
+ const data = await this.#api.get(`v1/app_streams`, {
101
+ searchParams: {
102
+ asset_id: assetId,
103
+ segment: 'drilling',
104
+ status: 'complete'
105
+ }
106
+ }).json();
122
107
 
123
- if (!response.data[0]) {
108
+ if (!data[0]) {
124
109
  throw new Error(`Could not found streams for asset ID - ${assetId}`);
125
110
  }
126
111
 
127
- return response.data;
112
+ return data;
128
113
  }
129
114
 
130
115
  /**
@@ -137,18 +122,13 @@ class Api {
137
122
  * @returns {object[]}
138
123
  */
139
124
  async getWellByAssetId(assetId) {
140
- const data = {
141
- assets: [assetId],
142
- };
125
+ const { wells } = await this.#api.post('v2/assets/resolve', { json: { assets: [assetId], } }).json();
143
126
 
144
- const url = this.getUrl(`/v2/assets/resolve`);
145
- const response = await this.sendRequest('post', url, data);
146
-
147
- if (!response.data.wells.length) {
127
+ if (!wells.length) {
148
128
  throw new Error(`Could not found wells by asset ID - ${assetId}`);
149
129
  }
150
130
 
151
- return response.data.wells;
131
+ return wells;
152
132
  }
153
133
 
154
134
  /**
@@ -165,7 +145,7 @@ class Api {
165
145
  * @returns {object}
166
146
  */
167
147
  async queueAppRun(appId, version, wellId, appDatasetsNames, streamId) {
168
- const data = {
148
+ const json = {
169
149
  app_run: {
170
150
  app_stream_id: streamId,
171
151
  well_id: wellId,
@@ -181,9 +161,9 @@ class Api {
181
161
  },
182
162
  };
183
163
 
184
- const url = this.getUrl(`/v2/apps/${appId}/app_runs`);
185
- const response = await this.sendRequest('post', url, data);
186
- return response.data.data;
164
+ const { data } = await this.#api.post(`v2/apps/${appId}/app_runs`, { json }).json();
165
+
166
+ return data;
187
167
  }
188
168
 
189
169
  /**
@@ -195,11 +175,10 @@ class Api {
195
175
  *
196
176
  * @returns {object[]}
197
177
  */
198
- async getAppRuns(appId) {
199
- const url = this.getUrl(`/v2/apps/${appId}/app_runs?page=1&per_page=500&status[]=pending&status[]=in_progress&status[]=running`);
200
- const response = await this.sendRequest('get', url);
178
+ async getAppRuns(appId) {
179
+ const { data } = await this.#api.get(`v2/apps/${appId}/app_runs?page=1&per_page=500&status[]=pending&status[]=in_progress&status[]=running`).json();
201
180
 
202
- return response.data.data;
181
+ return data;
203
182
  }
204
183
 
205
184
  /**
@@ -212,14 +191,104 @@ class Api {
212
191
  *
213
192
  * @returns
214
193
  */
215
- async uploadPackages(appKey, formData) {
216
- const url = this.getUrl(`/v2/apps/${appKey}/packages/upload`);
217
- this.config.headers = {
218
- ...this.config.headers,
219
- ...formData.getHeaders(),
194
+ async uploadPackages(appKey, formData) {
195
+ const uploadURL = `v2/apps/${appKey}/packages/upload`;
196
+
197
+ try {
198
+ const { data } = await this.#api.post(uploadURL, {
199
+ headers: formData.getHeaders(),
200
+ body: formData,
201
+ }).json();
202
+
203
+ return {
204
+ id: data.id,
205
+ status: data.attributes.status,
220
206
  };
221
- return this.sendRequest('post', url, formData)
207
+ } catch (e) {
208
+ throw new StepError(
209
+ `${JSON.parse(e.response.body).message || ''} \nPOST: ${uploadURL} failed.`,
210
+ { cause: e }
211
+ );
212
+
222
213
  }
223
- }
214
+ }
215
+
216
+
217
+ /**
218
+ * @param {string} appId
219
+ * @param {string} id
220
+ * @param {string} notes
221
+ *
222
+ * @returns { Promise<{id: number, status: string}>}
223
+ */
224
+ async addNotes(appId, id, notes) {
225
+ const { data } = await this.#api.patch(`v2/apps/${appId}/packages/${id}`, {
226
+ json: { package: { notes } },
227
+ }).json();
224
228
 
225
- module.exports = { Api };
229
+ return {
230
+ id: data.id,
231
+ status: data.attributes.status,
232
+ };
233
+ }
234
+
235
+ /**
236
+ * @param {string} appId
237
+ * @param {string} uploadId
238
+ *
239
+ * @returns { Promise<{id: number, status: string}>}
240
+ */
241
+ async checkApp(appId, uploadId) {
242
+ const { data } = await this.#api.get(`v2/apps/${appId}/packages/${uploadId}`).json();
243
+
244
+ return {
245
+ id: data.id,
246
+ status: data.attributes.status,
247
+ };
248
+ }
249
+
250
+ /**
251
+ * @param {string} appId
252
+ * @param {string} uploadId
253
+ *
254
+ * @returns { Promise<void>}
255
+ */
256
+ deleteAppUpload(appId, uploadId) {
257
+ return this.#api.del(`v2/apps/${appId}/packages/${uploadId}`).json();
258
+ }
259
+
260
+ /**
261
+ * @param {string} appId
262
+ * @param {string} id
263
+ *
264
+ * @returns { Promise<{id: number, status: string}>}
265
+ */
266
+ async publishApp(appId, id) {
267
+ console.log(`v2/apps/${appId}/packages/${id}`, {
268
+ json: { package: { status: 'published' } },
269
+ })
270
+ const { data } = await this.#api.patch(`v2/apps/${appId}/packages/${id}`, {
271
+ json: { package: { status: 'published' } },
272
+ }).json();
273
+
274
+ console.log('done')
275
+
276
+ return {
277
+ id: data.id,
278
+ status: data.attributes.status,
279
+ };
280
+ }
281
+
282
+ /**
283
+ * @param {string} appId
284
+ * @param {string} id
285
+ * @param {'BETA' | 'PROD'} label
286
+ *
287
+ * @returns { Promise<{id: number, status: string}>}
288
+ */
289
+ async putLabel(appId, id, label) {
290
+ await this.#api.patch(`v2/apps/${appId}/packages/${id}`, {
291
+ json: { package: { label } },
292
+ });
293
+ }
294
+ }
@@ -1,9 +1,11 @@
1
- const archiver = require('archiver');
2
- const debug = require('debug')('cca:zip');
3
- const { promises: fs, createWriteStream } = require('fs');
4
- const path = require('path');
1
+ import archiver from 'archiver';
2
+ import Debug from 'debug';
5
3
 
6
- const createZipArchive = async (dirName, zipName, itemsToZip = []) => {
4
+ const debug = Debug('cca:zip');
5
+ import { promises as fs, createWriteStream } from 'node:fs';
6
+ import path from 'node:path';
7
+
8
+ export const createZipArchive = async (dirName, zipName, itemsToZip = []) => {
7
9
  const filePath = path.resolve(dirName, zipName);
8
10
  const archive = archiver.create('zip', {});
9
11
  const output = createWriteStream(filePath);
@@ -73,5 +75,3 @@ const getDataToZip = async (itemsToZip, dirName) => {
73
75
 
74
76
  return allData.filter((f) => f.exists);
75
77
  };
76
-
77
- module.exports = { createZipArchive };
@@ -1,10 +1,12 @@
1
- const { resolve } = require('path');
2
- const { promises: fs } = require('fs');
3
- const os = require('os');
1
+ import { resolve } from 'node:path';
2
+ import { promises as fs } from 'node:fs';
3
+ import os from 'node:os';
4
4
 
5
- const debug = require('debug')('cca:json');
5
+ import Debug from 'debug';
6
6
 
7
- const loadJson = async (dirName, fileName) => {
7
+ const debug = Debug('cca:json');
8
+
9
+ export const loadJson = async (dirName, fileName) => {
8
10
  const fullPath = resolve(dirName, fileName);
9
11
 
10
12
  try {
@@ -21,8 +23,6 @@ const loadJson = async (dirName, fileName) => {
21
23
  }
22
24
  };
23
25
 
24
- const saveJson = async (dirName, fileName, data) => {
26
+ export const saveJson = async (dirName, fileName, data) => {
25
27
  return fs.writeFile(resolve(dirName, fileName), JSON.stringify(data, null, 2) + os.EOL);
26
28
  };
27
-
28
- module.exports = { loadJson, saveJson };
@@ -1,8 +1,8 @@
1
- const { APP_TYPES, APP_RUNTIMES } = require('../../constants/cli');
1
+ import { APP_TYPES, APP_RUNTIMES } from '../../constants/cli.js';
2
2
 
3
3
  const NODE_RUNTIMES = [APP_RUNTIMES.NODE12, APP_RUNTIMES.NODE14, APP_RUNTIMES.NODE16];
4
4
 
5
- class Manifest {
5
+ export class Manifest {
6
6
  constructor(manifest) {
7
7
  this.manifest = manifest;
8
8
  }
@@ -12,11 +12,11 @@ class Manifest {
12
12
  }
13
13
 
14
14
  get type() {
15
- return this.manifest.application.type
15
+ return this.manifest.application.type;
16
16
  }
17
17
 
18
18
  get name() {
19
- return this.manifest.application.name
19
+ return this.manifest.application.name;
20
20
  }
21
21
 
22
22
  get unix_name() {
@@ -25,7 +25,7 @@ class Manifest {
25
25
  }
26
26
 
27
27
  get description() {
28
- return this.manifest.application.description
28
+ return this.manifest.application.description;
29
29
  }
30
30
 
31
31
  isNode() {
@@ -48,5 +48,3 @@ class Manifest {
48
48
  return this.manifest.application.type === APP_TYPES.SCHEDULER;
49
49
  }
50
50
  }
51
-
52
- module.exports = { Manifest };
@@ -1,4 +1,4 @@
1
- class StepError extends Error {
1
+ export class StepError extends Error {
2
2
  cause;
3
3
  name;
4
4
 
@@ -8,5 +8,3 @@ class StepError extends Error {
8
8
  this.cause = cause;
9
9
  }
10
10
  }
11
-
12
- module.exports = { StepError };
@@ -1,8 +1,6 @@
1
- const { LOAD_APP_FILES_STEP } = require('./steps/prepare-load-app-files');
1
+ import { LOAD_APP_FILES_STEP } from './steps/prepare-load-app-files.js';
2
2
 
3
- const PREPARE_FLOW = {
3
+ export const PREPARE_FLOW = {
4
4
  name: 'prepare',
5
5
  steps: [LOAD_APP_FILES_STEP],
6
6
  };
7
-
8
- module.exports = { PREPARE_FLOW };
@@ -1,18 +1,26 @@
1
- const { PREPARE_FLOW } = require('./prepare');
2
- const { GET_APP_KEY_STEP } = require('./steps/release-get-app-key');
3
- const { GET_RELEASE_CONFIG_STEP } = require('./steps/release-get-config');
4
- const { UPLOAD_ZIP_TO_CORVA_STEP } = require('./steps/release-upload-zip-to-corva');
5
- const { ZIP_SIMPLE_FLOW } = require('./zip-simple');
1
+ import { PREPARE_FLOW } from './prepare.js';
2
+ import { SETUP_API_CLIENT_STEP } from './steps/release/get-config.js';
3
+ import { UPLOAD_ZIP_TO_CORVA_STEP } from './steps/release/upload-zip-to-corva.js';
4
+ import { ZIP_SIMPLE_FLOW } from './zip-simple.js';
5
+ import { WAIT_FOR_BUILD_FINISH_STEP } from './steps/release/wait-for-build.js';
6
+ import { REMOVE_FAILED_UPLOAD_STEP } from './steps/release/remove-failed-upload.js';
7
+ import { ADD_LABEL_STEP } from './steps/release/add-label.js';
8
+ import { ADD_NOTES_STEP } from './steps/release/add-notes.js';
9
+ import { PUBLISH_PACKAGE_STEP } from './steps/release/publish.js';
10
+ import { RELEASE_PREPARE_DATA_STEP } from './steps/release/prepare-data.js';
6
11
 
7
- const RELEASE_FLOW = {
12
+ export const RELEASE_FLOW = {
8
13
  name: 'release',
9
14
  steps: [
10
15
  PREPARE_FLOW,
11
- GET_RELEASE_CONFIG_STEP,
12
- GET_APP_KEY_STEP,
16
+ SETUP_API_CLIENT_STEP,
17
+ RELEASE_PREPARE_DATA_STEP,
13
18
  ZIP_SIMPLE_FLOW,
14
19
  UPLOAD_ZIP_TO_CORVA_STEP,
20
+ WAIT_FOR_BUILD_FINISH_STEP,
21
+ REMOVE_FAILED_UPLOAD_STEP,
22
+ PUBLISH_PACKAGE_STEP,
23
+ ADD_LABEL_STEP,
24
+ ADD_NOTES_STEP
15
25
  ],
16
26
  };
17
-
18
- module.exports = { RELEASE_FLOW };
@@ -1,10 +1,8 @@
1
- const { PREPARE_FLOW } = require('./prepare');
2
- const { RERUN_STEPS } = require('./steps/rerun');
3
- const { GET_RELEASE_CONFIG_STEP } = require('./steps/release-get-config');
1
+ import { PREPARE_FLOW } from './prepare.js';
2
+ import { RERUN_STEPS } from './steps/rerun.js';
3
+ import { SETUP_API_CLIENT_STEP } from './steps/release/get-config.js';
4
4
 
5
- const RERUN_FLOW = {
5
+ export const RERUN_FLOW = {
6
6
  name: 'rerun',
7
- steps: [PREPARE_FLOW, GET_RELEASE_CONFIG_STEP, ...RERUN_STEPS],
7
+ steps: [PREPARE_FLOW, SETUP_API_CLIENT_STEP, ...RERUN_STEPS],
8
8
  };
9
-
10
- module.exports = { RERUN_FLOW };
@@ -1,7 +1,7 @@
1
- const { loadJson } = require('../lib/json');
2
- const { Manifest } = require('../lib/manifest');
1
+ import { loadJson } from '../lib/json.js';
2
+ import { Manifest } from '../lib/manifest.js';
3
3
 
4
- const LOAD_APP_FILES_STEP = {
4
+ export const LOAD_APP_FILES_STEP = {
5
5
  message: "Loading Corva app's files...",
6
6
  async fn(context) {
7
7
  const manifest =
@@ -12,7 +12,3 @@ const LOAD_APP_FILES_STEP = {
12
12
  return { pkg, manifest };
13
13
  },
14
14
  };
15
-
16
- module.exports = {
17
- LOAD_APP_FILES_STEP,
18
- };
@@ -0,0 +1,11 @@
1
+
2
+ export const ADD_LABEL_STEP = {
3
+ message: 'Adding label...',
4
+ async fn({ options: { label }, api, appId, packageId }) {
5
+ if (!label) {
6
+ return;
7
+ }
8
+
9
+ await api.putLabel(appId, packageId, label);
10
+ }
11
+ }
@@ -0,0 +1,10 @@
1
+ export const ADD_NOTES_STEP = {
2
+ message: 'Adding notes...',
3
+ async fn({ api, appId, packageId, options: { notes } }) {
4
+ if (!notes) {
5
+ return;
6
+ }
7
+
8
+ await api.addNotes(appId, packageId, notes);
9
+ }
10
+ }
@@ -0,0 +1,37 @@
1
+ import { RELEASE } from '../../../constants/messages.js';
2
+ import { promises as fs } from 'node:fs';
3
+ import dotenv from 'dotenv';
4
+ import { resolve } from 'node:path';
5
+ import { StepError } from '../../lib/step-error.js';
6
+ import { Api } from '../../lib/api.js';
7
+
8
+ async function getVarsFromDotEnv({ dirName }) {
9
+ try {
10
+ const envFile = await fs.readFile(resolve(dirName, '.env'));
11
+ return dotenv.parse(envFile);
12
+ } catch (error) {
13
+ return {};
14
+ }
15
+ }
16
+
17
+ export const SETUP_API_CLIENT_STEP = {
18
+ message: RELEASE.getAuthToken,
19
+ fn: async ({ dirName, options: { apiKey, env } }) => {
20
+ const parsedEnv = await getVarsFromDotEnv({ dirName });
21
+
22
+ const CORVA_API_ENV = env || process.env.CORVA_API_ENV || parsedEnv.CORVA_API_ENV;
23
+ const AUTH_TOKEN = process.env.AUTH_TOKEN || parsedEnv.AUTH_TOKEN;
24
+ const API_KEY = apiKey || process.env.API_KEY || parsedEnv.API_KEY;
25
+
26
+ if (!AUTH_TOKEN && !API_KEY) {
27
+ throw new StepError(RELEASE.getAuthTokenError);
28
+ }
29
+
30
+ const api = new Api(CORVA_API_ENV, API_KEY, AUTH_TOKEN);
31
+
32
+ return {
33
+ CORVA_API_ENV: CORVA_API_ENV || 'qa',
34
+ api
35
+ };
36
+ },
37
+ };
@@ -0,0 +1,10 @@
1
+ export const RELEASE_PREPARE_DATA_STEP = {
2
+ message: 'Preparing data...',
3
+ async fn({ api, manifest }) {
4
+ const app = await api.getAppByKey(manifest.manifest.application.key.toLowerCase());
5
+
6
+ return {
7
+ appId: app.id,
8
+ }
9
+ }
10
+ }
@@ -0,0 +1,9 @@
1
+ export const PUBLISH_PACKAGE_STEP = {
2
+ message: 'Publishing app...',
3
+ /**
4
+ *
5
+ * @param {object} param0
6
+ * @param {import('../../lib/api').Api} param0.api
7
+ */
8
+ async fn({ api, appId, packageId }) { await api.publishApp(appId, packageId) }
9
+ }
@@ -0,0 +1,20 @@
1
+ import { resolve } from 'node:path'
2
+ import { unlink } from 'node:fs/promises'
3
+
4
+ export const REMOVE_FAILED_UPLOAD_STEP = {
5
+ message: 'Cleaning up...',
6
+ async fn({ api, appId, packageId, removeOnFail, uploadStatus, dirName, zipFileName }) {
7
+ if (uploadStatus === 'draft') {
8
+ await unlink(resolve(dirName, zipFileName));
9
+
10
+ return;
11
+ }
12
+
13
+ if (removeOnFail) {
14
+ await unlink(resolve(dirName, zipFileName));
15
+ await api.deleteAppUpload(appId, packageId);
16
+ }
17
+
18
+ throw new Error(`Got unexpected status '${uploadStatus}' while processing package ${packageId}.`);
19
+ }
20
+ }
@@ -0,0 +1,25 @@
1
+ import { RELEASE } from '../../../constants/messages.js';
2
+ import FormData from 'form-data';
3
+ import { resolve } from 'node:path';
4
+ import { createReadStream } from 'node:fs';
5
+ import { StepError } from '../../lib/step-error.js';
6
+ import _ from 'lodash/fp.js';
7
+
8
+ export const UPLOAD_ZIP_TO_CORVA_STEP = {
9
+ message: RELEASE.uploadApp,
10
+ /**
11
+ *
12
+ * @param {object} param0
13
+ * @param {import('../../lib/api').Api} param0.api
14
+ * @param {import('../../lib/manifest').Manifest} param0.manifest
15
+ */
16
+ fn: async ({ zipFileName, manifest, api, dirName }) => {
17
+ const form = new FormData();
18
+
19
+ form.append('package', createReadStream(resolve(dirName, zipFileName)), 'package.zip');
20
+
21
+ const { id: packageId, status: uploadStatus } = await api.uploadPackages(manifest.manifest.application.key, form)
22
+
23
+ return { packageId }
24
+ },
25
+ };
@@ -0,0 +1,29 @@
1
+ import Debug from 'debug';
2
+ import { waitForMs } from '../../lib/waitForMs.mjs';
3
+
4
+ const debug = Debug('cca:flow:release:step:wait-for-build');
5
+
6
+ const PROCESSING_STATUSES = ['pending', 'processing', 'queued', 'deploying'];
7
+
8
+ export const WAIT_FOR_BUILD_FINISH_STEP = {
9
+ message: 'Wait till the app will process to draft status...',
10
+ /**
11
+ * @param {object} param0
12
+ * @param {import('../../lib/api').Api} param0.api
13
+ */
14
+ async fn({ api, appId, packageId, progress }) {
15
+ do {
16
+ const { status } = await api.checkApp(appId, packageId);
17
+
18
+ progress()
19
+
20
+ debug(`Status: ${status}`);
21
+
22
+ if (!PROCESSING_STATUSES.includes(status)) {
23
+ return { uploadStatus: status };
24
+ }
25
+
26
+ await waitForMs(5000);
27
+ } while (true);
28
+ }
29
+ }