@leverege/build-tools 2.91.1 → 2.93.0-beta.10
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/.vscode/settings.json +3 -0
- package/package.json +8 -3
- package/src/Utils.mjs +9 -0
- package/src/artifacts/ArtifactPuller.mjs +21 -0
- package/src/artifacts/ArtifactPusher.mjs +133 -0
- package/src/artifacts/Structs.mjs +63 -0
- package/src/artifacts/Utils.mjs +49 -0
- package/src/artifacts/pull-artifact.mjs +7 -0
- package/src/artifacts/push-artifact.mjs +54 -0
- package/src/refresh-npm-token.mjs +25 -0
- package/leverege-build-tools-2.21.13.tgz +0 -0
- package/lib/server/build-tools.js +0 -138
- package/lib/server/firebaseDeploy.js +0 -195
- package/lib/server/firebaseServe.js +0 -116
- package/lib/server/getfbcfg.js +0 -25
- package/lib/server/getjson.js +0 -70
- package/lib/server/overwhelm.js +0 -447
- package/lib/server/push-my-chart.js +0 -18
- package/lib/server/refresh-npm-token.js +0 -135
- package/lib/server/tag-release.js +0 -681
- package/lib/server/unleash.js +0 -50
- package/lib/web/build-tools.js +0 -138
- package/lib/web/firebaseDeploy.js +0 -195
- package/lib/web/firebaseServe.js +0 -116
- package/lib/web/getfbcfg.js +0 -25
- package/lib/web/getjson.js +0 -70
- package/lib/web/overwhelm.js +0 -447
- package/lib/web/push-my-chart.js +0 -18
- package/lib/web/refresh-npm-token.js +0 -135
- package/lib/web/tag-release.js +0 -681
- package/lib/web/unleash.js +0 -50
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leverege/build-tools",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.93.0-beta.10",
|
|
4
4
|
"description": "A collection of build / support tools for Leverege developers",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"clean": "rm -rf lib",
|
|
12
12
|
"lint": "find ./src -name \\*.\\*js | xargs npx eslint --report-unused-disable-directives",
|
|
13
13
|
"prepare": "[ $SKIP_PREPARE ] && exit 0 || ./src/hook-and-release.mjs",
|
|
14
|
-
"test": "
|
|
14
|
+
"test": "mocha -t 60000 --exit 'test/**/*.mjs'",
|
|
15
15
|
"prepack": "npm exec prepack"
|
|
16
16
|
},
|
|
17
17
|
"bin": {
|
|
@@ -54,7 +54,9 @@
|
|
|
54
54
|
"pkglint": "src/pkglint.sh",
|
|
55
55
|
"prepack": "src/prepack.mjs",
|
|
56
56
|
"prune-git": "src/prune-git.sh",
|
|
57
|
+
"pull-artifact": "src/artifacts/pull-artifact.mjs",
|
|
57
58
|
"pull-git": "src/pull-git.sh",
|
|
59
|
+
"push-artifact": "src/artifacts/push-artifact.mjs",
|
|
58
60
|
"push-my-chart": "src/push-my-chart.mjs",
|
|
59
61
|
"refresh-npm-token": "src/refresh-npm-token.mjs",
|
|
60
62
|
"refresh-py-idx": "src/refresh-py-idx.sh",
|
|
@@ -91,11 +93,14 @@
|
|
|
91
93
|
"shell-quote": "^1.8.3",
|
|
92
94
|
"simple-git": "^3.30.0",
|
|
93
95
|
"sloc": "^0.3.2",
|
|
96
|
+
"superstruct": "^2.0.2",
|
|
94
97
|
"toml": "^3.0.0",
|
|
95
98
|
"zx": "^8.8.5"
|
|
96
99
|
},
|
|
97
100
|
"devDependencies": {
|
|
98
101
|
"@leverege/eslint-config-leverege": "^5.1.1",
|
|
102
|
+
"chai": "^6.2.1",
|
|
103
|
+
"mocha": "^11.7.5",
|
|
99
104
|
"npm": "^11.6.2"
|
|
100
105
|
}
|
|
101
|
-
}
|
|
106
|
+
}
|
package/src/Utils.mjs
CHANGED
|
@@ -224,6 +224,15 @@ export const gitRepoIsDirty = async () => {
|
|
|
224
224
|
return cleanliness?.length > 0
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
+
export const parseYamlFile = async ( filePath ) => {
|
|
228
|
+
try {
|
|
229
|
+
const fileContent = await fs.promises.readFile( filePath, 'utf8' )
|
|
230
|
+
return YAML.load( fileContent )
|
|
231
|
+
} catch ( error ) {
|
|
232
|
+
throw new Error( `Failed to parse YAML file ${filePath}: ${error.message}` )
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
227
236
|
export const parseJsonFile = async ( jsonFile ) => {
|
|
228
237
|
// TODO: rework this file exists logic / throw
|
|
229
238
|
if ( !fs.existsSync( jsonFile ) ) { return undefined } // eslint-disable-line security/detect-non-literal-fs-filename
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import crypto from 'crypto'
|
|
2
|
+
import fs from 'fs'
|
|
3
|
+
|
|
4
|
+
class ArtifactPusher {
|
|
5
|
+
constructor( artifact ) {
|
|
6
|
+
this.artifact = artifact
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
async pull() {
|
|
10
|
+
throw new Error( 'Not implemented' )
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
class GenericArtifactPusher extends ArtifactPusher {
|
|
15
|
+
|
|
16
|
+
async pull() {
|
|
17
|
+
throw new Error( 'Not implemented' )
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { ArtifactPusher, GenericArtifactPusher }
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import crypto from 'crypto'
|
|
2
|
+
import fs from 'fs'
|
|
3
|
+
|
|
4
|
+
class ArtifactPusher {
|
|
5
|
+
constructor( artifact ) {
|
|
6
|
+
this.artifact = artifact
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
calculateHash() {
|
|
10
|
+
try {
|
|
11
|
+
const hash = crypto.createHash( 'sha256' )
|
|
12
|
+
hash.update( fs.readFileSync( this.artifact.source_path ) )
|
|
13
|
+
return hash.digest( 'base64url' )
|
|
14
|
+
} catch ( error ) {
|
|
15
|
+
console.error( error )
|
|
16
|
+
throw new Error( `Failed to calculate hash for artifact ${this.artifact.name}: ${error.message}` )
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async exists() {
|
|
21
|
+
throw new Error( 'Not implemented' )
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async push() {
|
|
25
|
+
throw new Error( 'Not implemented' )
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
class GenericArtifactPusher extends ArtifactPusher {
|
|
30
|
+
|
|
31
|
+
async exists() {
|
|
32
|
+
const isDirectory = fs.statSync( this.artifact.source_path ).isDirectory()
|
|
33
|
+
|
|
34
|
+
// If source path is a directory, check whether the destination path alreadu exists in the registry
|
|
35
|
+
if ( isDirectory ) {
|
|
36
|
+
// For the time being, return false, and let gcloud skip existing files in upload-time.
|
|
37
|
+
// It's pretty slow, might be worth to break down the directory into individual artifacts
|
|
38
|
+
// and manage each one with its own pusher.
|
|
39
|
+
return false
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Check if artifact already exists in the registry
|
|
43
|
+
console.log( 'Checking if artifact already exists in the registry...' )
|
|
44
|
+
|
|
45
|
+
const artifactHash = this.calculateHash()
|
|
46
|
+
|
|
47
|
+
const command = `gcloud artifacts files list \
|
|
48
|
+
--project=${this.artifact.gcp_project_id} \
|
|
49
|
+
--location=${this.artifact.gcp_location} \
|
|
50
|
+
--repository=${this.artifact.gcp_artifact_registry_repository_name} \
|
|
51
|
+
--package=${this.artifact.gcp_artifact_registry_package_name} \
|
|
52
|
+
--version ${this.artifact.gcp_artifact_registry_package_version} \
|
|
53
|
+
--filter="name:${this.artifact.destination_path}" \
|
|
54
|
+
--format="json"`
|
|
55
|
+
|
|
56
|
+
console.log( 'Command:', command.replace( /\s+/g, ' ' ).trim() )
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
const { execSync } = await import( 'child_process' )
|
|
60
|
+
const result = execSync( command, { encoding : 'utf8', stdio : 'pipe' } )
|
|
61
|
+
|
|
62
|
+
// Parse the JSON response
|
|
63
|
+
const files = JSON.parse( result )
|
|
64
|
+
|
|
65
|
+
// Check if any files were found and match our hash
|
|
66
|
+
if ( files && files.length > 0 ) {
|
|
67
|
+
for ( const file of files ) {
|
|
68
|
+
for ( const hash of file.hashes ) {
|
|
69
|
+
// Compare without padding since base64url may omit trailing '='
|
|
70
|
+
const normalizedOurHash = artifactHash.replace( /=+$/, '' )
|
|
71
|
+
const normalizedRegistryHash = hash.value.replace( /=+$/, '' )
|
|
72
|
+
if ( hash.type === 'SHA256' && normalizedRegistryHash === normalizedOurHash ) {
|
|
73
|
+
console.log( `Artifact already exists in the registry: ${this.artifact.gcp_artifact_registry_package_name}:${this.artifact.gcp_artifact_registry_package_version}` )
|
|
74
|
+
return true
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
console.log( 'Artifact does not exist in the registry' )
|
|
80
|
+
return false
|
|
81
|
+
|
|
82
|
+
} catch ( error ) {
|
|
83
|
+
console.error( 'Error checking artifact existence:', error.message )
|
|
84
|
+
throw error
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async push() {
|
|
89
|
+
console.log( 'Publishing artifact to registry...' )
|
|
90
|
+
|
|
91
|
+
if ( await this.exists() ) {
|
|
92
|
+
console.log( 'Artifact already exists in the registry' )
|
|
93
|
+
return false
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
console.log( 'Uploading artifact to registry...' )
|
|
97
|
+
|
|
98
|
+
let command = ''
|
|
99
|
+
|
|
100
|
+
command = `gcloud artifacts generic upload \
|
|
101
|
+
--project=${this.artifact.gcp_project_id} \
|
|
102
|
+
--location=${this.artifact.gcp_location} \
|
|
103
|
+
--repository=${this.artifact.gcp_artifact_registry_repository_name} \
|
|
104
|
+
--package=${this.artifact.gcp_artifact_registry_package_name} \
|
|
105
|
+
--version=${this.artifact.gcp_artifact_registry_package_version}`
|
|
106
|
+
|
|
107
|
+
const isDirectory = fs.statSync( this.artifact.source_path ).isDirectory()
|
|
108
|
+
if ( isDirectory ) {
|
|
109
|
+
command += ` --source-directory=${this.artifact.source_path}`
|
|
110
|
+
command += ' --skip-existing'
|
|
111
|
+
} else {
|
|
112
|
+
command += ` --source=${this.artifact.source_path}`
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if ( this.artifact.destination_path ) {
|
|
116
|
+
command += ` --destination-path=${this.artifact.destination_path}`
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
console.log( 'Command:', command.replace( /\s+/g, ' ' ).trim() )
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
const { execSync } = await import( 'child_process' )
|
|
123
|
+
execSync( command, { encoding : 'utf8', stdio : 'pipe' } )
|
|
124
|
+
console.log( `Successfully published artifact: ${this.artifact.gcp_artifact_registry_package_name}:${this.artifact.gcp_artifact_registry_package_version}` )
|
|
125
|
+
return true
|
|
126
|
+
} catch ( error ) {
|
|
127
|
+
console.error( 'Error publishing artifact:', error.message )
|
|
128
|
+
return false
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export { ArtifactPusher, GenericArtifactPusher }
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { assign, object, string, array, optional, enums, union } from 'superstruct'
|
|
2
|
+
|
|
3
|
+
const ArtifactTypeEnum = {
|
|
4
|
+
GENERIC : 'generic',
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
// Superstruct schema for individual artifact configuration
|
|
8
|
+
const PartialArtifactSchema = object( {
|
|
9
|
+
name : string(),
|
|
10
|
+
type : optional( enums( Object.values( ArtifactTypeEnum ) ) ),
|
|
11
|
+
gcp_project_id : optional( string() ),
|
|
12
|
+
gcp_location : optional( string() ),
|
|
13
|
+
gcp_artifact_registry_repository_name : optional( string() ),
|
|
14
|
+
gcp_artifact_registry_package_name : optional( string() ),
|
|
15
|
+
gcp_artifact_registry_package_version : optional( string() )
|
|
16
|
+
} )
|
|
17
|
+
|
|
18
|
+
const ArtifactSchema = assign( PartialArtifactSchema, object( {
|
|
19
|
+
name : string(),
|
|
20
|
+
type : enums( Object.values( ArtifactTypeEnum ) ),
|
|
21
|
+
gcp_project_id : string(),
|
|
22
|
+
gcp_location : string(),
|
|
23
|
+
gcp_artifact_registry_repository_name : string(),
|
|
24
|
+
gcp_artifact_registry_package_name : string(),
|
|
25
|
+
gcp_artifact_registry_package_version : string()
|
|
26
|
+
} ) )
|
|
27
|
+
|
|
28
|
+
const PartialGenericArtifactSchema = assign( PartialArtifactSchema, object( {
|
|
29
|
+
type : enums( [ ArtifactTypeEnum.GENERIC ] ),
|
|
30
|
+
source_path : string(),
|
|
31
|
+
destination_path : string()
|
|
32
|
+
} ) )
|
|
33
|
+
|
|
34
|
+
const GenericArtifactSchema = assign( ArtifactSchema, object( {
|
|
35
|
+
source_path : string(),
|
|
36
|
+
destination_path : optional( string() )
|
|
37
|
+
} ) )
|
|
38
|
+
|
|
39
|
+
// Superstruct schema for defaults configuration
|
|
40
|
+
const DefaultsSchema = object( {
|
|
41
|
+
gcp_project_id : optional( string() ),
|
|
42
|
+
gcp_location : optional( string() ),
|
|
43
|
+
gcp_artifact_registry_repository_name : optional( string() ),
|
|
44
|
+
gcp_artifact_registry_package_name : optional( string() ),
|
|
45
|
+
gcp_artifact_registry_package_version : optional( string() )
|
|
46
|
+
} )
|
|
47
|
+
|
|
48
|
+
// Superstruct schema for the complete artifacts configuration with defaults
|
|
49
|
+
const ArtifactsSchema = object( {
|
|
50
|
+
defaults : optional( DefaultsSchema ),
|
|
51
|
+
artifacts : array( union( [ PartialArtifactSchema, PartialGenericArtifactSchema ] ) )
|
|
52
|
+
} )
|
|
53
|
+
|
|
54
|
+
const FlattenedArtifactsSchema = array( assign( union( [ ArtifactSchema, GenericArtifactSchema ] ) ) )
|
|
55
|
+
|
|
56
|
+
export {
|
|
57
|
+
ArtifactTypeEnum,
|
|
58
|
+
ArtifactsSchema,
|
|
59
|
+
FlattenedArtifactsSchema,
|
|
60
|
+
ArtifactSchema,
|
|
61
|
+
DefaultsSchema,
|
|
62
|
+
GenericArtifactSchema,
|
|
63
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { validate } from 'superstruct'
|
|
2
|
+
|
|
3
|
+
import { parseYamlFile, warning } from '../Utils.mjs'
|
|
4
|
+
|
|
5
|
+
import { ArtifactTypeEnum, ArtifactsSchema, GenericArtifactSchema } from './Structs.mjs'
|
|
6
|
+
|
|
7
|
+
const getArtifactsSchema = async ( artifactsFilePath = './artifacts.yml' ) => {
|
|
8
|
+
const artifactsConfig = await parseYamlFile( artifactsFilePath )
|
|
9
|
+
const [ error, result ] = validate( artifactsConfig, ArtifactsSchema )
|
|
10
|
+
if ( error ) {
|
|
11
|
+
throw new Error( `Invalid artifacts.yml file: ${error.message}` )
|
|
12
|
+
}
|
|
13
|
+
return result
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const flattenArtifactsSchema = ( artifactsSchema ) => {
|
|
17
|
+
return artifactsSchema.artifacts.reduce( ( flattenedArtifacts, artifact ) => {
|
|
18
|
+
const mergedArtifact = {
|
|
19
|
+
...artifactsSchema.defaults,
|
|
20
|
+
...artifact
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let schema
|
|
24
|
+
switch ( mergedArtifact.type ) {
|
|
25
|
+
case ArtifactTypeEnum.GENERIC:
|
|
26
|
+
schema = GenericArtifactSchema
|
|
27
|
+
break
|
|
28
|
+
default:
|
|
29
|
+
warning( `Unsupported artifact type "${mergedArtifact.type}"` )
|
|
30
|
+
break
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if ( !schema ) {
|
|
34
|
+
warning( `Invalid artifact type "${mergedArtifact.type}"` )
|
|
35
|
+
return flattenedArtifacts
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const [ error, validatedArtifact ] = validate( mergedArtifact, schema )
|
|
39
|
+
|
|
40
|
+
if ( error ) {
|
|
41
|
+
warning( `Invalid artifact "${mergedArtifact.name}": ${error.message}` )
|
|
42
|
+
return flattenedArtifacts
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return [ ...flattenedArtifacts, validatedArtifact ]
|
|
46
|
+
}, [] )
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export { getArtifactsSchema, flattenArtifactsSchema }
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { warning } from '../Utils.mjs'
|
|
4
|
+
|
|
5
|
+
import { getArtifactsSchema, flattenArtifactsSchema } from './Utils.mjs'
|
|
6
|
+
import { ArtifactTypeEnum } from './Structs.mjs'
|
|
7
|
+
import { GenericArtifactPusher } from './ArtifactPusher.mjs'
|
|
8
|
+
|
|
9
|
+
async function main() {
|
|
10
|
+
|
|
11
|
+
// If an argument is provided, use it as the artifacts.yml file path
|
|
12
|
+
const artifactsYmlPath = process.argv[2]
|
|
13
|
+
const artifactPackageName = process.argv[3]
|
|
14
|
+
const artifactPackageVersion = process.argv[4]
|
|
15
|
+
|
|
16
|
+
if ( artifactsYmlPath ) {
|
|
17
|
+
const artifactsSchema = await getArtifactsSchema( artifactsYmlPath )
|
|
18
|
+
const flattenedArtifactsSchema = flattenArtifactsSchema( artifactsSchema )
|
|
19
|
+
|
|
20
|
+
// Open for unexpected matches if we end up re-using the same package name and version for
|
|
21
|
+
// multiple artifacts spread across multiple repositories and/or projects.
|
|
22
|
+
const filteredArtifactSchemas = flattenedArtifactsSchema.filter(
|
|
23
|
+
artifact => artifact.gcp_artifact_registry_package_name === artifactPackageName &&
|
|
24
|
+
artifact.gcp_artifact_registry_package_version === artifactPackageVersion )
|
|
25
|
+
|
|
26
|
+
if ( filteredArtifactSchemas.length === 0 ) {
|
|
27
|
+
console.error( `No artifacts found for ${artifactPackageName} version ${artifactPackageVersion} in ${artifactsYmlPath}` )
|
|
28
|
+
process.exit( 1 )
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// TODO: Use concurrency to package artifacts and provide summary of results.
|
|
32
|
+
for ( const artifactSchema of filteredArtifactSchemas ) {
|
|
33
|
+
let packager
|
|
34
|
+
switch ( artifactSchema.type ) {
|
|
35
|
+
case ArtifactTypeEnum.GENERIC:
|
|
36
|
+
packager = new GenericArtifactPusher( artifactSchema )
|
|
37
|
+
break
|
|
38
|
+
default:
|
|
39
|
+
warning( `Unsupported artifact type "${artifactSchema.type}"` )
|
|
40
|
+
continue
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if ( !packager ) {
|
|
44
|
+
warning( `Unsupported artifact type "${artifactSchema.type}"` )
|
|
45
|
+
continue
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// eslint-disable-next-line no-await-in-loop
|
|
49
|
+
await packager.package()
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
main()
|
|
@@ -25,9 +25,13 @@ import commandLineArgs from 'command-line-args'
|
|
|
25
25
|
import commandLineUsage from 'command-line-usage'
|
|
26
26
|
import ms from 'ms'
|
|
27
27
|
import { lt as semverLt } from 'semver'
|
|
28
|
+
import YAML from 'js-yaml'
|
|
28
29
|
|
|
29
30
|
import { debug, log, shellCmd } from './Utils.mjs'
|
|
30
31
|
|
|
32
|
+
const AUTH_TOKEN_REGEX = /_authToken=(.+)/
|
|
33
|
+
const YARNRC_FILE_NAME = `${os.homedir()}/.yarnrc.yml`
|
|
34
|
+
|
|
31
35
|
const refreshTokenOptions = [ // Use refreshTokenOptions to tie into the Usage statements
|
|
32
36
|
{
|
|
33
37
|
name : 'project',
|
|
@@ -59,6 +63,12 @@ const refreshTokenOptions = [ // Use refreshTokenOptions to tie into the Usage s
|
|
|
59
63
|
default : false,
|
|
60
64
|
description : '{green display this help screen}',
|
|
61
65
|
},
|
|
66
|
+
{
|
|
67
|
+
name : 'update-yarnrc',
|
|
68
|
+
type : Boolean,
|
|
69
|
+
defaultValue : true,
|
|
70
|
+
description : '{green updates the npmAuthToken variable of your .yarnrc.yml file (in addition to .npmrc/.npmrc.ro)}'
|
|
71
|
+
}
|
|
62
72
|
]
|
|
63
73
|
|
|
64
74
|
const sections = [
|
|
@@ -195,11 +205,14 @@ const getGcpSecretCommand = ( secretName ) => {
|
|
|
195
205
|
|
|
196
206
|
// fetch the contents of the npmrc secret file stored on the specified project
|
|
197
207
|
let npmrcFile
|
|
208
|
+
let npmAuthToken
|
|
198
209
|
try {
|
|
199
210
|
const npmTokenFetcher = getGcpSecretCommand( 'REFRESH_NPM_NPMRC' )
|
|
200
211
|
debug( { npmTokenFetcher }, '<==Secret Fetcher' )
|
|
201
212
|
|
|
202
213
|
npmrcFile = await shellCmd( npmTokenFetcher )
|
|
214
|
+
npmAuthToken = npmrcFile.match( AUTH_TOKEN_REGEX )?.[1]
|
|
215
|
+
debug( { npmAuthToken }, '<==npmAuthToken' )
|
|
203
216
|
debug( { npmrcFile }, '<==shellCmd Output npmrc file' )// debug
|
|
204
217
|
} catch ( err ) {
|
|
205
218
|
log( chalk.yellow( `\nFailed Command => [${err.escapedCommand}]\n\n` ), chalk.red( err.stderr ) )
|
|
@@ -234,6 +247,18 @@ try {
|
|
|
234
247
|
fs.copyFileSync( filename, `${filename}-BAK` ) // make a backup for safety
|
|
235
248
|
}
|
|
236
249
|
fs.writeFileSync( filename, npmrcFile )
|
|
250
|
+
|
|
251
|
+
if ( args.updateYarnrc && npmAuthToken ) {
|
|
252
|
+
let yarnRcContent = { nodeLinker : 'node-modules' }
|
|
253
|
+
if ( fs.existsSync( YARNRC_FILE_NAME ) ) {
|
|
254
|
+
fs.copyFileSync( YARNRC_FILE_NAME, `${YARNRC_FILE_NAME}-BAK` )
|
|
255
|
+
yarnRcContent = YAML.load( fs.readFileSync( YARNRC_FILE_NAME, 'utf-8' ) )
|
|
256
|
+
debug( { yarnRcContent }, '<==yarnrc content' )
|
|
257
|
+
yarnRcContent.npmAuthToken = npmAuthToken
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
fs.writeFileSync( YARNRC_FILE_NAME, YAML.dump( yarnRcContent ) )
|
|
261
|
+
}
|
|
237
262
|
}
|
|
238
263
|
} catch ( fileErr ) {
|
|
239
264
|
log( fileErr, 'fs failed' )
|
|
Binary file
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
|
|
4
|
-
const fs = require('node:fs');
|
|
5
|
-
const path = require('node:path');
|
|
6
|
-
const chalk = require('chalk');
|
|
7
|
-
const cliArgs = require('command-line-args');
|
|
8
|
-
const cliHelp = require('command-line-usage');
|
|
9
|
-
const npmRegistryFetch = require('npm-registry-fetch');
|
|
10
|
-
const semverLt = require('semver/functions/lt');
|
|
11
|
-
|
|
12
|
-
/* eslint-disable no-console */
|
|
13
|
-
|
|
14
|
-
const optionList = [
|
|
15
|
-
// Use optionList to tie into the Usage statements
|
|
16
|
-
{
|
|
17
|
-
name: 'root',
|
|
18
|
-
type: Boolean,
|
|
19
|
-
default: false,
|
|
20
|
-
description: 'returns the root of the build-tools installation'
|
|
21
|
-
}, {
|
|
22
|
-
name: 'latest',
|
|
23
|
-
type: Boolean,
|
|
24
|
-
default: false,
|
|
25
|
-
description: 'verifies the latest build-tools are installed'
|
|
26
|
-
}, {
|
|
27
|
-
name: 'bashfun',
|
|
28
|
-
type: Boolean,
|
|
29
|
-
default: false,
|
|
30
|
-
description: 'source the output to define common bash helper functions'
|
|
31
|
-
}, {
|
|
32
|
-
name: 'reporoot',
|
|
33
|
-
type: Boolean,
|
|
34
|
-
default: false,
|
|
35
|
-
description: 'the root of the build-tools repo - for finding other config files'
|
|
36
|
-
}, {
|
|
37
|
-
name: 'help',
|
|
38
|
-
type: Boolean,
|
|
39
|
-
default: false,
|
|
40
|
-
description: 'display this help screen'
|
|
41
|
-
}, {
|
|
42
|
-
name: 'version',
|
|
43
|
-
type: Boolean,
|
|
44
|
-
default: false,
|
|
45
|
-
description: 'returns the build-tools repo version'
|
|
46
|
-
}, {
|
|
47
|
-
name: 'verbose',
|
|
48
|
-
alias: 'v',
|
|
49
|
-
type: Boolean,
|
|
50
|
-
default: false,
|
|
51
|
-
description: 'emit additional info at run time'
|
|
52
|
-
}];
|
|
53
|
-
const sections = [{
|
|
54
|
-
header: 'A collection of build / support tools for all Leverege code',
|
|
55
|
-
content: `README: {green https://bitbucket.org/leverege/build-tools/src/development}
|
|
56
|
-
`
|
|
57
|
-
}, {
|
|
58
|
-
header: 'Options',
|
|
59
|
-
optionList
|
|
60
|
-
}];
|
|
61
|
-
const args = cliArgs(optionList, {
|
|
62
|
-
partial: true
|
|
63
|
-
});
|
|
64
|
-
const help = cliHelp(sections);
|
|
65
|
-
const repoRoot = path.dirname(__dirname);
|
|
66
|
-
const thisPackage = require(`${repoRoot}/package.json`);
|
|
67
|
-
const thisVersion = thisPackage.version;
|
|
68
|
-
if (args.root) {
|
|
69
|
-
console.log(repoRoot);
|
|
70
|
-
process.exit(0);
|
|
71
|
-
}
|
|
72
|
-
if (args.bashfun) {
|
|
73
|
-
console.log(`${repoRoot}/src/bash-funcs`);
|
|
74
|
-
process.exit(0);
|
|
75
|
-
}
|
|
76
|
-
if (args.reporoot) {
|
|
77
|
-
console.log(`${repoRoot}`);
|
|
78
|
-
process.exit(0);
|
|
79
|
-
}
|
|
80
|
-
const checkForLatest = async (pkg = '@leverege/build-tools') => {
|
|
81
|
-
const getToken = () => {
|
|
82
|
-
const tokenFile = `${process.env.HOME}/.npmrc`;
|
|
83
|
-
if (!fs.existsSync(tokenFile)) {
|
|
84
|
-
console.error(`Cannot find token file ${tokenFile}`);
|
|
85
|
-
process.exit(1);
|
|
86
|
-
}
|
|
87
|
-
try {
|
|
88
|
-
const tokenLine = fs.readFileSync(tokenFile).toString();
|
|
89
|
-
const tokenRegX = new RegExp('.*registry.npmjs.org\\/:\\w+=+(.*)');
|
|
90
|
-
const tokenStr = tokenLine.match(tokenRegX);
|
|
91
|
-
if (!tokenStr) {
|
|
92
|
-
console.error(`\n***ERROR: malformed npm token in ${tokenFile}\n`);
|
|
93
|
-
process.exit(1);
|
|
94
|
-
}
|
|
95
|
-
return tokenLine.match(tokenRegX)[1];
|
|
96
|
-
} catch (err) {
|
|
97
|
-
console.error(err);
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
try {
|
|
101
|
-
const list = await npmRegistryFetch.json(pkg, {
|
|
102
|
-
'//registry.npmjs.org/:_authToken': getToken()
|
|
103
|
-
});
|
|
104
|
-
return list['dist-tags'].latest;
|
|
105
|
-
} catch (err) {
|
|
106
|
-
console.log(err);
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
const checkAndAnnounce = () => {
|
|
110
|
-
checkForLatest().then(latestVersion => {
|
|
111
|
-
if (semverLt(thisVersion, latestVersion)) {
|
|
112
|
-
console.log(chalk.white`
|
|
113
|
-
Update available ${chalk.grey(thisVersion)} \u2b62 ${chalk.green(latestVersion)}
|
|
114
|
-
Run ${chalk.cyan('npm i -g @leverege/build-tools')} to update
|
|
115
|
-
`);
|
|
116
|
-
process.exit(1);
|
|
117
|
-
} else {
|
|
118
|
-
process.exit(0);
|
|
119
|
-
}
|
|
120
|
-
}).catch(err => {});
|
|
121
|
-
};
|
|
122
|
-
if (args.latest) {
|
|
123
|
-
checkAndAnnounce();
|
|
124
|
-
}
|
|
125
|
-
if (args.version) {
|
|
126
|
-
console.log(`build-tools version ${thisVersion}`);
|
|
127
|
-
checkAndAnnounce();
|
|
128
|
-
}
|
|
129
|
-
if (args.help) {
|
|
130
|
-
console.log(help);
|
|
131
|
-
process.exit(0);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/* eslint-disable no-underscore-dangle */
|
|
135
|
-
if (args._unknown) {
|
|
136
|
-
console.log(`\nUnrecognized argument [${args._unknown}] try --help\n`);
|
|
137
|
-
process.exit(1);
|
|
138
|
-
}
|