@leverege/build-tools 2.93.5 → 2.93.7
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/package.json +3 -3
- package/src/Docker.mjs +9 -3
- package/src/Utils.mjs +1 -1
- package/src/artifacts/ArtifactPusher.mjs +34 -5
- package/src/artifacts/Utils.mjs +50 -7
- package/src/artifacts/pull-artifact.mjs +24 -13
- package/src/artifacts/push-artifact.mjs +23 -13
- package/src/helm-charts/prom-operator/helmup.plugin +2 -2
- package/.vscode/settings.json +0 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leverege/build-tools",
|
|
3
|
-
"version": "2.93.
|
|
3
|
+
"version": "2.93.7",
|
|
4
4
|
"description": "A collection of build / support tools for Leverege developers",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"glob": "^13.0.0",
|
|
83
83
|
"handlebars": "^4.7.8",
|
|
84
84
|
"ignore": "^7.0.5",
|
|
85
|
-
"inquirer": "^
|
|
85
|
+
"inquirer": "^13.1.0",
|
|
86
86
|
"js-yaml": "^4.1.1",
|
|
87
87
|
"jsdoc": "^4.0.5",
|
|
88
88
|
"ms": "^2.1.3",
|
|
@@ -105,4 +105,4 @@
|
|
|
105
105
|
"mocha": "^11.7.5",
|
|
106
106
|
"npm": "^11.7.0"
|
|
107
107
|
}
|
|
108
|
-
}
|
|
108
|
+
}
|
package/src/Docker.mjs
CHANGED
|
@@ -17,8 +17,14 @@ import {
|
|
|
17
17
|
|
|
18
18
|
const DIRNAME = path.dirname( url.fileURLToPath( import.meta.url ) )
|
|
19
19
|
|
|
20
|
-
// TODO:
|
|
21
|
-
|
|
20
|
+
// TODO: This is a temporary band-aid while we assess the impact of the yarn
|
|
21
|
+
// and/or CI pipeline transition. This will at least allow us to lock down the
|
|
22
|
+
// specific versions of node/npm and facilitate testing via the env vars.
|
|
23
|
+
//
|
|
24
|
+
// See the latest docker images here => https://hub.docker.com/_/node
|
|
25
|
+
//
|
|
26
|
+
const dockerfileNodeVersion = process.env.DOCKER_BUILD_NODE_VERSION || '24.12.0-alpine3.23'
|
|
27
|
+
const dockerfileNpmVersion = process.env.DOCKER_BUILD_NPM_VERSION || '11.6.0'
|
|
22
28
|
|
|
23
29
|
// The contents of these variables were initially located in files that live in
|
|
24
30
|
// the build-tools repository, but it just became simpler to pull the contents
|
|
@@ -55,7 +61,7 @@ const defaultSettings = {
|
|
|
55
61
|
nodeimage : 'jod-alpine',
|
|
56
62
|
imageBase : 'node:jod-alpine',
|
|
57
63
|
npmlogging : process.env.VERBOSE_NPM_LOGGING ? '--ddd' : '--silent',
|
|
58
|
-
npmVersion :
|
|
64
|
+
npmVersion : `npm@${dockerfileNpmVersion}`,
|
|
59
65
|
pluginfile : '# NO PLUGIN',
|
|
60
66
|
preInstallPluginfile : '# NO PRE-INSTALL PLUGIN',
|
|
61
67
|
regvers : 'package.version',
|
package/src/Utils.mjs
CHANGED
|
@@ -493,7 +493,7 @@ export const parseHelmChart = async ( helmroot = './helm' ) => {
|
|
|
493
493
|
|
|
494
494
|
// See if this is a leaf chart and whether or not dependencies need updating
|
|
495
495
|
const hasDependencies = chartYaml.dependencies !== undefined
|
|
496
|
-
let depsOutOfSync
|
|
496
|
+
let depsOutOfSync = hasDependencies // assume unsynced if dependencies
|
|
497
497
|
if ( chartFiles.includes( 'Chart.lock' ) ) {
|
|
498
498
|
const chartLock = YAML.load( fs.readFileSync( `${helmroot}/Chart.lock`, 'utf8' ) )
|
|
499
499
|
// Using Object.fromEntries will be able to handle multiple dependencies if ever needed
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
|
+
import fs from 'node:fs'
|
|
2
3
|
|
|
3
4
|
import { shellCmd, log, err, debug } from '../Utils.mjs'
|
|
4
5
|
|
|
5
6
|
import {
|
|
6
7
|
parseGenericArtifactFileToRemoteRelativePath,
|
|
7
8
|
parseGenericArtifactSchemaToRemoteRelativePath,
|
|
8
|
-
listGenericArtifactFiles
|
|
9
|
+
listGenericArtifactFiles,
|
|
10
|
+
shouldUseIgnoreConfiguration,
|
|
11
|
+
findIgnoreFilePath,
|
|
12
|
+
copyFilesWithIgnoreConfiguration
|
|
9
13
|
} from './Utils.mjs'
|
|
10
14
|
|
|
11
15
|
class ArtifactPusher {
|
|
@@ -29,8 +33,12 @@ class GenericArtifactPusher extends ArtifactPusher {
|
|
|
29
33
|
return false
|
|
30
34
|
}
|
|
31
35
|
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
if ( !this.artifact.local_path && !this.artifact.local_file_path ) {
|
|
37
|
+
err( 'Local path or local file path is required for pushing artifacts' )
|
|
38
|
+
return false
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
try {
|
|
34
42
|
let command = ''
|
|
35
43
|
|
|
36
44
|
command = `gcloud artifacts generic upload \
|
|
@@ -40,8 +48,25 @@ class GenericArtifactPusher extends ArtifactPusher {
|
|
|
40
48
|
--package=${this.artifact.package} \
|
|
41
49
|
--version=${this.artifact.version}`
|
|
42
50
|
|
|
51
|
+
let pathToDelete
|
|
52
|
+
|
|
43
53
|
if ( this.artifact.local_path ) {
|
|
44
|
-
const
|
|
54
|
+
const originalLocalPath = path.join( this.path, this.artifact.local_path )
|
|
55
|
+
|
|
56
|
+
let localPath = originalLocalPath
|
|
57
|
+
|
|
58
|
+
const useIgnoreConfiguration = await shouldUseIgnoreConfiguration()
|
|
59
|
+
|
|
60
|
+
if ( useIgnoreConfiguration ) {
|
|
61
|
+
const ignoreFilePath = await findIgnoreFilePath( this.path )
|
|
62
|
+
if ( ignoreFilePath ) {
|
|
63
|
+
const tmpLocalPath = path.join( '/', 'tmp', `${this.artifact.project}_${this.artifact.location}_${this.artifact.repository}_${this.artifact.package}_${this.artifact.version}` )
|
|
64
|
+
localPath = tmpLocalPath
|
|
65
|
+
pathToDelete = tmpLocalPath
|
|
66
|
+
await copyFilesWithIgnoreConfiguration( originalLocalPath, tmpLocalPath, ignoreFilePath )
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
45
70
|
command += ` --source-directory=${localPath}`
|
|
46
71
|
command += ' --skip-existing'
|
|
47
72
|
} else if ( this.artifact.local_file_path ) {
|
|
@@ -66,7 +91,11 @@ class GenericArtifactPusher extends ArtifactPusher {
|
|
|
66
91
|
debug( { command }, '<==Upload Command' )
|
|
67
92
|
|
|
68
93
|
await shellCmd( command )
|
|
69
|
-
|
|
94
|
+
|
|
95
|
+
if ( pathToDelete ) {
|
|
96
|
+
await fs.promises.rm( pathToDelete, { recursive : true } )
|
|
97
|
+
}
|
|
98
|
+
|
|
70
99
|
log( `Successfully pushed artifact: ${this.artifact.name}` )
|
|
71
100
|
|
|
72
101
|
return true
|
package/src/artifacts/Utils.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import { parseYamlFile, err, warning, debug, shellCmd } from '../Utils.mjs'
|
|
|
8
8
|
|
|
9
9
|
import { ArtifactTypeEnum, ArtifactsSchema, GenericArtifactSchema } from './Structs.mjs'
|
|
10
10
|
|
|
11
|
-
const getArtifactsSchema = async ( artifactsFilePath = './artifacts.
|
|
11
|
+
const getArtifactsSchema = async ( artifactsFilePath = './artifacts.yaml' ) => {
|
|
12
12
|
const artifactsConfig = await parseYamlFile( artifactsFilePath )
|
|
13
13
|
const [ error, result ] = validate( artifactsConfig, ArtifactsSchema )
|
|
14
14
|
if ( error ) {
|
|
@@ -163,7 +163,6 @@ const calculateHash = async ( path ) => {
|
|
|
163
163
|
hash.update( await fs.promises.readFile( path ) )
|
|
164
164
|
return `${hash.digest( 'base64url' )}=`
|
|
165
165
|
} catch ( error ) {
|
|
166
|
-
console.error( error )
|
|
167
166
|
throw new Error( `Failed to calculate hash for artifact ${path}: ${error.message}` )
|
|
168
167
|
}
|
|
169
168
|
}
|
|
@@ -186,7 +185,7 @@ const listGenericArtifactFiles = async ( artifact ) => {
|
|
|
186
185
|
return files
|
|
187
186
|
}
|
|
188
187
|
|
|
189
|
-
const
|
|
188
|
+
const getMissingRemoteFiles = async ( genericArtifactFiles, genericArtifactSchemaPath, genericArtifactSchema ) => {
|
|
190
189
|
|
|
191
190
|
const expectedRemoteRelativePath = parseGenericArtifactSchemaToRemoteRelativePath( genericArtifactSchema )
|
|
192
191
|
const localRelativePath = parseGenericArtifactSchemaToLocalRelativePath( genericArtifactSchema )
|
|
@@ -221,8 +220,47 @@ const checkGenericArtifactMatch = async ( genericArtifactFiles, genericArtifactS
|
|
|
221
220
|
const actualArray = Array.from( actualFiles )
|
|
222
221
|
const expectedArray = Array.from( expectedFiles )
|
|
223
222
|
|
|
224
|
-
return actualArray.
|
|
225
|
-
|
|
223
|
+
return expectedArray.filter( expected => !actualArray.some( actual => actual.remoteFilePath === expected.remoteFilePath && actual.remoteFileHash === expected.remoteFileHash ) )
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const shouldUseIgnoreConfiguration = async () => {
|
|
227
|
+
let result
|
|
228
|
+
try {
|
|
229
|
+
result = await shellCmd( 'gcloud config get-value gcloudignore/enabled' )
|
|
230
|
+
if ( result.trim() === '' || result.includes( 'has no property' ) ) {
|
|
231
|
+
return false
|
|
232
|
+
}
|
|
233
|
+
return result.trim() === 'true'
|
|
234
|
+
} catch ( error ) {
|
|
235
|
+
if ( error.message && error.message.includes( 'Section [gcloudignore] has no property [enabled]' ) ) {
|
|
236
|
+
return false
|
|
237
|
+
}
|
|
238
|
+
// Re-throw other errors
|
|
239
|
+
throw error
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const findIgnoreFilePath = async ( relativePath ) => {
|
|
244
|
+
if ( relativePath ) {
|
|
245
|
+
const ignoreFilePath = path.join( relativePath, '.gcloudignore' )
|
|
246
|
+
if ( fs.existsSync( ignoreFilePath ) ) {
|
|
247
|
+
return ignoreFilePath
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const ignoreFilePath = path.join( process.cwd(), '.gcloudignore' )
|
|
252
|
+
if ( fs.existsSync( ignoreFilePath ) ) {
|
|
253
|
+
return ignoreFilePath
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return null
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const copyFilesWithIgnoreConfiguration = async ( sourcePath, destinationPath, ignoreFilePath ) => {
|
|
260
|
+
// Ensure sourcePath ends with / so rsync copies contents (not the folder itself) and exclude patterns work correctly
|
|
261
|
+
const normalizedSourcePath = sourcePath.endsWith( '/' ) ? sourcePath : `${sourcePath}/`
|
|
262
|
+
const command = `rsync -av --delete --exclude-from='${ignoreFilePath}' ${normalizedSourcePath} ${destinationPath}`
|
|
263
|
+
await shellCmd( command )
|
|
226
264
|
}
|
|
227
265
|
|
|
228
266
|
export {
|
|
@@ -232,7 +270,12 @@ export {
|
|
|
232
270
|
parseGenericArtifactFileToRemoteRelativePath,
|
|
233
271
|
parseGenericArtifactSchemaToRemoteRelativePath,
|
|
234
272
|
parseGenericArtifactSchemaToLocalRelativePath,
|
|
273
|
+
parseGenericArtifactSchemaToArtifactNameBase,
|
|
274
|
+
parseGenericArtifactSchemaToArtifactNameFile,
|
|
235
275
|
parseGenericArtifactSchemaToArtifactName,
|
|
236
|
-
|
|
237
|
-
listGenericArtifactFiles
|
|
276
|
+
getMissingRemoteFiles,
|
|
277
|
+
listGenericArtifactFiles,
|
|
278
|
+
shouldUseIgnoreConfiguration,
|
|
279
|
+
findIgnoreFilePath,
|
|
280
|
+
copyFilesWithIgnoreConfiguration
|
|
238
281
|
}
|
|
@@ -13,12 +13,8 @@ import { GenericArtifactPuller } from './ArtifactPuller.mjs'
|
|
|
13
13
|
program
|
|
14
14
|
.name( 'pull-artifact' )
|
|
15
15
|
.description( 'Pull artifacts from GCP Artifact Registry' )
|
|
16
|
-
.
|
|
17
|
-
.
|
|
18
|
-
.requiredOption( '-l, --location <location>', 'GCP location' )
|
|
19
|
-
.requiredOption( '-r, --repository <repository>', 'GCP artifact registry repository' )
|
|
20
|
-
.requiredOption( '-n --package <name>', 'GCP artifact registry package name' )
|
|
21
|
-
.requiredOption( '-v, --version <version>', 'GCP artifact registry package version' )
|
|
16
|
+
.option( '-f, --file-path <file-path>', 'Path to artifacts.yaml file', './artifacts.yaml' )
|
|
17
|
+
.option( '-a, --artifact-path <artifact-path>', 'GCP artifact path' )
|
|
22
18
|
.parse()
|
|
23
19
|
|
|
24
20
|
const options = program.opts()
|
|
@@ -26,13 +22,26 @@ const options = program.opts()
|
|
|
26
22
|
async function main() {
|
|
27
23
|
const artifactsSchema = await getArtifactsSchema( options.filePath )
|
|
28
24
|
const flattenedArtifactsSchema = flattenArtifactsSchema( artifactsSchema )
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
|
|
26
|
+
let filteredArtifactsSchema = flattenedArtifactsSchema
|
|
27
|
+
|
|
28
|
+
if ( options.artifactPath ) {
|
|
29
|
+
const artifactPathElements = options.artifactPath.split( '/' )
|
|
30
|
+
|
|
31
|
+
if ( artifactPathElements.length !== 5 ) {
|
|
32
|
+
warning( 'Invalid artifact path, it must be in the format <project>/<location>/<repository>/<package>/<version>' )
|
|
33
|
+
return false
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const [ project, location, repository, packageName, version ] = artifactPathElements
|
|
37
|
+
|
|
38
|
+
filteredArtifactsSchema = flattenedArtifactsSchema.filter(
|
|
39
|
+
artifact => artifact.project === project &&
|
|
40
|
+
artifact.location === location &&
|
|
41
|
+
artifact.repository === repository &&
|
|
42
|
+
artifact.package === packageName &&
|
|
43
|
+
artifact.version === version )
|
|
44
|
+
}
|
|
36
45
|
|
|
37
46
|
let counter = 0
|
|
38
47
|
|
|
@@ -65,6 +74,8 @@ async function main() {
|
|
|
65
74
|
counter = pullResults.filter( Boolean ).length
|
|
66
75
|
|
|
67
76
|
log( `Successfully pulled ${counter}/${filteredArtifactsSchema.length} artifacts` )
|
|
77
|
+
|
|
78
|
+
return counter === filteredArtifactsSchema.length
|
|
68
79
|
}
|
|
69
80
|
|
|
70
81
|
main()
|
|
@@ -13,12 +13,8 @@ import { GenericArtifactPusher } from './ArtifactPusher.mjs'
|
|
|
13
13
|
program
|
|
14
14
|
.name( 'push-artifact' )
|
|
15
15
|
.description( 'Push artifacts to GCP Artifact Registry' )
|
|
16
|
-
.
|
|
17
|
-
.
|
|
18
|
-
.requiredOption( '-l, --location <location>', 'GCP location' )
|
|
19
|
-
.requiredOption( '-r, --repository <repository>', 'GCP artifact registry repository' )
|
|
20
|
-
.requiredOption( '-n --package <name>', 'GCP artifact registry package name' )
|
|
21
|
-
.requiredOption( '-v, --version <version>', 'GCP artifact registry package version' )
|
|
16
|
+
.option( '-f, --file-path <file-path>', 'Path to artifacts.yaml file', './artifacts.yaml' )
|
|
17
|
+
.option( '-a, --artifact-path <artifact-path>', 'GCP artifact path' )
|
|
22
18
|
.parse()
|
|
23
19
|
|
|
24
20
|
const options = program.opts()
|
|
@@ -26,13 +22,25 @@ const options = program.opts()
|
|
|
26
22
|
async function main() {
|
|
27
23
|
const artifactsSchema = await getArtifactsSchema( options.filePath )
|
|
28
24
|
const flattenedArtifactsSchema = flattenArtifactsSchema( artifactsSchema )
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
|
|
26
|
+
let filteredArtifactsSchema = flattenedArtifactsSchema
|
|
27
|
+
|
|
28
|
+
if ( options.artifactPath ) {
|
|
29
|
+
const artifactPathElements = options.artifactPath.split( '/' )
|
|
30
|
+
if ( artifactPathElements.length !== 5 ) {
|
|
31
|
+
warning( 'Invalid artifact path, it must be in the format <project>/<location>/<repository>/<package>/<version>' )
|
|
32
|
+
return false
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const [ project, location, repository, packageName, version ] = artifactPathElements
|
|
36
|
+
|
|
37
|
+
filteredArtifactsSchema = flattenedArtifactsSchema.filter(
|
|
38
|
+
artifact => artifact.project === project &&
|
|
39
|
+
artifact.location === location &&
|
|
40
|
+
artifact.repository === repository &&
|
|
41
|
+
artifact.package === packageName &&
|
|
42
|
+
artifact.version === version )
|
|
43
|
+
}
|
|
36
44
|
|
|
37
45
|
let counter = 0
|
|
38
46
|
|
|
@@ -65,6 +73,8 @@ async function main() {
|
|
|
65
73
|
counter = pushResults.filter( Boolean ).length
|
|
66
74
|
|
|
67
75
|
log( `Successfully pushed ${counter}/${filteredArtifactsSchema.length} artifacts` )
|
|
76
|
+
|
|
77
|
+
return counter === filteredArtifactsSchema.length
|
|
68
78
|
}
|
|
69
79
|
|
|
70
80
|
main()
|
|
@@ -8,14 +8,14 @@ showInstalling "The Prometheus Operator (kube-prometheus-stack)"
|
|
|
8
8
|
|
|
9
9
|
# https://artifacthub.io/packages/helm/prometheus-community/kube-prometheus-stack
|
|
10
10
|
OCI_CHART="oci://ghcr.io/prometheus-community/charts/kube-prometheus-stack"
|
|
11
|
-
[ -z "$PROMETHEUS_STACK_CHART_VERSION" ] && PROMETHEUS_STACK_CHART_VERSION="80.
|
|
11
|
+
[ -z "$PROMETHEUS_STACK_CHART_VERSION" ] && PROMETHEUS_STACK_CHART_VERSION="80.4.1"
|
|
12
12
|
helm upgrade $NS --install prometheus-stack $OCI_CHART \
|
|
13
13
|
--values prom-operator/prometheus-stack.yaml \
|
|
14
14
|
--version $PROMETHEUS_STACK_CHART_VERSION $HELM_WHAT
|
|
15
15
|
|
|
16
16
|
# https://artifacthub.io/packages/helm/prometheus-community/prometheus-elasticsearch-exporter
|
|
17
17
|
showInstalling "The Elasticsearch Exporter (prom-operator ES metrics exports)"
|
|
18
|
-
[ -z "$ELASTICSEARCH_EXPORTER_CHART_VERSION" ] && ELASTICSEARCH_EXPORTER_CHART_VERSION="7.2.
|
|
18
|
+
[ -z "$ELASTICSEARCH_EXPORTER_CHART_VERSION" ] && ELASTICSEARCH_EXPORTER_CHART_VERSION="7.2.1"
|
|
19
19
|
OCI_CHART="oci://ghcr.io/prometheus-community/charts/prometheus-elasticsearch-exporter"
|
|
20
20
|
helm upgrade $NS --install elasticsearch8-exporter $OCI_CHART \
|
|
21
21
|
--values prom-operator/elasticsearch-exporter.yaml \
|
package/.vscode/settings.json
DELETED