@leverege/build-tools 2.103.0 → 2.105.0
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/.github/dependabot.yml +7 -0
- package/README.md +20 -8
- package/eslint.config.mjs +13 -0
- package/package.json +14 -14
- package/src/Docker.mjs +3 -3
- package/src/Utils.mjs +33 -4
- package/src/bash-funcs +1 -1
- package/src/build-cnpg-image.mjs +1 -1
- package/src/chart-compass.mjs +3 -3
- package/src/chart-to-registry.mjs +1 -1
- package/src/custom-images/bitnami-audits/bitnami-audit.mjs +1 -1
- package/src/dashboard/DashboardManager.mjs +6 -0
- package/src/dashboard/json/deprecated/pitcrew/triton-server.json +1611 -0
- package/src/dashboard/json/deprecated/pitcrew/vms-server.json +2949 -0
- package/src/dashboard/json/pitcrew/triton-interface.json +1201 -0
- package/src/dashboard/json/pitcrew/vms-server.json +1636 -0
- package/src/firebaseDeploy.mjs +0 -1
- package/src/firebaseServe.mjs +0 -1
- package/src/helm-charts/prom-operator/helmup.plugin +1 -1
- package/src/helm-charts/prom-operator/prometheus-stack.yaml.ovh +24 -2
- package/src/helm-charts/prom-operator/rules/cnpg-rules.yaml +2 -1
- package/src/helm-charts/prom-operator/test-alert.yaml +1 -1
- package/src/overwhelm.mjs +6 -28
- package/src/refresh-npm-token.mjs +116 -197
- package/src/repo-panopticon.mjs +1 -1
- package/src/service-man/config/CommandLine.mjs +6 -3
- package/src/service-man/config/Config.mjs +1 -1
- package/src/service-man/gcloud-k8s/RolesManager.mjs +1 -1
- package/src/service-man/gcloud-k8s/SecretsManager.mjs +3 -3
- package/src/service-man/gcloud-k8s/ServiceAccountManager.mjs +4 -4
- package/src/unleash.mjs +1 -1
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ Most tools assume the following are installed and configured:
|
|
|
17
17
|
- `helm` (v3+)
|
|
18
18
|
- `fzf` (for interactive pod selection in `k8x` and `klog`)
|
|
19
19
|
- Node.js 22+ - prefer 24
|
|
20
|
+
- npm 11.10+
|
|
20
21
|
|
|
21
22
|
---
|
|
22
23
|
|
|
@@ -121,12 +122,14 @@ Secrets are defined as JSON files in `src/service-man/config/secrets/`. See the
|
|
|
121
122
|
### Docker Image Management
|
|
122
123
|
|
|
123
124
|
**`docker-to-registry`** — Builds and pushes Docker images (Node.js/general) to GCP
|
|
124
|
-
Artifact Registry with git tagging.
|
|
125
|
+
Artifact Registry with git tagging. Any non-semver version string (e.g. `latest`) is
|
|
126
|
+
treated as a beta build and skips git tagging.
|
|
125
127
|
```bash
|
|
126
|
-
docker-to-registry
|
|
127
|
-
docker-to-registry latest
|
|
128
|
+
docker-to-registry v1.2.3 # tagged release build
|
|
129
|
+
docker-to-registry latest # beta build — skips git tagging
|
|
128
130
|
docker-to-registry v1.2.3 --dry-run # skip confirmation prompt
|
|
129
131
|
docker-to-registry guide-me # print helm/registry migration guidance
|
|
132
|
+
docker-to-registry v1.2.3 --debug # enable debug logging
|
|
130
133
|
```
|
|
131
134
|
|
|
132
135
|
**`build-cnpg-image`** — Builds a custom CloudNative PostgreSQL image with jsquery and
|
|
@@ -221,11 +224,20 @@ package releases. Runs automatically as the npm `prepare` lifecycle hook.
|
|
|
221
224
|
prepack [--compile] [--manual-tag] [--force-tag] [--push-tag]
|
|
222
225
|
```
|
|
223
226
|
|
|
224
|
-
**`refresh-npm-token`** —
|
|
225
|
-
Manager
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
refresh
|
|
227
|
+
**`refresh-npm-token`** — Fetches the current npm token and rc file templates from GCP
|
|
228
|
+
Secret Manager and overwrites `~/.npmrc` and `~/.yarnrc.yml`. DevOps controls the full
|
|
229
|
+
content of both files via three secrets: `REFRESH_NPM_TOKEN` (raw token),
|
|
230
|
+
`REFRESH_NPM_NPMRC`, and `REFRESH_NPM_YARNRC` (templates with `${REFRESH_NPM_TOKEN}`
|
|
231
|
+
placeholder). Skips refresh if `~/.npmrc` is less than 24 hours old. On first run,
|
|
232
|
+
existing rc files are preserved as `.LEGACY` before being overwritten.
|
|
233
|
+
```bash
|
|
234
|
+
refresh-npm-token # refresh if older than 24h
|
|
235
|
+
refresh-npm-token --force # always refresh
|
|
236
|
+
refresh-npm-token --beta # use _BETA template secrets (migration testing)
|
|
237
|
+
refresh-npm-token --dry-run # fetch and validate without writing files
|
|
238
|
+
refresh-npm-token --no-version-check # warn on version requirements but continue
|
|
239
|
+
refresh-npm-token --no-update-yarnrc # skip ~/.yarnrc.yml update
|
|
240
|
+
refresh-npm-token --npmrc-age 1h # custom age threshold
|
|
229
241
|
```
|
|
230
242
|
|
|
231
243
|
**`repo-panopticon`** — Multi-repo health dashboard. Checks each repository against a suite
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import eslintConfig from '@leverege/eslint-config-leverege'
|
|
2
|
+
|
|
3
|
+
export default [
|
|
4
|
+
...eslintConfig,
|
|
5
|
+
{
|
|
6
|
+
rules: {
|
|
7
|
+
'@stylistic/curly-newline': 'off',
|
|
8
|
+
'@stylistic/key-spacing': 'off',
|
|
9
|
+
'@stylistic/object-curly-newline': 'off',
|
|
10
|
+
'@stylistic/nonblock-statement-body-position': 'off'
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leverege/build-tools",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.105.0",
|
|
4
4
|
"description": "A collection of build / support tools for Leverege developers",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"clean": "rm -rf lib",
|
|
12
|
-
"lint": "
|
|
12
|
+
"lint": "eslint",
|
|
13
13
|
"prepare": "[ $SKIP_PREPARE ] && exit 0 || ./src/hook-and-release.mjs",
|
|
14
14
|
"test": "mocha -t 60000 --exit 'test/**/!(*e2e*).mjs'",
|
|
15
15
|
"test-all": "mocha -t 60000 --exit 'test/**/**.mjs'",
|
|
@@ -66,14 +66,13 @@
|
|
|
66
66
|
"send-to-slack": "src/send-to-slack.mjs",
|
|
67
67
|
"service-man": "src/service-man/service-man.mjs",
|
|
68
68
|
"snapshot-cnpg": "src/snapshot-cnpg.mjs",
|
|
69
|
-
"unleash": "src/unleash.mjs",
|
|
70
69
|
"upload-model": "src/upload-model.sh",
|
|
71
70
|
"yarn-build": "src/yarn-build.mjs"
|
|
72
71
|
},
|
|
73
72
|
"author": "Leverege Devs",
|
|
74
73
|
"engines": {
|
|
75
|
-
"node": "^22.
|
|
76
|
-
"npm": ">=
|
|
74
|
+
"node": "^22.22 || >=24.15",
|
|
75
|
+
"npm": ">=11.10"
|
|
77
76
|
},
|
|
78
77
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
79
78
|
"dependencies": {
|
|
@@ -88,32 +87,33 @@
|
|
|
88
87
|
"execa": "^9.6.1",
|
|
89
88
|
"find-yarn-workspace-root": "^2.0.0",
|
|
90
89
|
"glob": "^13.0.6",
|
|
91
|
-
"googleapis": "^
|
|
90
|
+
"googleapis": "^172.0.0",
|
|
92
91
|
"handlebars": "^4.7.9",
|
|
93
92
|
"ignore": "^7.0.5",
|
|
94
|
-
"inquirer": "^
|
|
93
|
+
"inquirer": "^14.0.0",
|
|
95
94
|
"js-yaml": "^4.1.1",
|
|
96
95
|
"jsdoc": "^4.0.5",
|
|
97
96
|
"ms": "^2.1.3",
|
|
98
|
-
"npm-registry-fetch": "^
|
|
97
|
+
"npm-registry-fetch": "^20.0.0",
|
|
99
98
|
"ora": "^9.4.0",
|
|
100
99
|
"p-limit": "^7.3.0",
|
|
101
100
|
"package-up": "^5.0.0",
|
|
102
101
|
"readline-sync": "^1.4.10",
|
|
103
|
-
"semver": "^7.8.
|
|
104
|
-
"shell-quote": "^1.8.
|
|
102
|
+
"semver": "^7.8.1",
|
|
103
|
+
"shell-quote": "^1.8.4",
|
|
105
104
|
"simple-git": "^3.36.0",
|
|
106
105
|
"sloc": "^0.3.2",
|
|
107
106
|
"superstruct": "^2.0.2",
|
|
108
|
-
"tmp": "^0.2.
|
|
107
|
+
"tmp": "^0.2.6",
|
|
109
108
|
"toml": "^4.1.1",
|
|
110
109
|
"yaml": "^2.9.0",
|
|
111
110
|
"zx": "^8.8.5"
|
|
112
111
|
},
|
|
113
112
|
"devDependencies": {
|
|
114
|
-
"@leverege/eslint-config-leverege": "^
|
|
113
|
+
"@leverege/eslint-config-leverege": "^9.0.1",
|
|
115
114
|
"chai": "^6.2.2",
|
|
116
|
-
"
|
|
117
|
-
"
|
|
115
|
+
"eslint": "^9",
|
|
116
|
+
"mocha": "^11.7.6",
|
|
117
|
+
"npm": "^11.15.0"
|
|
118
118
|
}
|
|
119
119
|
}
|
package/src/Docker.mjs
CHANGED
|
@@ -98,7 +98,7 @@ const generateDockerfile = async ( options ) => {
|
|
|
98
98
|
// could probably be tightened up a little.
|
|
99
99
|
try {
|
|
100
100
|
fs.readdirSync( './docker' )
|
|
101
|
-
} catch ( err ) {
|
|
101
|
+
} catch ( err ) { // eslint-disable-line no-unused-vars
|
|
102
102
|
warning( 'creating the missing ./docker directory' )
|
|
103
103
|
fs.mkdirSync( './docker' ) // TODO: blindly assumes the mkdir succeeds
|
|
104
104
|
}
|
|
@@ -120,7 +120,7 @@ const generateDockerfile = async ( options ) => {
|
|
|
120
120
|
try {
|
|
121
121
|
fs.writeFileSync( bashrcFile, bashrcTemplate )
|
|
122
122
|
fs.appendFileSync( bashrcFile, bashrcPlugin )
|
|
123
|
-
} catch ( err ) {
|
|
123
|
+
} catch ( err ) { // eslint-disable-line no-unused-vars
|
|
124
124
|
errorExit( `***ERROR: failed creation of the ${bashrcFile} file` )
|
|
125
125
|
}
|
|
126
126
|
|
|
@@ -136,7 +136,7 @@ const generateDockerfile = async ( options ) => {
|
|
|
136
136
|
if ( build.length === 0 ) {
|
|
137
137
|
errorExit( `***ERROR: the build dir is empty - ${chalk.yellow( 'npm run build' )}` )
|
|
138
138
|
}
|
|
139
|
-
} catch ( err ) {
|
|
139
|
+
} catch ( err ) { // eslint-disable-line no-unused-vars
|
|
140
140
|
errorExit( `***ERROR: expected the ${buildDir} directory to exist - ${chalk.yellow( 'npm run build' )}` )
|
|
141
141
|
}
|
|
142
142
|
|
package/src/Utils.mjs
CHANGED
|
@@ -132,7 +132,7 @@ export const shellCmd = async ( cmd, opts = {} ) => {
|
|
|
132
132
|
} else {
|
|
133
133
|
const parsed = parse( cmd ).filter( x => typeof x === 'string' )
|
|
134
134
|
// the leading ; forces a break from previous line otherwise trailing ) and leading [ collide
|
|
135
|
-
;[ command, ...args ] = parsed // eslint-disable-line semi-style
|
|
135
|
+
;[ command, ...args ] = parsed // eslint-disable-line @stylistic/semi-style
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
debug( { command, args }, '<== execa $ invoke' )
|
|
@@ -146,6 +146,35 @@ export const shellCmd = async ( cmd, opts = {} ) => {
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
+
export const versionChecks = async ( { node, npm, strict = true } = {} ) => {
|
|
150
|
+
const check = ( tool, raw, { min, preferred, hint } = {} ) => {
|
|
151
|
+
const current = semver.coerce( raw )
|
|
152
|
+
if ( !current ) {
|
|
153
|
+
warning( `could not parse ${tool} version: "${raw}"` )
|
|
154
|
+
return
|
|
155
|
+
}
|
|
156
|
+
debug( { tool, current : current.version, min, preferred, strict }, '<==versionChecks' )
|
|
157
|
+
const hintSuffix = hint ? ` — ${hint}` : ''
|
|
158
|
+
if ( min && semver.lt( current, min ) ) {
|
|
159
|
+
const msg = `${tool} ${min} or later is required (found ${current.version})${hintSuffix}`
|
|
160
|
+
if ( strict ) {
|
|
161
|
+
errorExit( `***ERROR: ${msg}` )
|
|
162
|
+
} else {
|
|
163
|
+
warning( `${msg} — continuing due to --no-version-check` )
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if ( preferred && semver.lt( current, preferred ) ) {
|
|
167
|
+
warning( `${tool} ${preferred} or later is preferred (found ${current.version})` )
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if ( node ) { check( 'node', process.version, node ) }
|
|
172
|
+
if ( npm ) {
|
|
173
|
+
const raw = ( await shellCmd( 'npm --version' ) ).trim()
|
|
174
|
+
check( 'npm', raw, npm )
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
149
178
|
export const establishOauthAccess = async ( registryLocation = 'us-docker.pkg.dev' ) => {
|
|
150
179
|
// gcloud auth print-access-token | helm registry login -u oauth2accesstoken \
|
|
151
180
|
// -p ${password} https://us-docker.pkg.dev
|
|
@@ -271,7 +300,7 @@ export const getGitBranchAndUpstream = async () => {
|
|
|
271
300
|
let upstream = 'no-upstream'
|
|
272
301
|
try {
|
|
273
302
|
upstream = await tryCommand( `git rev-parse --abbrev-ref ${branch}@{u}`, 'getGitUpstream' ) ?? 'no-upstream'
|
|
274
|
-
} catch ( error ) {}
|
|
303
|
+
} catch ( error ) {} // eslint-disable-line no-unused-vars
|
|
275
304
|
return { branch, upstream }
|
|
276
305
|
}
|
|
277
306
|
|
|
@@ -710,12 +739,12 @@ export const analyzeRepository = async ( giveGuidance ) => {
|
|
|
710
739
|
let wsName
|
|
711
740
|
try {
|
|
712
741
|
wsName = await shellCmd( 'npm exec -c pwd -ws' )
|
|
713
|
-
} catch ( err ) { }
|
|
742
|
+
} catch ( err ) { } // eslint-disable-line no-unused-vars
|
|
714
743
|
|
|
715
744
|
let gitRemote
|
|
716
745
|
try {
|
|
717
746
|
gitRemote = await shellCmd( 'git config --get remote.origin.url' )
|
|
718
|
-
} catch ( err ) { }
|
|
747
|
+
} catch ( err ) { } // eslint-disable-line no-unused-vars
|
|
719
748
|
|
|
720
749
|
// TODO: Add in Define VERBOSE_DOCKREATE_NPM="yes" for verbose build logging
|
|
721
750
|
// TODO: Validity check for version and package.json
|
package/src/bash-funcs
CHANGED
|
@@ -270,7 +270,7 @@ function sendToSlack() {
|
|
|
270
270
|
read -rd '' slackmsg<<EOSLACK
|
|
271
271
|
--- $running by \`$account\` in \`$GCP_PROJECT_ID\` @ $dts
|
|
272
272
|
\`$toPost\`
|
|
273
|
-
node `node --version` / `build-tools --version` / helm `helm version --short`
|
|
273
|
+
node `node --version` / npm `npm --version` / `build-tools --version` / helm `helm version --short`
|
|
274
274
|
EOSLACK
|
|
275
275
|
send-to-slack --project ${REFRESH_NPM_PROJECT:-leverege-registry} \
|
|
276
276
|
--config REFRESH_NPM_SLACK_CONFIG \
|
package/src/build-cnpg-image.mjs
CHANGED
|
@@ -139,7 +139,7 @@ const buildAndPushImage = async () => {
|
|
|
139
139
|
const dockerfilePath = path.join( buildDir, 'Dockerfile' )
|
|
140
140
|
|
|
141
141
|
try {
|
|
142
|
-
fs.writeFileSync( dockerfilePath, renderedDockerfile )
|
|
142
|
+
fs.writeFileSync( dockerfilePath, renderedDockerfile ) // eslint-disable-line security/detect-non-literal-fs-filename
|
|
143
143
|
|
|
144
144
|
log( chalk.yellow( '\nBuilding Docker image...' ) )
|
|
145
145
|
const cloudBuildSubmit = 'gcloud builds submit --project leverege-registry'
|
package/src/chart-compass.mjs
CHANGED
|
@@ -96,7 +96,7 @@ if ( args.init ) {
|
|
|
96
96
|
errorExit( '\n***ERROR: expected to run in the root of a platform-k8s branch - no overwhelm.yaml present' )
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
if ( fs.existsSync( args.compass ) ) {
|
|
99
|
+
if ( fs.existsSync( args.compass ) ) { // eslint-disable-line security/detect-non-literal-fs-filename
|
|
100
100
|
errorExit( `\n***ERROR: ${args.compass} compass file already exists - not overwriting` )
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -107,12 +107,12 @@ if ( args.init ) {
|
|
|
107
107
|
|
|
108
108
|
// simply wraps the YAML read/sync
|
|
109
109
|
const buildCompassMap = ( yamlFile ) => {
|
|
110
|
-
if ( !fs.existsSync( yamlFile ) ) {
|
|
110
|
+
if ( !fs.existsSync( yamlFile ) ) { // eslint-disable-line security/detect-non-literal-fs-filename
|
|
111
111
|
debug( `chart-compass file ${yamlFile} does not exist` )
|
|
112
112
|
process.exit( 1 )
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
const chartCompass = YAML.load( fs.readFileSync( yamlFile, 'utf8' ) )
|
|
115
|
+
const chartCompass = YAML.load( fs.readFileSync( yamlFile, 'utf8' ) ) // eslint-disable-line security/detect-non-literal-fs-filename
|
|
116
116
|
return chartCompass
|
|
117
117
|
}
|
|
118
118
|
|
|
@@ -151,7 +151,7 @@ try {
|
|
|
151
151
|
} else {
|
|
152
152
|
errorExit( `\n***ERROR: chart ${chartName} version ${chartVersion} already exists` )
|
|
153
153
|
}
|
|
154
|
-
} catch ( error ) {
|
|
154
|
+
} catch ( error ) { // eslint-disable-line no-unused-vars
|
|
155
155
|
debug( `Chart ${chartName} version ${chartVersion} does not exist - proceeding` )
|
|
156
156
|
}
|
|
157
157
|
|
|
@@ -123,7 +123,7 @@ const runner = async ( projects ) => {
|
|
|
123
123
|
log( `Project [${project}]` )
|
|
124
124
|
try {
|
|
125
125
|
await prepareContext( project ) // eslint-disable-line no-await-in-loop
|
|
126
|
-
} catch ( error ) {
|
|
126
|
+
} catch ( error ) { // eslint-disable-line no-unused-vars
|
|
127
127
|
log( `Project or context is invalid, skipping [${chalk.redBright( project )}]` )
|
|
128
128
|
continue
|
|
129
129
|
}
|
|
@@ -59,6 +59,7 @@ export default class DashboardManager {
|
|
|
59
59
|
// leaf directory — apply JSON files using basename as the Grafana folder name
|
|
60
60
|
const folderName = path.basename( dir )
|
|
61
61
|
for ( const file of jsonFiles ) {
|
|
62
|
+
// eslint-disable-next-line no-await-in-loop
|
|
62
63
|
const name = await this.#applyDashboard( folderName, path.join( dir, file.name ) )
|
|
63
64
|
if ( name ) applied.add( name )
|
|
64
65
|
}
|
|
@@ -79,6 +80,7 @@ export default class DashboardManager {
|
|
|
79
80
|
.filter( f => f.endsWith( '.json' ) )
|
|
80
81
|
|
|
81
82
|
for ( const file of files ) {
|
|
83
|
+
// eslint-disable-next-line no-await-in-loop
|
|
82
84
|
const name = await this.#applyDashboard( folder.name, path.join( dir, folder.name, file ) )
|
|
83
85
|
if ( name ) applied.add( name )
|
|
84
86
|
}
|
|
@@ -159,6 +161,7 @@ export default class DashboardManager {
|
|
|
159
161
|
if ( subDirs.length === 0 ) {
|
|
160
162
|
const folderName = path.basename( dir )
|
|
161
163
|
for ( const file of jsonFiles ) {
|
|
164
|
+
// eslint-disable-next-line no-await-in-loop
|
|
162
165
|
const name = await this.#applyDashboard( folderName, path.join( dir, file.name ), local )
|
|
163
166
|
if ( name ) applied.add( name )
|
|
164
167
|
}
|
|
@@ -168,6 +171,7 @@ export default class DashboardManager {
|
|
|
168
171
|
.filter( f => f.endsWith( '.json' ) )
|
|
169
172
|
|
|
170
173
|
for ( const file of files ) {
|
|
174
|
+
// eslint-disable-next-line no-await-in-loop
|
|
171
175
|
const name = await this.#applyDashboard( folder.name, path.join( dir, folder.name, file ), local )
|
|
172
176
|
if ( name ) applied.add( name )
|
|
173
177
|
}
|
|
@@ -259,6 +263,7 @@ export default class DashboardManager {
|
|
|
259
263
|
continue
|
|
260
264
|
}
|
|
261
265
|
try {
|
|
266
|
+
// eslint-disable-next-line no-await-in-loop
|
|
262
267
|
await api.deleteNamespacedConfigMap( { name, namespace : this.#namespace } )
|
|
263
268
|
log( chalk.red( ` ✗ pruned ${name}` ) )
|
|
264
269
|
} catch ( e ) {
|
|
@@ -290,6 +295,7 @@ export default class DashboardManager {
|
|
|
290
295
|
continue
|
|
291
296
|
}
|
|
292
297
|
try {
|
|
298
|
+
// eslint-disable-next-line no-await-in-loop
|
|
293
299
|
await api.deleteNamespacedConfigMap( { name, namespace : this.#namespace } )
|
|
294
300
|
log( chalk.red( ` ✗ pruned (local) ${name}` ) )
|
|
295
301
|
} catch ( e ) {
|