@leverege/build-tools 2.35.1 → 2.36.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/lib/server/refresh-npm-token.js +78 -0
- package/lib/web/refresh-npm-token.js +78 -0
- package/package.json +10 -8
- package/src/bash-funcs +1 -1
- package/src/circle-lib.yml +150 -0
- package/src/circle-srv.yml +213 -0
- package/src/dockreate +4 -19
- package/src/helm-charts/geotile-server/.nohelm +0 -0
- package/src/helm-charts/geotile-server/gitignore +1 -0
- package/src/helm-charts/geotile-server/helmup.plugin +6 -0
- package/src/helmup +28 -40
- package/src/refresh-npm-token.mjs +80 -0
- package/leverege-build-tools-2.21.13.tgz +0 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
var _nodeFs = _interopRequireDefault(require("node:fs"));
|
|
5
|
+
var _nodeOs = _interopRequireDefault(require("node:os"));
|
|
6
|
+
var _chalk = _interopRequireDefault(require("chalk"));
|
|
7
|
+
var _execa = _interopRequireDefault(require("execa"));
|
|
8
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
9
|
+
// we can't use $ until we upgrade to ESM execa
|
|
10
|
+
// the standard user npmrc token is stored here
|
|
11
|
+
const npmrc = `${_nodeOs.default.homedir()}/.npmrc`;
|
|
12
|
+
|
|
13
|
+
// max age in seconds of the npmrc file before refresh
|
|
14
|
+
const refreshThreshold = 3600 * 24; // 1 day
|
|
15
|
+
|
|
16
|
+
const log = console.log;
|
|
17
|
+
|
|
18
|
+
// calculate number of seconds since last update and exit if the file
|
|
19
|
+
// was recently updated
|
|
20
|
+
let lastUpdated = refreshThreshold * 2; // forces refresh if npmrc file does not exist
|
|
21
|
+
let oldToken;
|
|
22
|
+
try {
|
|
23
|
+
if (_nodeFs.default.existsSync(npmrc)) {
|
|
24
|
+
const stat = _nodeFs.default.statSync(npmrc);
|
|
25
|
+
lastUpdated = Math.trunc((Date.now() - stat.mtimeMs) / 1000);
|
|
26
|
+
// grab the old token for logging a redacted version
|
|
27
|
+
const oldNpmrc = _nodeFs.default.readFileSync(npmrc, 'utf8');
|
|
28
|
+
const found = oldNpmrc.match(/_authToken=(.*)\n/);
|
|
29
|
+
if (found) {
|
|
30
|
+
oldToken = `${found[1].slice(0, 8)}......${found[1].slice(-4)}`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
} catch (statErr) {
|
|
34
|
+
log({
|
|
35
|
+
statErr
|
|
36
|
+
}, `<==fs.statSync failed on file ${npmrc}`);
|
|
37
|
+
}
|
|
38
|
+
if (lastUpdated < refreshThreshold) {
|
|
39
|
+
process.exit(0);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// fetch the contents of the npmrc secret stored on leverege-registry
|
|
43
|
+
let npmrcSecret;
|
|
44
|
+
try {
|
|
45
|
+
const {
|
|
46
|
+
stdout
|
|
47
|
+
} = await (0, _execa.default)('gcloud', ['secrets', 'versions', 'access', 'latest', '--secret=NPM_DEVELOPER_NPMRC', '--project=leverege-registry']);
|
|
48
|
+
npmrcSecret = stdout;
|
|
49
|
+
} catch (err) {
|
|
50
|
+
log(_chalk.default.yellow(`\nFailed Command => [${err.escapedCommand}]\n\n`), _chalk.default.red(err.stderr));
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// now update the user's npmrc file
|
|
55
|
+
log(_chalk.default.yellow('\n*** Refreshing your ~/.npmrc npm token file'));
|
|
56
|
+
try {
|
|
57
|
+
if (_nodeFs.default.existsSync(npmrc)) {
|
|
58
|
+
_nodeFs.default.copyFileSync(npmrc, `${npmrc}-BAK`); // make a backup for safety
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
_nodeFs.default.writeFileSync(`${npmrc}`, npmrcSecret);
|
|
62
|
+
} catch (fileErr) {
|
|
63
|
+
log(fileErr, 'fs failed');
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
const now = new Date().toLocaleString();
|
|
67
|
+
const slackURL = 'https://hooks.slack.com/services/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';
|
|
68
|
+
const slackData = {
|
|
69
|
+
text: `--- npmrc refreshed by \`${process.env['USER']}\` at ${now}\n token [\`${oldToken}\`]`,
|
|
70
|
+
channel: '#dev-ops-helm'
|
|
71
|
+
};
|
|
72
|
+
fetch(slackURL, {
|
|
73
|
+
method: 'POST',
|
|
74
|
+
body: JSON.stringify(slackData),
|
|
75
|
+
headers: {
|
|
76
|
+
'Content-Type': 'application/json'
|
|
77
|
+
}
|
|
78
|
+
}).catch(err => console.log(err));
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
var _nodeFs = _interopRequireDefault(require("node:fs"));
|
|
5
|
+
var _nodeOs = _interopRequireDefault(require("node:os"));
|
|
6
|
+
var _chalk = _interopRequireDefault(require("chalk"));
|
|
7
|
+
var _execa = _interopRequireDefault(require("execa"));
|
|
8
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
9
|
+
// we can't use $ until we upgrade to ESM execa
|
|
10
|
+
// the standard user npmrc token is stored here
|
|
11
|
+
const npmrc = `${_nodeOs.default.homedir()}/.npmrc`;
|
|
12
|
+
|
|
13
|
+
// max age in seconds of the npmrc file before refresh
|
|
14
|
+
const refreshThreshold = 3600 * 24; // 1 day
|
|
15
|
+
|
|
16
|
+
const log = console.log;
|
|
17
|
+
|
|
18
|
+
// calculate number of seconds since last update and exit if the file
|
|
19
|
+
// was recently updated
|
|
20
|
+
let lastUpdated = refreshThreshold * 2; // forces refresh if npmrc file does not exist
|
|
21
|
+
let oldToken;
|
|
22
|
+
try {
|
|
23
|
+
if (_nodeFs.default.existsSync(npmrc)) {
|
|
24
|
+
const stat = _nodeFs.default.statSync(npmrc);
|
|
25
|
+
lastUpdated = Math.trunc((Date.now() - stat.mtimeMs) / 1000);
|
|
26
|
+
// grab the old token for logging a redacted version
|
|
27
|
+
const oldNpmrc = _nodeFs.default.readFileSync(npmrc, 'utf8');
|
|
28
|
+
const found = oldNpmrc.match(/_authToken=(.*)\n/);
|
|
29
|
+
if (found) {
|
|
30
|
+
oldToken = `${found[1].slice(0, 8)}......${found[1].slice(-4)}`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
} catch (statErr) {
|
|
34
|
+
log({
|
|
35
|
+
statErr
|
|
36
|
+
}, `<==fs.statSync failed on file ${npmrc}`);
|
|
37
|
+
}
|
|
38
|
+
if (lastUpdated < refreshThreshold) {
|
|
39
|
+
process.exit(0);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// fetch the contents of the npmrc secret stored on leverege-registry
|
|
43
|
+
let npmrcSecret;
|
|
44
|
+
try {
|
|
45
|
+
const {
|
|
46
|
+
stdout
|
|
47
|
+
} = await (0, _execa.default)('gcloud', ['secrets', 'versions', 'access', 'latest', '--secret=NPM_DEVELOPER_NPMRC', '--project=leverege-registry']);
|
|
48
|
+
npmrcSecret = stdout;
|
|
49
|
+
} catch (err) {
|
|
50
|
+
log(_chalk.default.yellow(`\nFailed Command => [${err.escapedCommand}]\n\n`), _chalk.default.red(err.stderr));
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// now update the user's npmrc file
|
|
55
|
+
log(_chalk.default.yellow('\n*** Refreshing your ~/.npmrc npm token file'));
|
|
56
|
+
try {
|
|
57
|
+
if (_nodeFs.default.existsSync(npmrc)) {
|
|
58
|
+
_nodeFs.default.copyFileSync(npmrc, `${npmrc}-BAK`); // make a backup for safety
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
_nodeFs.default.writeFileSync(`${npmrc}`, npmrcSecret);
|
|
62
|
+
} catch (fileErr) {
|
|
63
|
+
log(fileErr, 'fs failed');
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
const now = new Date().toLocaleString();
|
|
67
|
+
const slackURL = 'https://hooks.slack.com/services/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';
|
|
68
|
+
const slackData = {
|
|
69
|
+
text: `--- npmrc refreshed by \`${process.env['USER']}\` at ${now}\n token [\`${oldToken}\`]`,
|
|
70
|
+
channel: '#dev-ops-helm'
|
|
71
|
+
};
|
|
72
|
+
fetch(slackURL, {
|
|
73
|
+
method: 'POST',
|
|
74
|
+
body: JSON.stringify(slackData),
|
|
75
|
+
headers: {
|
|
76
|
+
'Content-Type': 'application/json'
|
|
77
|
+
}
|
|
78
|
+
}).catch(err => console.log(err));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leverege/build-tools",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.36.1",
|
|
4
4
|
"description": "A collection of build / support tools for Leverege developers",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -24,14 +24,17 @@
|
|
|
24
24
|
"dirty-git": "src/dirty-git",
|
|
25
25
|
"dockreate": "src/dockreate",
|
|
26
26
|
"encrypt-secrets": "src/encrypt-secrets",
|
|
27
|
+
"firebaseDeploy": "src/firebaseDeploy.mjs",
|
|
28
|
+
"firebaseServe": "src/firebaseServe.mjs",
|
|
27
29
|
"getfbcfg": "src/getfbcfg.js",
|
|
28
30
|
"getjson": "src/getjson.js",
|
|
29
31
|
"git-tar": "src/git-tar",
|
|
30
32
|
"helmdn": "src/helmdn",
|
|
31
33
|
"helmup": "src/helmup",
|
|
34
|
+
"helminit": "src/helmup",
|
|
32
35
|
"helmwhat": "src/helmup",
|
|
33
|
-
"k8scale": "src/k8scale",
|
|
34
36
|
"k8cryo": "src/k8cryo",
|
|
37
|
+
"k8scale": "src/k8scale",
|
|
35
38
|
"k8thaw": "src/k8cryo",
|
|
36
39
|
"k8x": "src/k8x",
|
|
37
40
|
"klog": "src/klog",
|
|
@@ -43,10 +46,9 @@
|
|
|
43
46
|
"prune-git": "src/prune-git",
|
|
44
47
|
"pull-git": "src/pull-git",
|
|
45
48
|
"push-my-chart": "src/push-my-chart",
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"tag-release": "src/tag-release.mjs"
|
|
49
|
+
"refresh-npm-token": "src/refresh-npm-token.mjs",
|
|
50
|
+
"tag-release": "src/tag-release.mjs",
|
|
51
|
+
"unleash": "src/unleash.js"
|
|
50
52
|
},
|
|
51
53
|
"author": "Leverege Devs",
|
|
52
54
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
@@ -71,8 +73,8 @@
|
|
|
71
73
|
"zx": "^7.2.3"
|
|
72
74
|
},
|
|
73
75
|
"devDependencies": {
|
|
74
|
-
"@babel/cli": "^7.22.
|
|
75
|
-
"@babel/core": "^7.22.
|
|
76
|
+
"@babel/cli": "^7.22.10",
|
|
77
|
+
"@babel/core": "^7.22.10",
|
|
76
78
|
"@leverege/babel-preset-leverege-node": "^2.0.0",
|
|
77
79
|
"@leverege/eslint-config-leverege": "^3.0.1",
|
|
78
80
|
"npm": "^9.8.1"
|
package/src/bash-funcs
CHANGED
|
@@ -73,7 +73,7 @@ function setOrUnset() {
|
|
|
73
73
|
|
|
74
74
|
function getManagedSecret() {
|
|
75
75
|
local SECNAME=$1
|
|
76
|
-
local PROJECT="${2:-leverege-docker-images
|
|
76
|
+
local PROJECT="${2:-leverege-registry}" # was leverege-docker-images
|
|
77
77
|
SECRET=$(gcloud secrets versions access latest --secret="$SECNAME" --project=$PROJECT)
|
|
78
78
|
if [ $? -ne 0 ];
|
|
79
79
|
then
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
version: 2.1
|
|
2
|
+
jobs:
|
|
3
|
+
install:
|
|
4
|
+
docker:
|
|
5
|
+
- image: $CIRCLE_NODE_IMG
|
|
6
|
+
steps:
|
|
7
|
+
- checkout
|
|
8
|
+
- restore_cache:
|
|
9
|
+
keys:
|
|
10
|
+
- v1-npm-deps-{{ checksum "package-lock.json" }}
|
|
11
|
+
- v1-npm-deps-
|
|
12
|
+
|
|
13
|
+
- run:
|
|
14
|
+
name: Setup @leverege Token
|
|
15
|
+
command: echo \${NPMRC} > ~/.npmrc
|
|
16
|
+
|
|
17
|
+
- run: npm install
|
|
18
|
+
|
|
19
|
+
- save_cache:
|
|
20
|
+
key: v1-npm-deps-{{ checksum "package-lock.json" }}
|
|
21
|
+
paths:
|
|
22
|
+
- ./node_modules
|
|
23
|
+
|
|
24
|
+
- persist_to_workspace:
|
|
25
|
+
root: /home/circleci/project
|
|
26
|
+
paths:
|
|
27
|
+
- ./node_modules
|
|
28
|
+
|
|
29
|
+
security-check:
|
|
30
|
+
docker:
|
|
31
|
+
- image: $CIRCLE_NODE_IMG
|
|
32
|
+
steps:
|
|
33
|
+
- checkout
|
|
34
|
+
- attach_workspace:
|
|
35
|
+
at: ~/project
|
|
36
|
+
- run:
|
|
37
|
+
name: Check for vulnerabilities
|
|
38
|
+
command: npm audit --production --audit-level=moderate
|
|
39
|
+
|
|
40
|
+
license-check:
|
|
41
|
+
docker:
|
|
42
|
+
- image: $CIRCLE_NODE_IMG
|
|
43
|
+
steps:
|
|
44
|
+
- checkout
|
|
45
|
+
- attach_workspace:
|
|
46
|
+
at: ~/project
|
|
47
|
+
- run:
|
|
48
|
+
name: Check for LICENSE and README files
|
|
49
|
+
command: npm run pkglint
|
|
50
|
+
|
|
51
|
+
- run:
|
|
52
|
+
name: Check for license violations (e.g. GPL)
|
|
53
|
+
command: npx license-checker --production --summary --failOn GPL
|
|
54
|
+
|
|
55
|
+
lint:
|
|
56
|
+
docker:
|
|
57
|
+
- image: $CIRCLE_NODE_IMG
|
|
58
|
+
steps:
|
|
59
|
+
- checkout
|
|
60
|
+
- attach_workspace:
|
|
61
|
+
at: ~/project
|
|
62
|
+
- run:
|
|
63
|
+
name: Lint and save results
|
|
64
|
+
command: npm run lint-ci
|
|
65
|
+
|
|
66
|
+
- store_test_results:
|
|
67
|
+
path: reports
|
|
68
|
+
|
|
69
|
+
docs:
|
|
70
|
+
docker:
|
|
71
|
+
- image: $CIRCLE_NODE_IMG
|
|
72
|
+
steps:
|
|
73
|
+
- checkout
|
|
74
|
+
- attach_workspace:
|
|
75
|
+
at: ~/project
|
|
76
|
+
- run:
|
|
77
|
+
name: Generate docs
|
|
78
|
+
command: npx jsdoc -r src -R README.md -d docs
|
|
79
|
+
- store_artifacts:
|
|
80
|
+
path: docs
|
|
81
|
+
prefix: docs
|
|
82
|
+
|
|
83
|
+
coverage:
|
|
84
|
+
# coverage runs tests, generates coverage, and saves docs
|
|
85
|
+
environment:
|
|
86
|
+
TZ: 'America/New_York'
|
|
87
|
+
docker:
|
|
88
|
+
- image: $CIRCLE_NODE_IMG
|
|
89
|
+
# IF YOU NEED ANY OF THESE, UNCOMMENT TO USE
|
|
90
|
+
# - image: redis
|
|
91
|
+
# - image: circleci/mysql:5.7
|
|
92
|
+
# environment:
|
|
93
|
+
# MYSQL_USER: root
|
|
94
|
+
# MYSQL_ROOT_PASSWORD: root
|
|
95
|
+
# MYSQL_ALLOW_EMPTY_PASSWORD: true
|
|
96
|
+
# MYSQL_HOST: 127.0.0.1
|
|
97
|
+
# - image: nsqio/nsq
|
|
98
|
+
# command: /nsqlookupd -broadcast-address localhost:4160 -tcp-address 0.0.0.0:4160 -http-address 0.0.0.0:4161
|
|
99
|
+
|
|
100
|
+
# - image: nsqio/nsq
|
|
101
|
+
# command: >
|
|
102
|
+
# /nsqd
|
|
103
|
+
# -broadcast-address localhost:4150
|
|
104
|
+
# -tcp-address 0.0.0.0:4150
|
|
105
|
+
# -http-address 0.0.0.0:4151
|
|
106
|
+
# -lookupd-tcp-address localhost:4160
|
|
107
|
+
|
|
108
|
+
steps:
|
|
109
|
+
- checkout
|
|
110
|
+
- attach_workspace:
|
|
111
|
+
at: ~/project
|
|
112
|
+
|
|
113
|
+
# UNCOMMENT IF YOU NEED DECRYPTING SECRETS
|
|
114
|
+
# - run:
|
|
115
|
+
# name: Load secrets
|
|
116
|
+
# command: npm run decrypt
|
|
117
|
+
|
|
118
|
+
- run:
|
|
119
|
+
name: Run Tests and Generate Code Coverage
|
|
120
|
+
command: npm run coverage
|
|
121
|
+
|
|
122
|
+
- run:
|
|
123
|
+
name: Check if coverage meets at least 70%
|
|
124
|
+
command: npx c8 check-coverage --functions 70 --lines 70 --statements 70
|
|
125
|
+
|
|
126
|
+
- store_artifacts:
|
|
127
|
+
path: coverage
|
|
128
|
+
prefix: coverage
|
|
129
|
+
|
|
130
|
+
workflows:
|
|
131
|
+
version: 2.1
|
|
132
|
+
test-build-deploy:
|
|
133
|
+
jobs:
|
|
134
|
+
- install:
|
|
135
|
+
context: npm
|
|
136
|
+
- security-check:
|
|
137
|
+
requires:
|
|
138
|
+
- install
|
|
139
|
+
- license-check:
|
|
140
|
+
requires:
|
|
141
|
+
- install
|
|
142
|
+
- lint:
|
|
143
|
+
requires:
|
|
144
|
+
- install
|
|
145
|
+
- coverage:
|
|
146
|
+
requires:
|
|
147
|
+
- install
|
|
148
|
+
- docs:
|
|
149
|
+
requires:
|
|
150
|
+
- install
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
version: 2.1
|
|
2
|
+
#orbs:
|
|
3
|
+
# gcp-gcr: circleci/gcp-gcr@0.6.1
|
|
4
|
+
executors:
|
|
5
|
+
default:
|
|
6
|
+
description: >
|
|
7
|
+
A debian-based machine executor.
|
|
8
|
+
machine: true
|
|
9
|
+
jobs:
|
|
10
|
+
install:
|
|
11
|
+
docker:
|
|
12
|
+
- image: $CIRCLE_NODE_IMG
|
|
13
|
+
steps:
|
|
14
|
+
- checkout
|
|
15
|
+
- restore_cache:
|
|
16
|
+
keys:
|
|
17
|
+
- v1-npm-deps-{{ checksum "package-lock.json" }}
|
|
18
|
+
- v1-npm-deps-
|
|
19
|
+
|
|
20
|
+
- run:
|
|
21
|
+
name: Setup @leverege Token
|
|
22
|
+
command: echo \${NPMRC} > ~/.npmrc
|
|
23
|
+
|
|
24
|
+
- run: npm install
|
|
25
|
+
|
|
26
|
+
- save_cache:
|
|
27
|
+
key: v1-npm-deps-{{ checksum "package-lock.json" }}
|
|
28
|
+
paths:
|
|
29
|
+
- ./node_modules
|
|
30
|
+
|
|
31
|
+
- persist_to_workspace:
|
|
32
|
+
root: /home/circleci/project
|
|
33
|
+
paths:
|
|
34
|
+
- ./node_modules
|
|
35
|
+
|
|
36
|
+
security-check:
|
|
37
|
+
docker:
|
|
38
|
+
- image: $CIRCLE_NODE_IMG
|
|
39
|
+
steps:
|
|
40
|
+
- checkout
|
|
41
|
+
- attach_workspace:
|
|
42
|
+
at: ~/project
|
|
43
|
+
- run:
|
|
44
|
+
name: Check for vulnerabilities
|
|
45
|
+
command: npm audit --production --audit-level=moderate
|
|
46
|
+
|
|
47
|
+
license-check:
|
|
48
|
+
docker:
|
|
49
|
+
- image: $CIRCLE_NODE_IMG
|
|
50
|
+
steps:
|
|
51
|
+
- checkout
|
|
52
|
+
- attach_workspace:
|
|
53
|
+
at: ~/project
|
|
54
|
+
- run:
|
|
55
|
+
name: Check for LICENSE and README files
|
|
56
|
+
command: npm run pkglint
|
|
57
|
+
|
|
58
|
+
- run:
|
|
59
|
+
name: Check for license violations (e.g. GPL)
|
|
60
|
+
command: npx license-checker --production --summary --failOn GPL
|
|
61
|
+
|
|
62
|
+
lint:
|
|
63
|
+
docker:
|
|
64
|
+
- image: $CIRCLE_NODE_IMG
|
|
65
|
+
steps:
|
|
66
|
+
- checkout
|
|
67
|
+
- attach_workspace:
|
|
68
|
+
at: ~/project
|
|
69
|
+
- run:
|
|
70
|
+
name: Lint and save results
|
|
71
|
+
command: npm run lint-ci
|
|
72
|
+
|
|
73
|
+
- store_test_results:
|
|
74
|
+
path: reports
|
|
75
|
+
|
|
76
|
+
docs:
|
|
77
|
+
docker:
|
|
78
|
+
- image: $CIRCLE_NODE_IMG
|
|
79
|
+
steps:
|
|
80
|
+
- checkout
|
|
81
|
+
- attach_workspace:
|
|
82
|
+
at: ~/project
|
|
83
|
+
- run:
|
|
84
|
+
name: Generate docs
|
|
85
|
+
command: npx jsdoc -r src -R README.md -d docs
|
|
86
|
+
- store_artifacts:
|
|
87
|
+
path: docs
|
|
88
|
+
prefix: docs
|
|
89
|
+
|
|
90
|
+
coverage:
|
|
91
|
+
# coverage runs tests, generates coverage, and saves docs
|
|
92
|
+
environment:
|
|
93
|
+
TZ: 'America/New_York'
|
|
94
|
+
docker:
|
|
95
|
+
- image: $CIRCLE_NODE_IMG
|
|
96
|
+
# IF YOU NEED ANY OF THESE, UNCOMMENT TO USE
|
|
97
|
+
# - image: redis
|
|
98
|
+
# - image: circleci/mysql:5.7
|
|
99
|
+
# environment:
|
|
100
|
+
# MYSQL_USER: root
|
|
101
|
+
# MYSQL_ROOT_PASSWORD: root
|
|
102
|
+
# MYSQL_ALLOW_EMPTY_PASSWORD: true
|
|
103
|
+
# MYSQL_HOST: 127.0.0.1
|
|
104
|
+
# - image: nsqio/nsq
|
|
105
|
+
# command: /nsqlookupd -broadcast-address localhost:4160 -tcp-address 0.0.0.0:4160 -http-address 0.0.0.0:4161
|
|
106
|
+
|
|
107
|
+
# - image: nsqio/nsq
|
|
108
|
+
# command: >
|
|
109
|
+
# /nsqd
|
|
110
|
+
# -broadcast-address localhost:4150
|
|
111
|
+
# -tcp-address 0.0.0.0:4150
|
|
112
|
+
# -http-address 0.0.0.0:4151
|
|
113
|
+
# -lookupd-tcp-address localhost:4160
|
|
114
|
+
|
|
115
|
+
steps:
|
|
116
|
+
- checkout
|
|
117
|
+
- attach_workspace:
|
|
118
|
+
at: ~/project
|
|
119
|
+
|
|
120
|
+
# UNCOMMENT IF YOU NEED DECRYPTING SECRETS
|
|
121
|
+
# - run:
|
|
122
|
+
# name: Load secrets
|
|
123
|
+
# command: npm run decrypt
|
|
124
|
+
|
|
125
|
+
- run:
|
|
126
|
+
name: Run Tests and Generate Code Coverage
|
|
127
|
+
command: npm run coverage
|
|
128
|
+
|
|
129
|
+
- run:
|
|
130
|
+
name: Check if coverage meets at least 70%
|
|
131
|
+
command: npx c8 check-coverage --functions 70 --lines 70 --statements 70
|
|
132
|
+
|
|
133
|
+
- store_artifacts:
|
|
134
|
+
path: coverage
|
|
135
|
+
prefix: coverage
|
|
136
|
+
|
|
137
|
+
build:
|
|
138
|
+
# build should make dist image and prepare docker file
|
|
139
|
+
docker:
|
|
140
|
+
- image: $CIRCLE_NODE_IMG
|
|
141
|
+
|
|
142
|
+
steps:
|
|
143
|
+
- checkout
|
|
144
|
+
- attach_workspace:
|
|
145
|
+
at: ~/project
|
|
146
|
+
|
|
147
|
+
- run:
|
|
148
|
+
name: Setup @leverege Token
|
|
149
|
+
command: echo \${NPMRC} > ~/.npmrc.ro
|
|
150
|
+
|
|
151
|
+
- run:
|
|
152
|
+
name: Determine version number and container name
|
|
153
|
+
command: |
|
|
154
|
+
container="\`node -p \"require('./package.json').leverege.container\"\`"
|
|
155
|
+
if [ "\$container" == "undefined" ];
|
|
156
|
+
then
|
|
157
|
+
container=\$CIRCLE_PROJECT_REPONAME
|
|
158
|
+
fi
|
|
159
|
+
NODE_IMAGE="\`node -p \"require('./package.json').leverege.nodeimg\"\`"
|
|
160
|
+
|
|
161
|
+
echo \$(git describe --tags) > package_version
|
|
162
|
+
echo \${container} > container_name
|
|
163
|
+
echo \${NODE_IMAGE} > node_img
|
|
164
|
+
|
|
165
|
+
- run:
|
|
166
|
+
name: Create Dockerfile and build dist directory
|
|
167
|
+
command: mkdir -p docker && npm run dockerize \$(git describe --tags)
|
|
168
|
+
|
|
169
|
+
- persist_to_workspace:
|
|
170
|
+
root: ~/project
|
|
171
|
+
paths:
|
|
172
|
+
- docker/*
|
|
173
|
+
- package_version
|
|
174
|
+
- container_name
|
|
175
|
+
- node_img
|
|
176
|
+
|
|
177
|
+
workflows:
|
|
178
|
+
version: 2.1
|
|
179
|
+
test-build-deploy:
|
|
180
|
+
jobs:
|
|
181
|
+
- install:
|
|
182
|
+
context: npm
|
|
183
|
+
- security-check:
|
|
184
|
+
requires:
|
|
185
|
+
- install
|
|
186
|
+
- license-check:
|
|
187
|
+
requires:
|
|
188
|
+
- install
|
|
189
|
+
- lint:
|
|
190
|
+
requires:
|
|
191
|
+
- install
|
|
192
|
+
- coverage:
|
|
193
|
+
requires:
|
|
194
|
+
- install
|
|
195
|
+
- docs:
|
|
196
|
+
requires:
|
|
197
|
+
- install
|
|
198
|
+
- build:
|
|
199
|
+
context: npm
|
|
200
|
+
filters:
|
|
201
|
+
branches:
|
|
202
|
+
only:
|
|
203
|
+
- development
|
|
204
|
+
- /release-.*/
|
|
205
|
+
- master
|
|
206
|
+
requires:
|
|
207
|
+
- install
|
|
208
|
+
- security-check
|
|
209
|
+
- license-check
|
|
210
|
+
- lint
|
|
211
|
+
- coverage
|
|
212
|
+
- docs
|
|
213
|
+
|
package/src/dockreate
CHANGED
|
@@ -202,23 +202,8 @@ cmclear()
|
|
|
202
202
|
EOBASHRC
|
|
203
203
|
} # end of create_bashrc
|
|
204
204
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
then
|
|
208
|
-
cat<<ROTOKEN
|
|
209
|
-
|
|
210
|
-
$(color r '***ERROR: expecting to see a readonly npmjs token')
|
|
211
|
-
|
|
212
|
-
For security purposes, we deploy images with read-only npmjs tokens.
|
|
213
|
-
These may be acquired from another developer, or can be created with the
|
|
214
|
-
npmjs leverege account.
|
|
215
|
-
|
|
216
|
-
Obtain the token and drop it here => $(color g "$NPMRC")
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
ROTOKEN
|
|
220
|
-
exit 1
|
|
221
|
-
fi
|
|
205
|
+
# make sure we have a current npmrc file
|
|
206
|
+
refresh-npm-token
|
|
222
207
|
|
|
223
208
|
# Look for leverege specifics, but only require the project name.
|
|
224
209
|
project=$(packageJson .leverege.project)
|
|
@@ -406,8 +391,8 @@ create_bashrc "$version" "$nodeimg"
|
|
|
406
391
|
rm -rf ./workspace && mkdir -p ./workspace
|
|
407
392
|
cp -rfp ${PKGTOP}/package*json ${PKGTOP}/dist/* ./workspace
|
|
408
393
|
|
|
409
|
-
# grab the
|
|
410
|
-
cp -f $
|
|
394
|
+
# grab the npmrc token for the image
|
|
395
|
+
cp -f "$HOME/.npmrc" .npmrc
|
|
411
396
|
|
|
412
397
|
[ "$CIRCLECI" == "true" ] && exit 0
|
|
413
398
|
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
geotile-local.yaml
|
package/src/helmup
CHANGED
|
@@ -260,19 +260,6 @@ function monitoringHelp() {
|
|
|
260
260
|
ACCESS
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
-
function getManagedSecret() {
|
|
264
|
-
local SECNAME=$1
|
|
265
|
-
local PROJECT="${2:-leverege-docker-images}"
|
|
266
|
-
SECRET=$(gcloud secrets versions access latest --secret="$SECNAME" --project=$PROJECT)
|
|
267
|
-
if [ $? -ne 0 ];
|
|
268
|
-
then
|
|
269
|
-
printf "This failed=>[gcloud secrets versions access latest --secret="$SECNAME" --project=$PROJECT]\n"
|
|
270
|
-
printf "Returned =>[$SECRET]\n\n"
|
|
271
|
-
exit 1
|
|
272
|
-
fi
|
|
273
|
-
echo $SECRET
|
|
274
|
-
}
|
|
275
|
-
|
|
276
263
|
# https://github.com/estafette/estafette-gke-preemptible-killer
|
|
277
264
|
function installPreemptibleKiller() {
|
|
278
265
|
showInstalling "Preemptible Node Killing Coordinator"
|
|
@@ -404,32 +391,6 @@ NEED_MANAGED_SECRET
|
|
|
404
391
|
fi
|
|
405
392
|
}
|
|
406
393
|
|
|
407
|
-
function installTraefikEnvironment() {
|
|
408
|
-
showInstalling "Traefik Namespace and Cloudflare Secret"
|
|
409
|
-
createNamespaceIfNeeded traefik
|
|
410
|
-
|
|
411
|
-
kubectl get secret cloudflare --namespace traefik &>/dev/null
|
|
412
|
-
if [[ $? -eq 1 ]];
|
|
413
|
-
then
|
|
414
|
-
cat<<NEED_TRAEFIK_SECRET
|
|
415
|
-
$RED_ERROR missing secret: `color y cloudflare` namespace: `color y traefik`
|
|
416
|
-
|
|
417
|
-
Injecting the `color y cloudflare` secret from the `color g leverege-docker-images` cluster.
|
|
418
|
-
|
|
419
|
-
NEED_TRAEFIK_SECRET
|
|
420
|
-
TOKEN=$(getManagedSecret "CLOUDFLARE_API_TOKEN")
|
|
421
|
-
if [ $? -ne 0 ];
|
|
422
|
-
then
|
|
423
|
-
printf "$RED_ERROR getManagedSecret reponse=>[$TOKEN]"
|
|
424
|
-
exitOnError 1 "Failed to fetch the secret from leverege-docker-images"
|
|
425
|
-
fi
|
|
426
|
-
printf "\nInjecting=[$TOKEN] into cloudflare secret\n"
|
|
427
|
-
kubectl create secret generic cloudflare \
|
|
428
|
-
--namespace traefik \
|
|
429
|
-
--from-literal=dns-token=$TOKEN
|
|
430
|
-
fi
|
|
431
|
-
}
|
|
432
|
-
|
|
433
394
|
function installVeleroEnvironment() {
|
|
434
395
|
# Follows instructions => https://github.com/vmware-tanzu/velero-plugin-for-gcp
|
|
435
396
|
showInstalling "Velero Backup Management"
|
|
@@ -614,8 +575,29 @@ function doInstall() {
|
|
|
614
575
|
# slap additional helm syntax in there if the version is set
|
|
615
576
|
[ ! -z "$CHARTVER" ] && CHARTVER="--version $CHARTVER"
|
|
616
577
|
|
|
578
|
+
local INVOKED_AS=`basename $0`
|
|
617
579
|
# set the dry-run flag on what
|
|
618
|
-
[ "
|
|
580
|
+
[ "$INVOKED_AS" == "helmwhat" ] && HELM_WHAT="--dry-run --debug"
|
|
581
|
+
|
|
582
|
+
# helminit is used to redeploy an existing service
|
|
583
|
+
if [ "$INVOKED_AS" == "helminit" ] && [ -f "$SERVICE/helmup.plugin" ];
|
|
584
|
+
then
|
|
585
|
+
local BACKUP_DIR="$SERVICE-bak"
|
|
586
|
+
if [ ! -d "$BACKUP_DIR" ];
|
|
587
|
+
then
|
|
588
|
+
printf "Moving existing `color y $SERVICE` to backup `color g $BACKUP_DIR`\n\n"
|
|
589
|
+
mv $SERVICE $BACKUP_DIR
|
|
590
|
+
else
|
|
591
|
+
cat<<CATBACKUP
|
|
592
|
+
$RED_ERROR `color y "Existing backup directories detected"`
|
|
593
|
+
|
|
594
|
+
In order to proceed the backup directories must not pre-exist or helminit
|
|
595
|
+
may overrite important information. Clean up the backups and try again.
|
|
596
|
+
|
|
597
|
+
CATBACKUP
|
|
598
|
+
ls -ld *-bak && exit 1
|
|
599
|
+
fi
|
|
600
|
+
fi
|
|
619
601
|
|
|
620
602
|
# If we're referencing a plugin then execute it and continue
|
|
621
603
|
ifPluggedIn $SERVICE && continue
|
|
@@ -642,6 +624,12 @@ function doInstall() {
|
|
|
642
624
|
kubectl create -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter.yaml
|
|
643
625
|
;;
|
|
644
626
|
|
|
627
|
+
db-curator*)
|
|
628
|
+
# db-curator / db-curator-dh diffs are defined in values-local.yaml
|
|
629
|
+
HELMUP="helm upgrade --install $SERVICE leverege/db-curator --values $SERVICE/values.yaml $CHARTVER $HELM_WHAT"
|
|
630
|
+
doHelmup "$HELMUP"
|
|
631
|
+
;;
|
|
632
|
+
|
|
645
633
|
"elasticsearch") # simple 3 master v7.16 cluster
|
|
646
634
|
bootstrapLocalSetup $SERVICE
|
|
647
635
|
;;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs'
|
|
3
|
+
import os from 'node:os'
|
|
4
|
+
|
|
5
|
+
import chalk from 'chalk'
|
|
6
|
+
import execa from 'execa' // we can't use $ until we upgrade to ESM execa
|
|
7
|
+
|
|
8
|
+
// the standard user npmrc token is stored here
|
|
9
|
+
const npmrc = `${os.homedir()}/.npmrc`
|
|
10
|
+
|
|
11
|
+
// max age in seconds of the npmrc file before refresh
|
|
12
|
+
const refreshThreshold = 3600 *24 // 1 day
|
|
13
|
+
|
|
14
|
+
const log = console.log
|
|
15
|
+
|
|
16
|
+
// calculate number of seconds since last update and exit if the file
|
|
17
|
+
// was recently updated
|
|
18
|
+
let lastUpdated = refreshThreshold * 2 // forces refresh if npmrc file does not exist
|
|
19
|
+
let oldToken
|
|
20
|
+
try {
|
|
21
|
+
if ( fs.existsSync( npmrc ) ) {
|
|
22
|
+
const stat = fs.statSync( npmrc )
|
|
23
|
+
lastUpdated = Math.trunc( ( Date.now() - stat.mtimeMs ) / 1000 )
|
|
24
|
+
// grab the old token for logging a redacted version
|
|
25
|
+
const oldNpmrc = fs.readFileSync( npmrc, 'utf8' )
|
|
26
|
+
const found = oldNpmrc.match( /_authToken=(.*)\n/ )
|
|
27
|
+
if( found ) {
|
|
28
|
+
oldToken = `${found[1].slice(0,8)}......${found[1].slice(-4)}`
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
} catch ( statErr ) {
|
|
32
|
+
log( { statErr }, `<==fs.statSync failed on file ${npmrc}` )
|
|
33
|
+
}
|
|
34
|
+
if ( lastUpdated < refreshThreshold ) { process.exit( 0 ) }
|
|
35
|
+
|
|
36
|
+
// fetch the contents of the npmrc secret stored on leverege-registry
|
|
37
|
+
let npmrcSecret
|
|
38
|
+
try {
|
|
39
|
+
const { stdout } = await execa( 'gcloud', [
|
|
40
|
+
'secrets',
|
|
41
|
+
'versions',
|
|
42
|
+
'access',
|
|
43
|
+
'latest',
|
|
44
|
+
'--secret=NPM_DEVELOPER_NPMRC',
|
|
45
|
+
'--project=leverege-registry',
|
|
46
|
+
] )
|
|
47
|
+
npmrcSecret = stdout
|
|
48
|
+
} catch( err ) {
|
|
49
|
+
log( chalk.yellow( `\nFailed Command => [${err.escapedCommand}]\n\n` ), chalk.red( err.stderr ) )
|
|
50
|
+
process.exit( 1 )
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// now update the user's npmrc file
|
|
54
|
+
log( chalk.yellow( '\n*** Refreshing your ~/.npmrc npm token file' ) )
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
if ( fs.existsSync( npmrc ) ) {
|
|
58
|
+
fs.copyFileSync( npmrc, `${npmrc}-BAK` ) // make a backup for safety
|
|
59
|
+
}
|
|
60
|
+
fs.writeFileSync( `${npmrc}`, npmrcSecret )
|
|
61
|
+
} catch( fileErr ) {
|
|
62
|
+
log( fileErr, 'fs failed' )
|
|
63
|
+
process.exit( 1 )
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const now = ( new Date() ).toLocaleString()
|
|
67
|
+
const slackURL = 'https://hooks.slack.com/services/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'
|
|
68
|
+
const slackData = {
|
|
69
|
+
text: `--- npmrc refreshed by \`${process.env['USER']}\` at ${now}\n token [\`${oldToken}\`]`,
|
|
70
|
+
channel: '#dev-ops-helm',
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
fetch( slackURL, {
|
|
74
|
+
method: 'POST',
|
|
75
|
+
body: JSON.stringify( slackData ),
|
|
76
|
+
headers: {
|
|
77
|
+
'Content-Type': 'application/json',
|
|
78
|
+
},
|
|
79
|
+
} )
|
|
80
|
+
.catch( err => console.log( err ) )
|
|
Binary file
|