@leverege/build-tools 2.56.0 → 2.56.2
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/.husky/pre-commit +1 -0
- package/.husky/pre-push +1 -0
- package/package.json +7 -5
- package/src/Utils.mjs +30 -3
- package/src/chart-compass.mjs +2 -2
- package/src/chart-to-registry.mjs +0 -2
- package/src/docker-to-registry.mjs +0 -1
- package/src/firebaseDeploy.mjs +0 -1
- package/src/firebaseServe.mjs +0 -1
- package/src/hook-and-release.mjs +161 -0
- package/src/overwhelm.mjs +6 -5
- package/src/refresh-npm-token.mjs +0 -3
- package/src/tag-release.mjs +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
unleash
|
package/.husky/pre-push
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
unleash
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leverege/build-tools",
|
|
3
|
-
"version": "2.56.
|
|
3
|
+
"version": "2.56.2",
|
|
4
4
|
"description": "A collection of build / support tools for Leverege developers",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"clean": "rm -rf lib",
|
|
12
12
|
"lint": "find ./src -name \\*.\\*js | xargs npx eslint --report-unused-disable-directives",
|
|
13
|
-
"
|
|
13
|
+
"prepare": "npx husky",
|
|
14
|
+
"test": "echo \"no tests specified\" && exit 0"
|
|
14
15
|
},
|
|
15
16
|
"bin": {
|
|
16
17
|
"build-tools": "src/build-tools.mjs",
|
|
@@ -56,7 +57,7 @@
|
|
|
56
57
|
"author": "Leverege Devs",
|
|
57
58
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
58
59
|
"dependencies": {
|
|
59
|
-
"@google-cloud/artifact-registry": "^3.
|
|
60
|
+
"@google-cloud/artifact-registry": "^3.5.0",
|
|
60
61
|
"ansi-colors": "^4.1.3",
|
|
61
62
|
"chalk": "^5.3.0",
|
|
62
63
|
"command-line-args": "^6.0.1",
|
|
@@ -66,7 +67,7 @@
|
|
|
66
67
|
"execa": "^9.5.1",
|
|
67
68
|
"glob": "^11.0.0",
|
|
68
69
|
"handlebars": "^4.7.8",
|
|
69
|
-
"inquirer": "^12.0
|
|
70
|
+
"inquirer": "^12.1.0",
|
|
70
71
|
"js-yaml": "^4.1.0",
|
|
71
72
|
"ms": "^2.1.3",
|
|
72
73
|
"npm-registry-fetch": "^18.0.2",
|
|
@@ -76,10 +77,11 @@
|
|
|
76
77
|
"readline-sync": "^1.4.10",
|
|
77
78
|
"semver": "^7.6.3",
|
|
78
79
|
"simple-git": "^3.27.0",
|
|
79
|
-
"zx": "^8.2.
|
|
80
|
+
"zx": "^8.2.1"
|
|
80
81
|
},
|
|
81
82
|
"devDependencies": {
|
|
82
83
|
"@leverege/eslint-config-leverege": "^5.0.1",
|
|
84
|
+
"husky": "^9.1.6",
|
|
83
85
|
"npm": "^10.9.0"
|
|
84
86
|
}
|
|
85
87
|
}
|
package/src/Utils.mjs
CHANGED
|
@@ -9,6 +9,7 @@ import YAML from 'js-yaml'
|
|
|
9
9
|
|
|
10
10
|
let debugEnabled = process.env.BUILD_TOOLS_DEBUG === '1'
|
|
11
11
|
|
|
12
|
+
export const enableDebug = () => { debugEnabled = true }
|
|
12
13
|
export const disableDebug = () => { debugEnabled = false }
|
|
13
14
|
|
|
14
15
|
/* eslint-disable no-console */
|
|
@@ -382,13 +383,14 @@ export const parseHelmChart = async ( helmroot = './helm' ) => {
|
|
|
382
383
|
} )
|
|
383
384
|
}
|
|
384
385
|
|
|
385
|
-
export const
|
|
386
|
+
export const getRepositoryDescr = async () => {
|
|
387
|
+
const currentDir = process.cwd()
|
|
388
|
+
const workingDir = process.env.PWD
|
|
386
389
|
const gitRoot = await getGitRootDirectory()
|
|
390
|
+
const { branch : gitBranch, upstream : gitUpstream } = await getGitUpstream()
|
|
387
391
|
const subPkgs = await glob( `${gitRoot}/packages/**/package.json`, { ignore : '/**/node_modules/**' } )
|
|
388
392
|
const helmChart = await parseHelmChart()
|
|
389
393
|
const isMonoRepo = subPkgs?.length > 0
|
|
390
|
-
|
|
391
|
-
// Verify the presence of a root package.json file for all monorepos
|
|
392
394
|
let rootPackageJson
|
|
393
395
|
try {
|
|
394
396
|
rootPackageJson = await parseJsonFile( `${gitRoot}/package.json` )
|
|
@@ -396,6 +398,31 @@ export const analyzeRepository = async ( giveGuidance ) => {
|
|
|
396
398
|
rootPackageJson = { isInvalid : true, error : 'invalid or non-existent root package.json file' }
|
|
397
399
|
}
|
|
398
400
|
const isNpmWorkspace = rootPackageJson?.workspaces?.length > 0
|
|
401
|
+
|
|
402
|
+
return {
|
|
403
|
+
currentDir,
|
|
404
|
+
workingDir,
|
|
405
|
+
gitBranch,
|
|
406
|
+
gitRoot,
|
|
407
|
+
gitUpstream,
|
|
408
|
+
helmChart,
|
|
409
|
+
isMonoRepo,
|
|
410
|
+
isNpmWorkspace,
|
|
411
|
+
rootPackageJson,
|
|
412
|
+
subPkgs,
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
export const analyzeRepository = async ( giveGuidance ) => {
|
|
417
|
+
const {
|
|
418
|
+
gitRoot,
|
|
419
|
+
subPkgs,
|
|
420
|
+
helmChart,
|
|
421
|
+
isMonoRepo,
|
|
422
|
+
rootPackageJson,
|
|
423
|
+
isNpmWorkspace,
|
|
424
|
+
} = await getRepositoryDescr()
|
|
425
|
+
|
|
399
426
|
if ( isMonoRepo && rootPackageJson.isInvalid ) {
|
|
400
427
|
log( chalk.red.bold( `
|
|
401
428
|
***REQUIRED: A package.json file is required at the monorepo root` ) )
|
package/src/chart-compass.mjs
CHANGED
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
shellCmd } from './Utils.mjs'
|
|
23
23
|
|
|
24
24
|
const commandLineOptions = [ // Use commandLineOptions to tie into the Usage statements
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
{
|
|
27
27
|
name : 'location',
|
|
28
28
|
type : String,
|
|
@@ -48,7 +48,7 @@ const commandLineOptions = [ // Use commandLineOptions to tie into the Usage sta
|
|
|
48
48
|
type : Boolean,
|
|
49
49
|
description : '{green display this help screen}',
|
|
50
50
|
},
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
]
|
|
53
53
|
|
|
54
54
|
const sections = [
|
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
shellCmd } from './Utils.mjs'
|
|
21
21
|
|
|
22
22
|
const commandLineOptions = [ // Use commandLineOptions to tie into the Usage statements
|
|
23
|
-
/* eslint-disable max-len */
|
|
24
23
|
{
|
|
25
24
|
name : 'location',
|
|
26
25
|
type : String,
|
|
@@ -51,7 +50,6 @@ const commandLineOptions = [ // Use commandLineOptions to tie into the Usage sta
|
|
|
51
50
|
type : Boolean,
|
|
52
51
|
description : '{green display this help screen}',
|
|
53
52
|
},
|
|
54
|
-
/* eslint-enable max-len */
|
|
55
53
|
]
|
|
56
54
|
|
|
57
55
|
const sections = [
|
package/src/firebaseDeploy.mjs
CHANGED
package/src/firebaseServe.mjs
CHANGED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'node:fs'
|
|
4
|
+
import path from 'node:path'
|
|
5
|
+
|
|
6
|
+
import chalk from 'chalk'
|
|
7
|
+
import commandLineArgs from 'command-line-args'
|
|
8
|
+
import commandLineUsage from 'command-line-usage'
|
|
9
|
+
import SimpleGit from 'simple-git'
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
condir,
|
|
13
|
+
debug,
|
|
14
|
+
enableDebug,
|
|
15
|
+
getRepositoryDescr,
|
|
16
|
+
log,
|
|
17
|
+
shellCmd,
|
|
18
|
+
} from './Utils.mjs'
|
|
19
|
+
|
|
20
|
+
const git = new SimpleGit()
|
|
21
|
+
const repoDescr = await getRepositoryDescr()
|
|
22
|
+
|
|
23
|
+
debug( { repoDescr }, '--------LOCAL UNLEASH-------' )
|
|
24
|
+
|
|
25
|
+
const hookAndReleaseOptions = [
|
|
26
|
+
{
|
|
27
|
+
name : 'init',
|
|
28
|
+
type : Boolean,
|
|
29
|
+
default : false,
|
|
30
|
+
description : '{green bootstraps the repo .har directory and adds appropriate git hook}',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name : 'debug',
|
|
34
|
+
type : Boolean,
|
|
35
|
+
default : false,
|
|
36
|
+
description : '{yellow enables verbose debugging}',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name : 'help',
|
|
40
|
+
type : Boolean,
|
|
41
|
+
default : false,
|
|
42
|
+
description : '{green display this help screen}',
|
|
43
|
+
},
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
const sections = [
|
|
47
|
+
{
|
|
48
|
+
header : 'Leverege Hook and Release Script',
|
|
49
|
+
content : '{green This tool help...}',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
header : 'Options',
|
|
53
|
+
optionList : hookAndReleaseOptions,
|
|
54
|
+
},
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
const args = commandLineArgs( hookAndReleaseOptions, { camelCase : true, partial : true } )
|
|
58
|
+
const usage = commandLineUsage( sections )
|
|
59
|
+
|
|
60
|
+
if ( args.debug ) {
|
|
61
|
+
enableDebug()
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if ( args.help ) {
|
|
65
|
+
log( usage )
|
|
66
|
+
process.exit( 0 )
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* eslint-disable no-underscore-dangle */
|
|
70
|
+
if ( args._unknown ) {
|
|
71
|
+
log( usage )
|
|
72
|
+
log( `\nUnrecognized argument [${chalk.bold.red( args._unknown )}]\n` )
|
|
73
|
+
process.exit( 1 )
|
|
74
|
+
}
|
|
75
|
+
/* eslint-enable no-underscore-dangle */
|
|
76
|
+
|
|
77
|
+
if ( args.init ) {
|
|
78
|
+
const harDir = `${repoDescr.gitRoot}/.har`
|
|
79
|
+
if ( fs.existsSync( harDir ) ) {
|
|
80
|
+
log( `this repo already has ${harDir}` )
|
|
81
|
+
process.exit( 1 )
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
fs.mkdirSync( harDir )
|
|
85
|
+
await git.addConfig( 'core.hookspath', '.har' )
|
|
86
|
+
process.exit( 0 )
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const getCurrentBranchName = async () => {
|
|
90
|
+
const branchInfo = await git.branch()
|
|
91
|
+
|
|
92
|
+
// first check to see if there are no branches - new repo?
|
|
93
|
+
if ( Object.keys( branchInfo.branches ).length === 0 ) { return '' }
|
|
94
|
+
|
|
95
|
+
return Object
|
|
96
|
+
.entries( branchInfo.branches )
|
|
97
|
+
.find( ( [ name, info ] ) => ( info.current ) )[0]
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const isProtected = async () => {
|
|
101
|
+
const theBranch = await getCurrentBranchName()
|
|
102
|
+
|
|
103
|
+
const protectedBranches = [ 'main', 'master', 'development' ]
|
|
104
|
+
const additionalProtectedBranches = [ ...process.argv.slice( 2 ) ]
|
|
105
|
+
|
|
106
|
+
// Check if the current branch starts with any of the additional
|
|
107
|
+
// protected branch name
|
|
108
|
+
let matchesAdditionalBranch = false
|
|
109
|
+
for ( let i = 0; i < additionalProtectedBranches.length; i++ ) {
|
|
110
|
+
matchesAdditionalBranch = matchesAdditionalBranch ||
|
|
111
|
+
theBranch.startsWith( additionalProtectedBranches[i] )
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return protectedBranches.includes( theBranch ) || matchesAdditionalBranch
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Identify the package directory based on staged files
|
|
118
|
+
const getPackageDirectory = async () => {
|
|
119
|
+
const gitDiff = await git.diff( [ '--name-only', '--cached' ] )
|
|
120
|
+
const stagedFiles = gitDiff.split( '\n' )
|
|
121
|
+
const packageDirs = new Set()
|
|
122
|
+
|
|
123
|
+
// Loop through staged files and extract package directories
|
|
124
|
+
stagedFiles.forEach( ( file ) => {
|
|
125
|
+
const parts = file.split( path.sep ) // Split path to identify package
|
|
126
|
+
if ( parts.length > 1 && parts[0] === 'packages' ) {
|
|
127
|
+
const packageDir = parts[1]
|
|
128
|
+
packageDirs.add( packageDir )
|
|
129
|
+
}
|
|
130
|
+
} )
|
|
131
|
+
|
|
132
|
+
const packageDirsArray = Array.from( packageDirs )
|
|
133
|
+
debug( { stagedFiles, packageDirsArray }, '<==unleash: getPackageDirectory' )
|
|
134
|
+
return packageDirsArray
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const npmRunner = async ( script, packageDir ) => {
|
|
138
|
+
try {
|
|
139
|
+
const cmd = `npm run ${script}`
|
|
140
|
+
const results = await shellCmd( cmd, { cwd : path.join( process.cwd(), 'packages', packageDir ), stdio : 'inherit' } )
|
|
141
|
+
return results
|
|
142
|
+
} catch ( err ) {
|
|
143
|
+
process.exit( 1 )
|
|
144
|
+
}
|
|
145
|
+
return undefined
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
( async () => {
|
|
149
|
+
if ( await isProtected() ) {
|
|
150
|
+
const packageDirs = await getPackageDirectory()
|
|
151
|
+
for ( let pi = 0; pi < packageDirs.length; pi++ ) {
|
|
152
|
+
const packageDir = packageDirs[pi]
|
|
153
|
+
const script = [ 'test', 'lint' ]
|
|
154
|
+
for ( let i = 0; i < script.length; i++ ) {
|
|
155
|
+
await npmRunner( script[i], packageDir ) // eslint-disable-line no-await-in-loop
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
process.exit( 0 )
|
|
160
|
+
}
|
|
161
|
+
} )()
|
package/src/overwhelm.mjs
CHANGED
|
@@ -266,19 +266,20 @@ const ahoy = glob.sync( '*/', opt )
|
|
|
266
266
|
|
|
267
267
|
// Verifies that all values in a config block are quoted
|
|
268
268
|
const validValuesLocalConfig = ( vlf ) => {
|
|
269
|
-
if ( !
|
|
269
|
+
if ( !fs.existsSync( vlf ) ) { return undefined }
|
|
270
270
|
|
|
271
271
|
const valuesLocal = YAML.load( fs.readFileSync( vlf, { encoding : 'utf-8' } ) )
|
|
272
|
-
const configBlock = valuesLocal
|
|
272
|
+
const configBlock = valuesLocal?.config
|
|
273
273
|
|
|
274
274
|
// only care about validating config at this time
|
|
275
275
|
if ( configBlock ) {
|
|
276
|
-
|
|
277
|
-
|
|
276
|
+
Object.entries( configBlock ).forEach( ( cfgLine ) => {
|
|
277
|
+
const [ key, value ] = cfgLine
|
|
278
|
+
if ( !isString( value ) ) {
|
|
278
279
|
err( { configBlock }, '***Bad config block' )
|
|
279
280
|
errorExit( `Is ${key} missing quotes around ${value} in ${vlf}?` )
|
|
280
281
|
}
|
|
281
|
-
}
|
|
282
|
+
} )
|
|
282
283
|
}
|
|
283
284
|
|
|
284
285
|
return true // TODO: return the already read valuesLocal info?
|
|
@@ -29,7 +29,6 @@ import { lt as semverLt } from 'semver'
|
|
|
29
29
|
import { debug, log, shellCmd } from './Utils.mjs'
|
|
30
30
|
|
|
31
31
|
const refreshTokenOptions = [ // Use refreshTokenOptions to tie into the Usage statements
|
|
32
|
-
/* eslint-disable max-len */
|
|
33
32
|
{
|
|
34
33
|
name : 'project',
|
|
35
34
|
type : String,
|
|
@@ -60,7 +59,6 @@ const refreshTokenOptions = [ // Use refreshTokenOptions to tie into the Usage s
|
|
|
60
59
|
default : false,
|
|
61
60
|
description : '{green display this help screen}',
|
|
62
61
|
},
|
|
63
|
-
/* eslint-enable max-len */
|
|
64
62
|
]
|
|
65
63
|
|
|
66
64
|
const sections = [
|
|
@@ -245,7 +243,6 @@ try {
|
|
|
245
243
|
const now = ( new Date() ).toLocaleString()
|
|
246
244
|
const account = await shellCmd( 'gcloud config get account' )
|
|
247
245
|
const slackData = {
|
|
248
|
-
// eslint-disable-next-line max-len
|
|
249
246
|
text : `--- npmrc refreshed by \`${account}\` at ${now}\n tokens RW [\`${npmrc.token}\`] RO [\`${npmrcRo.token}\`]`,
|
|
250
247
|
channel : slackConfig.channel,
|
|
251
248
|
}
|