@leverege/build-tools 2.21.7 → 2.21.8
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/lib/server/build-tools.js +4 -24
- package/lib/server/firebaseDeploy.js +2 -19
- package/lib/server/firebaseServe.js +2 -23
- package/lib/server/getfbcfg.js +1 -3
- package/lib/server/getjson.js +3 -7
- package/lib/server/npm-scripts/postinstall.js +0 -4
- package/lib/server/overwhelm.js +68 -90
- package/lib/server/unleash.js +2 -10
- package/lib/web/build-tools.js +4 -24
- package/lib/web/firebaseDeploy.js +2 -19
- package/lib/web/firebaseServe.js +2 -23
- package/lib/web/getfbcfg.js +1 -3
- package/lib/web/getjson.js +3 -7
- package/lib/web/npm-scripts/postinstall.js +0 -4
- package/lib/web/overwhelm.js +68 -90
- package/lib/web/unleash.js +2 -10
- package/package.json +6 -6
- package/src/helmup +1 -1
package/lib/server/overwhelm.js
CHANGED
|
@@ -4,26 +4,16 @@
|
|
|
4
4
|
"use strict";
|
|
5
5
|
|
|
6
6
|
const chalk = require('chalk');
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
const cliArgs = require('command-line-args');
|
|
8
|
+
// const cliHelp = require( 'command-line-usage' )
|
|
11
9
|
const deepmerge = require('deepmerge');
|
|
12
|
-
|
|
13
10
|
const exec = require('child_process').execSync;
|
|
14
|
-
|
|
15
11
|
const fs = require('fs');
|
|
16
|
-
|
|
17
12
|
const glob = require('glob');
|
|
18
|
-
|
|
19
13
|
const parse = require('parse-gitignore');
|
|
20
|
-
|
|
21
14
|
const ask = require('readline-sync');
|
|
22
|
-
|
|
23
15
|
const YAML = require('js-yaml');
|
|
24
|
-
|
|
25
|
-
const optionsDefinitions = [
|
|
26
|
-
/* eslint-disable no-multi-spaces */
|
|
16
|
+
const optionsDefinitions = [/* eslint-disable no-multi-spaces */
|
|
27
17
|
{
|
|
28
18
|
name: 'context',
|
|
29
19
|
alias: 'x',
|
|
@@ -53,39 +43,41 @@ const optionsDefinitions = [
|
|
|
53
43
|
alias: 't',
|
|
54
44
|
type: Boolean,
|
|
55
45
|
default: false
|
|
56
|
-
},
|
|
46
|
+
},
|
|
47
|
+
// checks overwhelm context
|
|
57
48
|
{
|
|
58
49
|
name: 'fetchctx',
|
|
59
50
|
alias: 'f',
|
|
60
51
|
type: Boolean,
|
|
61
52
|
default: false
|
|
62
|
-
},
|
|
53
|
+
},
|
|
54
|
+
// fetch and set k8s context
|
|
63
55
|
{
|
|
64
56
|
name: 'matchk8s',
|
|
65
57
|
alias: 'm',
|
|
66
58
|
type: Boolean,
|
|
67
59
|
default: false
|
|
68
|
-
},
|
|
60
|
+
},
|
|
61
|
+
// checks k8s context
|
|
69
62
|
{
|
|
70
63
|
name: 'verbose',
|
|
71
64
|
alias: 'v',
|
|
72
65
|
type: Boolean,
|
|
73
66
|
default: false
|
|
74
67
|
}
|
|
75
|
-
/* eslint-enable no-multi-spaces */
|
|
76
|
-
];
|
|
77
|
-
const args = cliArgs(optionsDefinitions); // The kubernetes context is equal to the git branch name.
|
|
68
|
+
/* eslint-enable no-multi-spaces */];
|
|
78
69
|
|
|
70
|
+
const args = cliArgs(optionsDefinitions);
|
|
71
|
+
|
|
72
|
+
// The kubernetes context is equal to the git branch name.
|
|
79
73
|
const gitBranch = exec('git rev-parse --abbrev-ref HEAD', {
|
|
80
74
|
stdio: [undefined]
|
|
81
75
|
}).toString().trim();
|
|
82
76
|
const context = args.context || gitBranch;
|
|
83
|
-
|
|
84
77
|
if (context === 'master') {
|
|
85
78
|
console.log('***ERROR: master context is forbidden; change to a different branch\n\n');
|
|
86
79
|
process.exit(1);
|
|
87
80
|
}
|
|
88
|
-
|
|
89
81
|
if (!fs.existsSync('overwhelm.yaml')) {
|
|
90
82
|
console.log(chalk.red.bold(`
|
|
91
83
|
|
|
@@ -93,7 +85,9 @@ if (!fs.existsSync('overwhelm.yaml')) {
|
|
|
93
85
|
to execute from within a platform-k8s branch
|
|
94
86
|
`));
|
|
95
87
|
process.exit(1);
|
|
96
|
-
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Load the default values and then overlay with the project specific yaml
|
|
97
91
|
// values. This supports the notion of this type of approach in the
|
|
98
92
|
// overwhelm yaml settings:
|
|
99
93
|
// default:
|
|
@@ -106,24 +100,20 @@ if (!fs.existsSync('overwhelm.yaml')) {
|
|
|
106
100
|
// approach in order to keep us cognizant of exactly where a cluster is
|
|
107
101
|
// being formed.
|
|
108
102
|
//
|
|
109
|
-
|
|
110
|
-
|
|
111
103
|
const yaml = YAML.load(fs.readFileSync('overwhelm.yaml', 'utf-8'));
|
|
112
104
|
const over = yaml.default;
|
|
113
|
-
|
|
114
105
|
if (process.env.OVERWHELM_DEBUG) {
|
|
115
106
|
console.log({
|
|
116
107
|
over,
|
|
117
108
|
yaml
|
|
118
109
|
}, '<==Contents of the over and yaml structs');
|
|
119
110
|
}
|
|
111
|
+
let cfgs = yaml[context];
|
|
120
112
|
|
|
121
|
-
|
|
122
|
-
|
|
113
|
+
// If we just need to check context return 0 if cfgs exists, else error.
|
|
123
114
|
if (args.checkctx) {
|
|
124
115
|
process.exit(!cfgs);
|
|
125
116
|
}
|
|
126
|
-
|
|
127
117
|
if (!cfgs) {
|
|
128
118
|
console.log(`***ERROR: Unknown context => [${context}]\n`);
|
|
129
119
|
console.log(' Known k8s contexts are:');
|
|
@@ -134,9 +124,9 @@ if (!cfgs) {
|
|
|
134
124
|
});
|
|
135
125
|
console.log(`Add a section into overwhelm.yaml for ${context}\n\n`);
|
|
136
126
|
process.exit(1);
|
|
137
|
-
}
|
|
138
|
-
|
|
127
|
+
}
|
|
139
128
|
|
|
129
|
+
// Check to see if we are deriving from another configuration.
|
|
140
130
|
if (cfgs['PROJECT_BASE']) {
|
|
141
131
|
const baseName = cfgs['PROJECT_BASE'];
|
|
142
132
|
const tempCfgs = cfgs;
|
|
@@ -151,7 +141,9 @@ if (cfgs['PROJECT_BASE']) {
|
|
|
151
141
|
|
|
152
142
|
Object.keys(cfgs).forEach(key => {
|
|
153
143
|
over[key] = cfgs[key] || over[key];
|
|
154
|
-
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// Expand any variables that reference other variable settings. A perfect
|
|
155
147
|
// example of where this is useful is in the setting of a PROJECT_NAME and
|
|
156
148
|
// a PROJECT_ID. Most of the time these values are identical, which is why
|
|
157
149
|
// this setting exists in the default section:
|
|
@@ -164,12 +156,11 @@ Object.keys(cfgs).forEach(key => {
|
|
|
164
156
|
// PROJECT_NAME : siren-marine
|
|
165
157
|
// PROJECT_ID : prod-rt-data
|
|
166
158
|
//
|
|
167
|
-
|
|
168
159
|
const varErrors = [];
|
|
169
160
|
Object.keys(over).forEach(key => {
|
|
170
161
|
if (!over[key]) return; // no value to work with - skip it
|
|
171
|
-
// Look for something in the form of "thing-${VAR1}-${VAR2}-${VARn}-stuff"
|
|
172
162
|
|
|
163
|
+
// Look for something in the form of "thing-${VAR1}-${VAR2}-${VARn}-stuff"
|
|
173
164
|
const matches = over[key].match(/\$\{\w+\}/g);
|
|
174
165
|
if (!matches) return;
|
|
175
166
|
matches.forEach(replaceThis => {
|
|
@@ -177,17 +168,14 @@ Object.keys(over).forEach(key => {
|
|
|
177
168
|
// the ${} characters before using the VARNAME to map into the
|
|
178
169
|
// overwhelm map containing the desired replacement value.
|
|
179
170
|
const withThat = over[replaceThis.replace(/\W+/g, '')];
|
|
180
|
-
|
|
181
171
|
if (!withThat) {
|
|
182
172
|
varErrors.push(`${key} : ${over[key]}`);
|
|
183
173
|
return;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
|
|
174
|
+
}
|
|
175
|
+
// Store the replaced string back in the overwhelm value map.
|
|
187
176
|
over[key] = over[key].replace(replaceThis, withThat);
|
|
188
177
|
});
|
|
189
178
|
});
|
|
190
|
-
|
|
191
179
|
if (varErrors.length > 0) {
|
|
192
180
|
console.log('***ERROR: unkown variable reference(s) in overwhelm.yaml:\n');
|
|
193
181
|
varErrors.forEach(error => {
|
|
@@ -195,27 +183,28 @@ if (varErrors.length > 0) {
|
|
|
195
183
|
});
|
|
196
184
|
console.log('');
|
|
197
185
|
process.exit(1);
|
|
198
|
-
}
|
|
186
|
+
}
|
|
199
187
|
|
|
188
|
+
// Grab a list of the existing yaml templates.
|
|
189
|
+
const yams = glob.sync('values-*.yaml');
|
|
200
190
|
|
|
201
|
-
|
|
191
|
+
// A function to apply the replacements to all of the matching yaml which
|
|
202
192
|
// will error out if it runs into an unknown OVH<tag>.
|
|
203
|
-
|
|
204
193
|
const doReplacements = (yamls, replacements) => {
|
|
205
|
-
let replYaml = yamls;
|
|
194
|
+
let replYaml = yamls;
|
|
206
195
|
|
|
196
|
+
// wrap special chars with quotes if needed, like "#---incident-alerts---"
|
|
207
197
|
const quoteSpecials = raw => {
|
|
208
198
|
return /[#$?*]/g.test(raw) ? `"${raw}"` : raw;
|
|
209
199
|
};
|
|
210
|
-
|
|
211
200
|
Object.keys(replacements).forEach(repl => {
|
|
212
201
|
const replaceThis = new RegExp(`OVH:<${repl}>`, 'g');
|
|
213
202
|
const withThat = quoteSpecials(`${replacements[repl]}`);
|
|
214
203
|
replYaml = replYaml.replace(replaceThis, withThat);
|
|
215
|
-
});
|
|
204
|
+
});
|
|
216
205
|
|
|
206
|
+
// Verify all replaceables have been handled, or error out.
|
|
217
207
|
const missed = replYaml.match(/OVH:<(.*)>/g);
|
|
218
|
-
|
|
219
208
|
if (missed) {
|
|
220
209
|
console.log('\n***ERROR: missing replacements in overwhelm.yaml for these tags:\n');
|
|
221
210
|
missed.forEach(miss => {
|
|
@@ -224,12 +213,11 @@ const doReplacements = (yamls, replacements) => {
|
|
|
224
213
|
console.log('');
|
|
225
214
|
process.exit(1);
|
|
226
215
|
}
|
|
227
|
-
|
|
228
216
|
return replYaml;
|
|
229
|
-
};
|
|
230
|
-
// platform yamls to be in that list.
|
|
231
|
-
|
|
217
|
+
};
|
|
232
218
|
|
|
219
|
+
// Collect all of the yaml from the yams, and always expect the default and
|
|
220
|
+
// platform yamls to be in that list.
|
|
233
221
|
const buildYaml = (yamls, replacements) => {
|
|
234
222
|
// We always start with default but values-platform is no longer needed.
|
|
235
223
|
const always = ['values-default.yaml'];
|
|
@@ -241,7 +229,6 @@ const buildYaml = (yamls, replacements) => {
|
|
|
241
229
|
console.log(`\n***ERROR: yaml file missing => ${yaml}\n`);
|
|
242
230
|
process.exit(1);
|
|
243
231
|
}
|
|
244
|
-
|
|
245
232
|
if (!loaded.includes(yaml)) {
|
|
246
233
|
allYamls += `\n# AHOY => ${yaml}\n\n`;
|
|
247
234
|
allYamls += fs.readFileSync(yaml, {
|
|
@@ -249,40 +236,40 @@ const buildYaml = (yamls, replacements) => {
|
|
|
249
236
|
});
|
|
250
237
|
loaded.push(yaml);
|
|
251
238
|
}
|
|
252
|
-
});
|
|
239
|
+
});
|
|
253
240
|
|
|
241
|
+
// Now apply all of the replacements from the overwhelm file.
|
|
254
242
|
return doReplacements(allYamls, replacements);
|
|
255
|
-
};
|
|
256
|
-
|
|
243
|
+
};
|
|
257
244
|
|
|
258
|
-
|
|
245
|
+
// Call buildYaml to replace the OVH strings in the yaml files.
|
|
246
|
+
const values = buildYaml(yams, over);
|
|
259
247
|
|
|
248
|
+
// Check to see if someone is requesting a value from the yaml.
|
|
260
249
|
if (args.key) {
|
|
261
250
|
const section = args.section || 'default';
|
|
262
251
|
const keys = yaml[section];
|
|
263
|
-
|
|
264
252
|
if (args.verbose) {
|
|
265
253
|
console.log('replacements');
|
|
266
254
|
console.log(keys);
|
|
267
255
|
}
|
|
268
|
-
|
|
269
256
|
if (args.export) {
|
|
270
257
|
console.log(`export ${args.key}=${keys[args.key]}`);
|
|
271
258
|
} else {
|
|
272
259
|
console.log(keys[args.key]);
|
|
273
260
|
}
|
|
274
|
-
|
|
275
261
|
if (!args.continue) process.exit();
|
|
276
|
-
}
|
|
277
|
-
|
|
262
|
+
}
|
|
278
263
|
|
|
264
|
+
// Find all of the potential target dirs. Utilize .gitignore to ignore files
|
|
279
265
|
const gitignore = parse(fs.readFileSync('.gitignore'));
|
|
280
266
|
const opt = {
|
|
281
267
|
ignore: gitignore.patterns
|
|
282
268
|
};
|
|
283
|
-
const ahoy = glob.sync('*/', opt);
|
|
284
|
-
// .nohelm = overwhelm and helmup will skip the deployment entirely
|
|
269
|
+
const ahoy = glob.sync('*/', opt);
|
|
285
270
|
|
|
271
|
+
// .noahoy = skips generation of values.yaml but allows helmup to run
|
|
272
|
+
// .nohelm = overwhelm and helmup will skip the deployment entirely
|
|
286
273
|
ahoy.forEach(dir => {
|
|
287
274
|
if (fs.existsSync(`${dir}/.noahoy`)) {
|
|
288
275
|
!args.fetchctx && console.log(chalk.yellow(`***WARNING: .noahoy detected, not regenerating ${dir}values.yaml`));
|
|
@@ -290,23 +277,21 @@ ahoy.forEach(dir => {
|
|
|
290
277
|
args.verbose && console.log(`Generating values in ${dir}`); // eslint-disable-line no-unused-expressions
|
|
291
278
|
|
|
292
279
|
let valuesOut = []; // An accumulator for all of the output values.
|
|
293
|
-
// Add support for localized values for things like keel (or whatever)
|
|
294
280
|
|
|
281
|
+
// Add support for localized values for things like keel (or whatever)
|
|
295
282
|
const valuesLocal = `${dir}values-local.yaml`;
|
|
296
|
-
|
|
297
283
|
if (fs.existsSync(valuesLocal)) {
|
|
298
284
|
args.verbose && console.log(` Local values in ${valuesLocal}`); // eslint-disable-line no-unused-expressions
|
|
299
|
-
|
|
300
285
|
valuesOut += '\n# AHOY => values-local.yaml\n\n';
|
|
301
286
|
valuesOut += fs.readFileSync(valuesLocal, {
|
|
302
287
|
encoding: 'utf-8'
|
|
303
288
|
});
|
|
304
289
|
}
|
|
290
|
+
valuesOut += `\n${values}`;
|
|
305
291
|
|
|
306
|
-
|
|
292
|
+
// Augment the default service section of the YAML with settings that
|
|
307
293
|
// usually come from the top level overwhelm.yaml file.
|
|
308
294
|
//
|
|
309
|
-
|
|
310
295
|
const valuesAll = YAML.load(valuesOut);
|
|
311
296
|
const valuesSvc = {
|
|
312
297
|
service: {
|
|
@@ -319,12 +304,12 @@ ahoy.forEach(dir => {
|
|
|
319
304
|
const valuesMerged = YAML.dump(deepmerge(valuesSvc, valuesAll), {
|
|
320
305
|
quotingType: '"'
|
|
321
306
|
});
|
|
322
|
-
valuesOut = doReplacements(valuesMerged, over);
|
|
307
|
+
valuesOut = doReplacements(valuesMerged, over);
|
|
308
|
+
|
|
309
|
+
// DEPRECATED once siren and manheim are platform 4.0
|
|
323
310
|
// If we are going to override then we need to convert it to YAML and
|
|
324
311
|
// do a deepmerge to combine the values.
|
|
325
|
-
|
|
326
312
|
const valuesOverride = `${dir}/values-override.yaml`;
|
|
327
|
-
|
|
328
313
|
if (fs.existsSync(valuesOverride)) {
|
|
329
314
|
console.log(`===>Applying Overrides=> ${valuesOverride}`);
|
|
330
315
|
const overrides = YAML.load(fs.readFileSync(valuesOverride, {
|
|
@@ -334,13 +319,14 @@ ahoy.forEach(dir => {
|
|
|
334
319
|
valuesOut = YAML.dump(deepmerge(allValues, overrides), {
|
|
335
320
|
quotingType: '"'
|
|
336
321
|
});
|
|
337
|
-
}
|
|
338
|
-
|
|
322
|
+
}
|
|
323
|
+
// DEPRECATED
|
|
339
324
|
|
|
340
325
|
fs.writeFileSync(`${dir}/values.yaml`, valuesOut);
|
|
341
326
|
}
|
|
342
|
-
});
|
|
327
|
+
});
|
|
343
328
|
|
|
329
|
+
// we can also apply replaceables to any top level .ovh files to support top level config maps
|
|
344
330
|
glob.sync('**/*.ovh').forEach(cfgmap => {
|
|
345
331
|
const target = cfgmap.replace(/.ovh$/, '');
|
|
346
332
|
let valuesOut = fs.readFileSync(cfgmap, {
|
|
@@ -348,17 +334,15 @@ glob.sync('**/*.ovh').forEach(cfgmap => {
|
|
|
348
334
|
});
|
|
349
335
|
valuesOut = doReplacements(valuesOut, over);
|
|
350
336
|
fs.writeFileSync(target, valuesOut);
|
|
351
|
-
});
|
|
337
|
+
});
|
|
352
338
|
|
|
339
|
+
// Set the GCP context for safety!
|
|
353
340
|
const clusterName = over.CLUSTER_NAME;
|
|
354
|
-
|
|
355
341
|
if (over.PROJECT_NAME === 'minikube') {
|
|
356
342
|
process.exit(0);
|
|
357
343
|
}
|
|
358
|
-
|
|
359
344
|
const projectId = over.PROJECT_ID;
|
|
360
345
|
let zone = over['GCE_REGION'] + (over['GCE_ZONE'] ? `-${over['GCE_ZONE']}` : '');
|
|
361
|
-
|
|
362
346
|
if (!clusterName) {
|
|
363
347
|
console.log(chalk.yellow(`
|
|
364
348
|
|
|
@@ -377,35 +361,34 @@ if (!clusterName) {
|
|
|
377
361
|
`));
|
|
378
362
|
process.exit(1);
|
|
379
363
|
}
|
|
380
|
-
|
|
381
364
|
let kubeout = '_no_current_context_';
|
|
382
|
-
|
|
383
365
|
try {
|
|
384
366
|
kubeout = exec('kubectl config current-context', {
|
|
385
367
|
stdio: [undefined]
|
|
386
368
|
});
|
|
387
|
-
} catch (err) {
|
|
369
|
+
} catch (err) {
|
|
370
|
+
// err && console.log( `Caught Error =>[${err}]` )
|
|
388
371
|
}
|
|
389
|
-
|
|
390
372
|
const currentCtx = kubeout.toString().trim();
|
|
391
373
|
let desiredCtx = `gke_${projectId}_${zone}_${clusterName}`;
|
|
392
|
-
let cmd = `gcloud container clusters get-credentials ${clusterName} --zone ${zone} --project ${projectId}`;
|
|
374
|
+
let cmd = `gcloud container clusters get-credentials ${clusterName} --zone ${zone} --project ${projectId}`;
|
|
393
375
|
|
|
376
|
+
// Check if we are using AWS
|
|
394
377
|
if (cfgs.CLOUD === 'aws') {
|
|
395
378
|
const awsAcctId = cfgs['AWS_ACCT_ID'];
|
|
396
379
|
zone = over['AWS_REGION'];
|
|
397
380
|
desiredCtx = `arn:aws:eks:${zone}:${awsAcctId}:cluster/${clusterName}`;
|
|
398
381
|
cmd = `aws eks --region ${zone} update-kubeconfig --name ${clusterName}`;
|
|
399
|
-
}
|
|
382
|
+
}
|
|
400
383
|
|
|
384
|
+
// TODO - FETCH AWS CLUSTER CREDENTIALS
|
|
401
385
|
|
|
402
386
|
const matchedCtx = currentCtx === desiredCtx;
|
|
403
|
-
|
|
404
387
|
if (args.matchk8s) {
|
|
405
388
|
process.exit(matchedCtx ? 0 : 1);
|
|
406
|
-
}
|
|
407
|
-
|
|
389
|
+
}
|
|
408
390
|
|
|
391
|
+
// just fetch the context and exit if -f is specified
|
|
409
392
|
if (args.fetchctx) {
|
|
410
393
|
if (!matchedCtx) {
|
|
411
394
|
try {
|
|
@@ -419,7 +402,6 @@ if (args.fetchctx) {
|
|
|
419
402
|
|
|
420
403
|
process.exit(0);
|
|
421
404
|
}
|
|
422
|
-
|
|
423
405
|
if (matchedCtx) {
|
|
424
406
|
console.log(`
|
|
425
407
|
|
|
@@ -435,20 +417,16 @@ if (matchedCtx) {
|
|
|
435
417
|
|
|
436
418
|
`);
|
|
437
419
|
}
|
|
438
|
-
|
|
439
420
|
const operation = matchedCtx ? 'refetch the credentials' : 'switch your context';
|
|
440
421
|
const ans = ask.question(`Enter "${chalk.bold.green('yes')}" if you wish to ${operation} => `);
|
|
441
|
-
|
|
442
422
|
if (ans !== 'yes') {
|
|
443
423
|
if (matchedCtx) {
|
|
444
424
|
console.log(chalk.bold.yellow('\n\nSkipping a refetch of your Kubernetes context and credentials\n\n'));
|
|
445
425
|
process.exit(0);
|
|
446
426
|
}
|
|
447
|
-
|
|
448
427
|
console.log(chalk.bold.red('\n\nYour Kubernetes context and credentials do NOT match - this could be bad!\n\n'));
|
|
449
428
|
process.exit(1);
|
|
450
429
|
}
|
|
451
|
-
|
|
452
430
|
console.log(`\n\nExecuting: ${chalk.bold.yellow(cmd)}\n\n`);
|
|
453
431
|
exec(`${cmd}`, (error, out) => {
|
|
454
432
|
if (error) {
|
package/lib/server/unleash.js
CHANGED
|
@@ -2,27 +2,22 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
const execa = require('execa');
|
|
5
|
-
|
|
6
5
|
const SimpleGit = require('simple-git');
|
|
7
|
-
|
|
8
6
|
const git = new SimpleGit();
|
|
9
|
-
|
|
10
7
|
const getCurrentBranchName = async () => {
|
|
11
|
-
const branchInfo = await git.branch();
|
|
8
|
+
const branchInfo = await git.branch();
|
|
12
9
|
|
|
10
|
+
// first check to see if there are no branches - new repo?
|
|
13
11
|
if (Object.keys(branchInfo.branches).length === 0) {
|
|
14
12
|
return '';
|
|
15
13
|
}
|
|
16
|
-
|
|
17
14
|
return Object.entries(branchInfo.branches).find(([name, info]) => info.current)[0];
|
|
18
15
|
};
|
|
19
|
-
|
|
20
16
|
const isProtected = async () => {
|
|
21
17
|
const protectedBranches = ['main', 'master', 'development', ...process.argv.slice(2)];
|
|
22
18
|
const theBranch = await getCurrentBranchName();
|
|
23
19
|
return protectedBranches.includes(theBranch);
|
|
24
20
|
};
|
|
25
|
-
|
|
26
21
|
const npmRunner = async script => {
|
|
27
22
|
try {
|
|
28
23
|
const results = await execa('npm', ['run', script], {
|
|
@@ -32,14 +27,11 @@ const npmRunner = async script => {
|
|
|
32
27
|
} catch (err) {
|
|
33
28
|
process.exit(1);
|
|
34
29
|
}
|
|
35
|
-
|
|
36
30
|
return undefined;
|
|
37
31
|
};
|
|
38
|
-
|
|
39
32
|
(async () => {
|
|
40
33
|
if (await isProtected()) {
|
|
41
34
|
const script = ['test', 'lint'];
|
|
42
|
-
|
|
43
35
|
for (let i = 0; i < script.length; i++) {
|
|
44
36
|
await npmRunner(script[i]);
|
|
45
37
|
}
|
package/lib/web/build-tools.js
CHANGED
|
@@ -2,22 +2,17 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
const chalk = require('chalk');
|
|
5
|
-
|
|
6
5
|
const cliArgs = require('command-line-args');
|
|
7
|
-
|
|
8
6
|
const cliHelp = require('command-line-usage');
|
|
9
|
-
|
|
10
7
|
const fs = require('fs');
|
|
11
|
-
|
|
12
8
|
const npmRegistryFetch = require('npm-registry-fetch');
|
|
13
|
-
|
|
14
9
|
const path = require('path');
|
|
15
|
-
|
|
16
10
|
const semverLt = require('semver/functions/lt');
|
|
17
|
-
/* eslint-disable no-console */
|
|
18
11
|
|
|
12
|
+
/* eslint-disable no-console */
|
|
19
13
|
|
|
20
|
-
const optionList = [
|
|
14
|
+
const optionList = [
|
|
15
|
+
// Use optionList to tie into the Usage statements
|
|
21
16
|
{
|
|
22
17
|
name: 'root',
|
|
23
18
|
type: Boolean,
|
|
@@ -63,46 +58,36 @@ const args = cliArgs(optionList, {
|
|
|
63
58
|
});
|
|
64
59
|
const help = cliHelp(sections);
|
|
65
60
|
const repoRoot = path.dirname(__dirname);
|
|
66
|
-
|
|
67
61
|
const thisPackage = require(`${repoRoot}/package.json`);
|
|
68
|
-
|
|
69
62
|
const thisVersion = thisPackage.version;
|
|
70
|
-
|
|
71
63
|
if (args.root) {
|
|
72
64
|
console.log(repoRoot);
|
|
73
65
|
process.exit(0);
|
|
74
66
|
}
|
|
75
|
-
|
|
76
67
|
if (args.bashfun) {
|
|
77
68
|
console.log(`${repoRoot}/src/bash-funcs`);
|
|
78
69
|
process.exit(0);
|
|
79
70
|
}
|
|
80
|
-
|
|
81
71
|
const checkForLatest = async (pkg = '@leverege/build-tools') => {
|
|
82
72
|
const getToken = () => {
|
|
83
73
|
const tokenFile = `${process.env.HOME}/.npmrc`;
|
|
84
|
-
|
|
85
74
|
if (!fs.existsSync(tokenFile)) {
|
|
86
75
|
console.error(`Cannot find token file ${tokenFile}`);
|
|
87
76
|
process.exit(1);
|
|
88
77
|
}
|
|
89
|
-
|
|
90
78
|
try {
|
|
91
79
|
const tokenLine = fs.readFileSync(tokenFile).toString();
|
|
92
80
|
const tokenRegX = new RegExp('.*registry.npmjs.org\\/:\\w+=+(.*)');
|
|
93
81
|
const tokenStr = tokenLine.match(tokenRegX);
|
|
94
|
-
|
|
95
82
|
if (!tokenStr) {
|
|
96
83
|
console.error(`\n***ERROR: malformed npm token in ${tokenFile}\n`);
|
|
97
84
|
process.exit(1);
|
|
98
85
|
}
|
|
99
|
-
|
|
100
86
|
return tokenLine.match(tokenRegX)[1];
|
|
101
87
|
} catch (err) {
|
|
102
88
|
console.error(err);
|
|
103
89
|
}
|
|
104
90
|
};
|
|
105
|
-
|
|
106
91
|
try {
|
|
107
92
|
const list = await npmRegistryFetch.json(pkg, {
|
|
108
93
|
'//registry.npmjs.org/:_authToken': getToken()
|
|
@@ -112,7 +97,6 @@ const checkForLatest = async (pkg = '@leverege/build-tools') => {
|
|
|
112
97
|
console.log(err);
|
|
113
98
|
}
|
|
114
99
|
};
|
|
115
|
-
|
|
116
100
|
const checkAndAnnounce = () => {
|
|
117
101
|
checkForLatest().then(latestVersion => {
|
|
118
102
|
if (semverLt(thisVersion, latestVersion)) {
|
|
@@ -126,23 +110,19 @@ const checkAndAnnounce = () => {
|
|
|
126
110
|
}
|
|
127
111
|
}).catch(err => {});
|
|
128
112
|
};
|
|
129
|
-
|
|
130
113
|
if (args.latest) {
|
|
131
114
|
checkAndAnnounce();
|
|
132
115
|
}
|
|
133
|
-
|
|
134
116
|
if (args.version) {
|
|
135
117
|
console.log(`build-tools version ${thisVersion}`);
|
|
136
118
|
checkAndAnnounce();
|
|
137
119
|
}
|
|
138
|
-
|
|
139
120
|
if (args.help) {
|
|
140
121
|
console.log(help);
|
|
141
122
|
process.exit(0);
|
|
142
123
|
}
|
|
143
|
-
/* eslint-disable no-underscore-dangle */
|
|
144
|
-
|
|
145
124
|
|
|
125
|
+
/* eslint-disable no-underscore-dangle */
|
|
146
126
|
if (args._unknown) {
|
|
147
127
|
console.log(`\nUnrecognized argument [${args._unknown}] try --help\n`);
|
|
148
128
|
process.exit(1);
|
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// https://github.com/google/zx
|
|
3
|
-
|
|
4
3
|
/* eslint-disable max-len */
|
|
5
4
|
"use strict";
|
|
6
5
|
|
|
7
6
|
var _enquirer = _interopRequireDefault(require("enquirer"));
|
|
8
|
-
|
|
9
7
|
var _zx = require("zx");
|
|
10
|
-
|
|
11
8
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
12
|
-
|
|
13
9
|
const {
|
|
14
10
|
prompt
|
|
15
|
-
} = _enquirer.default;
|
|
11
|
+
} = _enquirer.default;
|
|
16
12
|
|
|
13
|
+
// This will preserve coloration from spawned child processes
|
|
17
14
|
process.env.FORCE_COLORS = 3;
|
|
18
15
|
process.env.FORCE_COLOR = '1';
|
|
19
16
|
let TARGET = _zx.argv._[0];
|
|
@@ -21,19 +18,15 @@ let exited = false;
|
|
|
21
18
|
const SECRETS_DIR = 'secrets';
|
|
22
19
|
const EXIT_EVENTS = ['SIGINT', 'exit', 'uncaughException', 'unhandledRejection'];
|
|
23
20
|
const [firebaserc, firebaseJson] = await Promise.all([_zx.fs.exists(_zx.path.join(process.cwd(), '.firebaserc')), _zx.fs.exists(_zx.path.join(process.cwd(), 'firebase.json'))]);
|
|
24
|
-
|
|
25
21
|
if (!firebaserc) {
|
|
26
22
|
console.log(_zx.chalk.red('No .firebaserc file found. Make sure that you are executing firebaseDeploy from within a firebase project directory.'));
|
|
27
23
|
}
|
|
28
|
-
|
|
29
24
|
if (!firebaseJson) {
|
|
30
25
|
console.log(_zx.chalk.red('No firebase.json file found. Make sure that you are executing firebaseDeploy from within a firebase project directory.'));
|
|
31
26
|
}
|
|
32
|
-
|
|
33
27
|
if (!firebaserc || !firebaseJson) {
|
|
34
28
|
process.exit();
|
|
35
29
|
}
|
|
36
|
-
|
|
37
30
|
const firebasercContent = JSON.parse(await _zx.fs.readFile(_zx.path.join(process.cwd(), '.firebaserc'), {
|
|
38
31
|
encoding: 'utf-8'
|
|
39
32
|
}));
|
|
@@ -49,7 +42,6 @@ const targets = Object.entries(firebasercContent.targets).reduce((prev, [project
|
|
|
49
42
|
});
|
|
50
43
|
return prev;
|
|
51
44
|
}, {});
|
|
52
|
-
|
|
53
45
|
if (!TARGET) {
|
|
54
46
|
const {
|
|
55
47
|
targetEnv
|
|
@@ -66,27 +58,21 @@ if (!TARGET) {
|
|
|
66
58
|
} else {
|
|
67
59
|
TARGET = targets[TARGET];
|
|
68
60
|
}
|
|
69
|
-
|
|
70
61
|
if (!TARGET) {
|
|
71
62
|
console.log(_zx.chalk.red('No such target exists in .firebaserc config.'));
|
|
72
63
|
process.exit();
|
|
73
64
|
}
|
|
74
|
-
|
|
75
65
|
const [aliasFileExists, siteIdFileExists, sharedFileExists] = await Promise.all([_zx.fs.exists(_zx.path.join(process.cwd(), SECRETS_DIR, `${TARGET.alias}.env`)), _zx.fs.exists(_zx.path.join(process.cwd(), SECRETS_DIR, `${TARGET.siteId}.env`)), _zx.fs.exists(_zx.path.join(process.cwd(), SECRETS_DIR, 'shared.env'))]);
|
|
76
|
-
|
|
77
66
|
if (!aliasFileExists && !siteIdFileExists) {
|
|
78
67
|
console.log(_zx.chalk.red(`No env file for ${TARGET.alias} exists. Check your secrets directory and try again`));
|
|
79
68
|
process.exit();
|
|
80
69
|
}
|
|
81
|
-
|
|
82
70
|
const exec = [];
|
|
83
|
-
|
|
84
71
|
if (sharedFileExists) {
|
|
85
72
|
exec.push(_zx.fs.readFile(_zx.path.join(process.cwd(), SECRETS_DIR, 'shared.env'), {
|
|
86
73
|
encoding: 'utf-8'
|
|
87
74
|
}));
|
|
88
75
|
}
|
|
89
|
-
|
|
90
76
|
if (aliasFileExists) {
|
|
91
77
|
exec.push(_zx.fs.readFile(_zx.path.join(process.cwd(), SECRETS_DIR, `${TARGET.alias}.env`), {
|
|
92
78
|
encoding: 'utf-8'
|
|
@@ -96,19 +82,16 @@ if (aliasFileExists) {
|
|
|
96
82
|
encoding: 'utf-8'
|
|
97
83
|
}));
|
|
98
84
|
}
|
|
99
|
-
|
|
100
85
|
const envFileContent = (await Promise.all(exec)).join('\n');
|
|
101
86
|
EXIT_EVENTS.forEach(event => {
|
|
102
87
|
process.on(event, () => {
|
|
103
88
|
if (!exited) {
|
|
104
89
|
exited = true;
|
|
105
|
-
|
|
106
90
|
_zx.fs.removeSync(_zx.path.join(process.cwd(), '.env.temp'));
|
|
107
91
|
}
|
|
108
92
|
});
|
|
109
93
|
});
|
|
110
94
|
await _zx.fs.writeFile(_zx.path.join(process.cwd(), '.env.temp'), envFileContent);
|
|
111
|
-
|
|
112
95
|
try {
|
|
113
96
|
await (0, _zx.$)`npm run clean && DOTENV_CONFIG_PATH=${_zx.path.join(process.cwd(), '.env.temp')} npm run build && firebase use ${TARGET.projectId} && firebase deploy --only hosting:${TARGET.siteId}`;
|
|
114
97
|
} catch (err) {
|