1
1
const inquirer = require("inquirer");
2
2
const JSONbig = require("json-bigint")({ storeAsString: false });
3
3
const { Command } = require("commander");
4
- const { localConfig } = require("../config");
4
+ const { localConfig, globalConfig } = require("../config");
5
5
const { Spinner, SPINNER_ARC, SPINNER_DOTS } = require('../spinner');
6
6
const { paginate } = require('../paginate');
7
7
const { questionsPushBuckets, questionsPushTeams, questionsPushFunctions, questionsGetEntrypoint, questionsPushCollections, questionsConfirmPushCollections } = require("../questions");
8
8
const { actionRunner, success, log, error, commandDescriptions } = require("../parser");
9
- const { functionsGet, functionsCreate, functionsUpdate, functionsCreateDeployment, functionsUpdateDeployment, functionsListVariables, functionsDeleteVariable, functionsCreateVariable } = require('./functions');
9
+ const { functionsGet, functionsCreate, functionsUpdate, functionsCreateDeployment, functionsUpdateDeployment, functionsGetDeployment, functionsListVariables, functionsDeleteVariable, functionsCreateVariable } = require('./functions');
10
10
const {
11
11
databasesGet,
12
12
databasesCreate,
@@ -40,13 +40,14 @@ const {
40
40
} = require("./teams");
41
41
42
42
const STEP_SIZE = 100; // Resources
43
- const POOL_DEBOUNCE = 2000; // Milliseconds
43
+ const POLL_DEBOUNCE = 2000; // Milliseconds
44
+ const POLL_MAX_DEBOUNCE = 30; // Times
44
45
45
- let poolMaxDebounces = 30;
46
+ let pollMaxDebounces = 30;
46
47
47
48
const awaitPools = {
48
49
wipeAttributes: async (databaseId, collectionId, iteration = 1) => {
49
- if (iteration > poolMaxDebounces ) {
50
+ if (iteration > pollMaxDebounces ) {
50
51
return false;
51
52
}
52
53
@@ -63,12 +64,12 @@ const awaitPools = {
63
64
64
65
let steps = Math.max(1, Math.ceil(total / STEP_SIZE));
65
66
if (steps > 1 && iteration === 1) {
66
- poolMaxDebounces *= steps;
67
+ pollMaxDebounces *= steps;
67
68
68
- log('Found a large number of attributes, increasing timeout to ' + (poolMaxDebounces * POOL_DEBOUNCE / 1000 / 60) + ' minutes')
69
+ log('Found a large number of attributes, increasing timeout to ' + (pollMaxDebounces * POLL_DEBOUNCE / 1000 / 60) + ' minutes')
69
70
}
70
71
71
- await new Promise(resolve => setTimeout(resolve, POOL_DEBOUNCE ));
72
+ await new Promise(resolve => setTimeout(resolve, POLL_DEBOUNCE ));
72
73
73
74
return await awaitPools.wipeAttributes(
74
75
databaseId,
@@ -77,7 +78,7 @@ const awaitPools = {
77
78
);
78
79
},
79
80
wipeIndexes: async (databaseId, collectionId, iteration = 1) => {
80
- if (iteration > poolMaxDebounces ) {
81
+ if (iteration > pollMaxDebounces ) {
81
82
return false;
82
83
}
83
84
@@ -94,12 +95,12 @@ const awaitPools = {
94
95
95
96
let steps = Math.max(1, Math.ceil(total / STEP_SIZE));
96
97
if (steps > 1 && iteration === 1) {
97
- poolMaxDebounces *= steps;
98
+ pollMaxDebounces *= steps;
98
99
99
- log('Found a large number of indexes, increasing timeout to ' + (poolMaxDebounces * POOL_DEBOUNCE / 1000 / 60) + ' minutes')
100
+ log('Found a large number of indexes, increasing timeout to ' + (pollMaxDebounces * POLL_DEBOUNCE / 1000 / 60) + ' minutes')
100
101
}
101
102
102
- await new Promise(resolve => setTimeout(resolve, POOL_DEBOUNCE ));
103
+ await new Promise(resolve => setTimeout(resolve, POLL_DEBOUNCE ));
103
104
104
105
return await awaitPools.wipeIndexes(
105
106
databaseId,
@@ -108,7 +109,7 @@ const awaitPools = {
108
109
);
109
110
},
110
111
wipeVariables: async (functionId, iteration = 1) => {
111
- if (iteration > poolMaxDebounces ) {
112
+ if (iteration > pollMaxDebounces ) {
112
113
return false;
113
114
}
114
115
@@ -124,28 +125,28 @@ const awaitPools = {
124
125
125
126
let steps = Math.max(1, Math.ceil(total / STEP_SIZE));
126
127
if (steps > 1 && iteration === 1) {
127
- poolMaxDebounces *= steps;
128
+ pollMaxDebounces *= steps;
128
129
129
- log('Found a large number of variables, increasing timeout to ' + (poolMaxDebounces * POOL_DEBOUNCE / 1000 / 60) + ' minutes')
130
+ log('Found a large number of variables, increasing timeout to ' + (pollMaxDebounces * POLL_DEBOUNCE / 1000 / 60) + ' minutes')
130
131
}
131
132
132
- await new Promise(resolve => setTimeout(resolve, POOL_DEBOUNCE ));
133
+ await new Promise(resolve => setTimeout(resolve, POLL_DEBOUNCE ));
133
134
134
135
return await awaitPools.wipeVariables(
135
136
functionId,
136
137
iteration + 1
137
138
);
138
139
},
139
140
expectAttributes: async (databaseId, collectionId, attributeKeys, iteration = 1) => {
140
- if (iteration > poolMaxDebounces ) {
141
+ if (iteration > pollMaxDebounces ) {
141
142
return false;
142
143
}
143
144
144
145
let steps = Math.max(1, Math.ceil(attributeKeys.length / STEP_SIZE));
145
146
if (steps > 1 && iteration === 1) {
146
- poolMaxDebounces *= steps;
147
+ pollMaxDebounces *= steps;
147
148
148
- log('Creating a large number of attributes, increasing timeout to ' + (poolMaxDebounces * POOL_DEBOUNCE / 1000 / 60) + ' minutes')
149
+ log('Creating a large number of attributes, increasing timeout to ' + (pollMaxDebounces * POLL_DEBOUNCE / 1000 / 60) + ' minutes')
149
150
}
150
151
151
152
const { attributes } = await paginate(databasesListAttributes, {
@@ -172,7 +173,7 @@ const awaitPools = {
172
173
return true;
173
174
}
174
175
175
- await new Promise(resolve => setTimeout(resolve, POOL_DEBOUNCE ));
176
+ await new Promise(resolve => setTimeout(resolve, POLL_DEBOUNCE ));
176
177
177
178
return await awaitPools.expectAttributes(
178
179
databaseId,
@@ -182,15 +183,15 @@ const awaitPools = {
182
183
);
183
184
},
184
185
expectIndexes: async (databaseId, collectionId, indexKeys, iteration = 1) => {
185
- if (iteration > poolMaxDebounces ) {
186
+ if (iteration > pollMaxDebounces ) {
186
187
return false;
187
188
}
188
189
189
190
let steps = Math.max(1, Math.ceil(indexKeys.length / STEP_SIZE));
190
191
if (steps > 1 && iteration === 1) {
191
- poolMaxDebounces *= steps;
192
+ pollMaxDebounces *= steps;
192
193
193
- log('Creating a large number of indexes, increasing timeout to ' + (poolMaxDebounces * POOL_DEBOUNCE / 1000 / 60) + ' minutes')
194
+ log('Creating a large number of indexes, increasing timeout to ' + (pollMaxDebounces * POLL_DEBOUNCE / 1000 / 60) + ' minutes')
194
195
}
195
196
196
197
const { indexes } = await paginate(databasesListIndexes, {
@@ -217,7 +218,7 @@ const awaitPools = {
217
218
return true;
218
219
}
219
220
220
- await new Promise(resolve => setTimeout(resolve, POOL_DEBOUNCE ));
221
+ await new Promise(resolve => setTimeout(resolve, POLL_DEBOUNCE ));
221
222
222
223
return await awaitPools.expectIndexes(
223
224
databaseId,
@@ -237,7 +238,7 @@ const push = new Command("push")
237
238
command.help()
238
239
}));
239
240
240
- const pushFunction = async ({ functionId, all, yes } = {}) => {
241
+ const pushFunction = async ({ functionId, all, yes, async } = {}) => {
241
242
let response = {};
242
243
243
244
const functionIds = [];
@@ -312,10 +313,13 @@ const pushFunction = async ({ functionId, all, yes } = {}) => {
312
313
313
314
Spinner.start(false);
314
315
let successfullyPushed = 0;
316
+ let successfullyDeployed = 0;
317
+ const failedDeployments = [];
315
318
316
319
await Promise.all(functions.map(async (func) => {
317
320
const ignore = func.ignore ? 'appwrite.json' : '.gitignore';
318
321
let functionExists = false;
322
+ let deploymentCreated = false;
319
323
320
324
const updaterRow = new Spinner({ status: '', resource: func.name, id: func['$id'], end: `Ignoring using: ${ignore}` });
321
325
@@ -437,9 +441,9 @@ const pushFunction = async ({ functionId, all, yes } = {}) => {
437
441
parseOutput: false
438
442
})
439
443
440
- updaterRow.update({ status: 'Pushed' })
444
+ updaterRow.update({ status: 'Pushed' });
445
+ deploymentCreated = true;
441
446
successfullyPushed++;
442
-
443
447
} catch (e) {
444
448
switch (e.code) {
445
449
case 'ENOENT':
@@ -449,12 +453,63 @@ const pushFunction = async ({ functionId, all, yes } = {}) => {
449
453
updaterRow.fail({ errorMessage: e.message ?? 'General error occurs please try again' })
450
454
}
451
455
}
456
+
457
+ if (deploymentCreated && !async) {
458
+ try {
459
+ const deploymentId = response['$id'];
460
+ updaterRow.update({ status: 'Deploying', end: 'Checking deployment status...' })
461
+ let pollChecks = 0;
462
+
463
+ while (true) {
464
+ if (pollChecks >= POLL_MAX_DEBOUNCE) {
465
+ updaterRow.update({ end: 'Deployment is taking too long. Please check the console for more details.' })
466
+ break;
467
+ }
468
+
469
+ response = await functionsGetDeployment({
470
+ functionId: func['$id'],
471
+ deploymentId: deploymentId,
472
+ parseOutput: false
473
+ });
474
+
475
+
476
+ const status = response['status'];
477
+ if (status === 'ready') {
478
+ updaterRow.update({ status: 'Deployed' });
479
+ successfullyDeployed++;
480
+
481
+ break;
482
+ } else if (status === 'failed') {
483
+ failedDeployments.push({ name: func['name'], $id: func['$id'], deployment: response['$id'] });
484
+ updaterRow.fail({ errorMessage: `Failed to deploy` });
485
+
486
+ break;
487
+ } else {
488
+ updaterRow.update({ status: 'Deploying', end: `Current status: ${status}` })
489
+ }
490
+
491
+ pollChecks++;
492
+ await new Promise(resolve => setTimeout(resolve, POLL_DEBOUNCE));
493
+ }
494
+ } catch (e) {
495
+ updaterRow.fail({ errorMessage: e.message ?? 'Unknown error occurred. Please try again' })
496
+ }
497
+ }
498
+
452
499
updaterRow.stopSpinner();
453
500
}));
454
501
455
502
Spinner.stop();
503
+ console.log('\n');
504
+
505
+ failedDeployments.forEach((failed) => {
506
+ const { name, deployment, $id } = failed;
507
+ const failUrl = `${globalConfig.getEndpoint().replace('/v1', '')}/console/project-${localConfig.getProject().projectId}/functions/function-${$id}/deployment-${deployment}`;
508
+
509
+ error(`Deployment of ${name} has failed. Check at ${failUrl} for more details\n`);
510
+ })
456
511
457
- success(`Pushed ${successfullyPushed} functions`);
512
+ success(`Pushed ${successfullyPushed} functions with ${successfullyDeployed} successful deployments. `);
458
513
}
459
514
460
515
const createAttribute = async (databaseId, collectionId, attribute) => {
@@ -958,6 +1013,7 @@ push
958
1013
.option(`--functionId <functionId >`, `Function ID`)
959
1014
.option(`--all`, `Flag to push all functions`)
960
1015
.option(`--yes`, `Flag to confirm all warnings`)
1016
+ .option(`--async`, `Don't wait for functions deployments status`)
961
1017
.action(actionRunner(pushFunction));
962
1018
963
1019
push
0 commit comments