@leverege/build-tools 2.67.3-beta.9 → 2.68.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/package.json +6 -6
- package/src/Docker.mjs +22 -14
- package/src/DockerPy.mjs +7 -5
- package/src/Utils.mjs +43 -14
- package/src/docker-to-registry-py.mjs +6 -6
- package/src/docker-to-registry.mjs +40 -18
- package/src/helm-charts/cnpg-db-psql-stack/cluster.yaml.ovh +1 -1
- package/src/helm-charts/cnpg-db-tsdb-basic/cluster.yaml.ovh +1 -1
- package/src/helm-charts/cnpg-db-tsdb-dense/cluster.yaml.ovh +1 -1
- package/src/helm-charts/scheduler/values-local.yaml +3 -0
- package/src/helm-charts/transponder-bq/values-local.yaml +1 -1
- package/src/helm-charts/transponder-dh/values-local.yaml +1 -1
- package/src/helm-charts/transponder-rt/values-local.yaml +1 -1
- package/src/helm-charts/transponder-tsdb/values-local.yaml +1 -1
- package/src/k8x.sh +4 -0
- package/src/templates/{cloudBuildSteps.hbs → cloudBuildTargetGKE.hbs} +1 -4
- package/src/templates/{dockerfileTemplate.hbs → dockerfileTemplateNodeJs.hbs} +1 -0
- package/src/templates/dockerfileTemplatePy.hbs +5 -0
- package/src/templates/dockerfileTemplatePython.hbs +65 -0
- package/.vscode/settings.json +0 -3
- package/src/build-and-push.sh +0 -78
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leverege/build-tools",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.68.0",
|
|
4
4
|
"description": "A collection of build / support tools for Leverege developers",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -70,10 +70,10 @@
|
|
|
70
70
|
"deepmerge": "^4.3.1",
|
|
71
71
|
"enquirer": "^2.4.1",
|
|
72
72
|
"execa": "^9.6.0",
|
|
73
|
-
"glob": "^11.0.
|
|
73
|
+
"glob": "^11.0.3",
|
|
74
74
|
"handlebars": "^4.7.8",
|
|
75
75
|
"ignore": "^7.0.5",
|
|
76
|
-
"inquirer": "^12.
|
|
76
|
+
"inquirer": "^12.7.0",
|
|
77
77
|
"js-yaml": "^4.1.0",
|
|
78
78
|
"jsdoc": "^4.0.4",
|
|
79
79
|
"ms": "^2.1.3",
|
|
@@ -86,10 +86,10 @@
|
|
|
86
86
|
"shell-quote": "^1.8.3",
|
|
87
87
|
"simple-git": "^3.28.0",
|
|
88
88
|
"toml": "^3.0.0",
|
|
89
|
-
"zx": "^8.
|
|
89
|
+
"zx": "^8.6.1"
|
|
90
90
|
},
|
|
91
91
|
"devDependencies": {
|
|
92
92
|
"@leverege/eslint-config-leverege": "^5.0.1",
|
|
93
|
-
"npm": "^11.4.
|
|
93
|
+
"npm": "^11.4.2"
|
|
94
94
|
}
|
|
95
|
-
}
|
|
95
|
+
}
|
package/src/Docker.mjs
CHANGED
|
@@ -40,16 +40,14 @@ const dockerfilePluginTemplate = `
|
|
|
40
40
|
# a best practice.
|
|
41
41
|
`
|
|
42
42
|
const bashrcPluginTemplate = `
|
|
43
|
-
|
|
44
43
|
# Bashrc.plugin - optionally extend the image .bashrc file
|
|
45
44
|
#
|
|
46
45
|
# This plugin file may contain additional .bashrc settigns / functions to
|
|
47
46
|
# provide on the target image.
|
|
48
|
-
|
|
47
|
+
#
|
|
49
48
|
`
|
|
50
|
-
const dockerfileTemplate = fs.readFileSync( path.join( DIRNAME, './templates/dockerfileTemplate.hbs' ), 'utf8' )
|
|
51
49
|
const bashrcTemplate = fs.readFileSync( path.join( DIRNAME, './templates/bashrcTemplate.hbs' ), 'utf8' )
|
|
52
|
-
const cloudBuildSteps = fs.readFileSync( path.join( DIRNAME, './templates/
|
|
50
|
+
const cloudBuildSteps = fs.readFileSync( path.join( DIRNAME, './templates/cloudBuildTargetGKE.hbs' ), 'utf8' )
|
|
53
51
|
|
|
54
52
|
const defaultSettings = {
|
|
55
53
|
apkadds : '',
|
|
@@ -78,7 +76,9 @@ const generateDockerfile = async ( options ) => {
|
|
|
78
76
|
|
|
79
77
|
const gitReference = await shellCmd( 'git rev-parse --short HEAD' )
|
|
80
78
|
const settings = { gitReference, ...defaultSettings, ...options }
|
|
81
|
-
|
|
79
|
+
const dockerTemplate = options.isNodeJsProject ? 'dockerfileTemplateNodeJs' : 'dockerfileTemplatePython'
|
|
80
|
+
const dockerfileTemplate = fs.readFileSync( path.join( DIRNAME, `./templates/${dockerTemplate}.hbs` ), 'utf8' ) // eslint-disable-line security/detect-non-literal-fs-filename
|
|
81
|
+
|
|
82
82
|
// defaults to the current "official" version of node unless it gets
|
|
83
83
|
// overridden in the leverege.nodeimg package.json stanza
|
|
84
84
|
if ( !settings.nodeimage ) {
|
|
@@ -173,10 +173,16 @@ const validateCloudBuildBucket = async ( artifactProject ) => {
|
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
-
const buildContainerImage = async ( {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
176
|
+
const buildContainerImage = async ( repoDescr ) => {
|
|
177
|
+
const {
|
|
178
|
+
artifactProject,
|
|
179
|
+
artifactRegistry,
|
|
180
|
+
containerName,
|
|
181
|
+
imageVersion,
|
|
182
|
+
isNodeJsProject,
|
|
183
|
+
isNpmWorkspace,
|
|
184
|
+
// isPythonProject,
|
|
185
|
+
} = repoDescr
|
|
180
186
|
const buildWorkspace = './build/workspace' // passed to Cloud Build
|
|
181
187
|
const imageName = `${artifactRegistry}/images/${containerName}`
|
|
182
188
|
|
|
@@ -192,7 +198,7 @@ const buildContainerImage = async ( {
|
|
|
192
198
|
// Steps taken here attempt to minimize impact on legacy build setups
|
|
193
199
|
// 1. rename build dir to workspace
|
|
194
200
|
// 2. create the actual build dir and move workspace into it
|
|
195
|
-
// 3.
|
|
201
|
+
// 3. copy the Dockerfile into build and make a copy for image root
|
|
196
202
|
// 4. copy the bashrc file into build and .bashrc on the image root
|
|
197
203
|
// 5. drop a copy of dev's npmrc to use for build process
|
|
198
204
|
// 6. drop a copy of package.json and the lock into the image root
|
|
@@ -200,12 +206,14 @@ const buildContainerImage = async ( {
|
|
|
200
206
|
fs.renameSync( './build', './workspace' )
|
|
201
207
|
fs.mkdirSync( './build' )
|
|
202
208
|
fs.renameSync( './workspace', buildWorkspace )
|
|
203
|
-
fs.
|
|
209
|
+
fs.cpSync( './docker/Dockerfile', './build/Dockerfile' )
|
|
204
210
|
fs.cpSync( './build/Dockerfile', `${buildWorkspace}/Dockerfile` )
|
|
205
211
|
fs.renameSync( './docker/bashrc', './build/bashrc' )
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
212
|
+
if ( isNodeJsProject ) {
|
|
213
|
+
fs.cpSync( `${process.env.HOME}/.npmrc`, './build/.npmrc' )
|
|
214
|
+
fs.cpSync( './package.json', `${buildWorkspace}/package.json` )
|
|
215
|
+
fs.cpSync( './package-lock.json', `${buildWorkspace}/package-lock.json` )
|
|
216
|
+
}
|
|
209
217
|
if ( isNpmWorkspace ) {
|
|
210
218
|
fs.rm( './package-lock.json', ( err ) => {} ) // no leaf node locks in workspaces
|
|
211
219
|
}
|
package/src/DockerPy.mjs
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DEPRECATED - DO NOT MODIFY
|
|
3
|
+
*/
|
|
1
4
|
import fs from 'node:fs'
|
|
2
5
|
import path from 'node:path'
|
|
3
6
|
import url from 'node:url'
|
|
@@ -37,7 +40,7 @@ const pluginTemplate = `
|
|
|
37
40
|
# a best practice.
|
|
38
41
|
`
|
|
39
42
|
const dockerfileTemplate = fs.readFileSync( path.join( DIRNAME, './templates/dockerfileTemplatePy.hbs' ), 'utf8' )
|
|
40
|
-
const cloudBuildSteps = fs.readFileSync( path.join( DIRNAME, './templates/
|
|
43
|
+
const cloudBuildSteps = fs.readFileSync( path.join( DIRNAME, './templates/cloudBuildTargetGKE.hbs' ), 'utf8' )
|
|
41
44
|
let bashrcTemplate = fs.readFileSync( path.join( DIRNAME, './templates/bashrcTemplate.hbs' ), 'utf8' )
|
|
42
45
|
const bashrcPyTemplate = fs.readFileSync( path.join( DIRNAME, './templates/bashrcTemplatePy.hbs' ), 'utf8' )
|
|
43
46
|
bashrcTemplate = `${bashrcTemplate}\n${bashrcPyTemplate}`
|
|
@@ -79,7 +82,6 @@ const extractBaseImageTag = ( imageStr ) => {
|
|
|
79
82
|
function generateDockerfile( options ) {
|
|
80
83
|
|
|
81
84
|
const settings = { ...defaultSettings, ...options }
|
|
82
|
-
|
|
83
85
|
settings.image = settings.imageBase
|
|
84
86
|
// TODO: this is a janky way to pass the image tag back out
|
|
85
87
|
defaultSettings.buildTag = extractBaseImageTag( settings.image )
|
|
@@ -161,8 +163,8 @@ async function validateCloudBuildBucket( artifactProject ) {
|
|
|
161
163
|
}
|
|
162
164
|
|
|
163
165
|
async function buildContainerImage( {
|
|
164
|
-
artifactProject, artifactRegistry, containerName,
|
|
165
|
-
imageVersion,
|
|
166
|
+
artifactProject, artifactRegistry, containerName,
|
|
167
|
+
imageVersion, isNpmWorkspace, options
|
|
166
168
|
} ) {
|
|
167
169
|
const buildWorkspace = './build/workspace' // passed to Cloud Build
|
|
168
170
|
const imageName = `${artifactRegistry}/images/${containerName}`
|
|
@@ -195,7 +197,7 @@ async function buildContainerImage( {
|
|
|
195
197
|
// build the cloudbuild.yaml from the handlebars template
|
|
196
198
|
const cloudBuildFile = './build/cloudbuild.yaml'
|
|
197
199
|
const cbst = handlebars.compile( cloudBuildSteps, { noEscape : true } )
|
|
198
|
-
const cbs = cbst( { artifactProject, artifactRegistry, imageName, imageVersion, imageInfoTag,
|
|
200
|
+
const cbs = cbst( { artifactProject, artifactRegistry, imageName, imageVersion, imageInfoTag, } )
|
|
199
201
|
fs.writeFileSync( cloudBuildFile, cbs )
|
|
200
202
|
|
|
201
203
|
// build up the cloud build command and options
|
package/src/Utils.mjs
CHANGED
|
@@ -415,7 +415,26 @@ export const parsePyProjectToml = async ( packageFileName = './pyproject.toml' )
|
|
|
415
415
|
if ( !fs.existsSync( packageFileName ) ) { return undefined } // eslint-disable-line security/detect-non-literal-fs-filename
|
|
416
416
|
const tomlStr = fs.readFileSync( packageFileName ) // eslint-disable-line security/detect-non-literal-fs-filename
|
|
417
417
|
const pyproject = toml.parse( tomlStr )
|
|
418
|
-
|
|
418
|
+
|
|
419
|
+
const registry = pyproject?.leverege?.registry
|
|
420
|
+
if ( !registry ) {
|
|
421
|
+
errorExit( 'Error: pyproject.toml is missing a proper [leverege] registry statement' )
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
const registryComponents = registry.split( '/' )
|
|
425
|
+
if ( registryComponents.length !== 3 ) {
|
|
426
|
+
errorExit( 'Error: pyproject.toml has a malformed [leverege] registry statement' )
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
const [ region, project, repository ] = registryComponents
|
|
430
|
+
const artifactRegistry = { region, project, repository }
|
|
431
|
+
|
|
432
|
+
if ( !fs.existsSync( '.python-version' ) ) {
|
|
433
|
+
errorExit( 'Error: missing the .python-version file - it is required' )
|
|
434
|
+
}
|
|
435
|
+
const pythonVersion = fs.readFileSync( '.python-version' )
|
|
436
|
+
|
|
437
|
+
return { artifactRegistry, pythonVersion, ...pyproject }
|
|
419
438
|
}
|
|
420
439
|
|
|
421
440
|
export const parseHelmChart = async ( helmroot = './helm' ) => {
|
|
@@ -451,30 +470,27 @@ export const parseHelmChart = async ( helmroot = './helm' ) => {
|
|
|
451
470
|
}
|
|
452
471
|
|
|
453
472
|
export const getRepositoryDescr = async () => {
|
|
454
|
-
const currentDir = process.cwd()
|
|
455
|
-
const workingDir = process.env.PWD
|
|
456
473
|
const gitRoot = await getGitRootDirectory()
|
|
457
|
-
const isGitRepo = gitRoot !== undefined
|
|
458
474
|
const gitHooksPath = await getGitHooksPath()
|
|
459
475
|
const { branch : gitBranch, upstream : gitUpstream } = await getGitBranchAndUpstream()
|
|
460
476
|
const subPkgs = await glob( `${gitRoot}/packages/**/package.json`, { ignore : '/**/node_modules/**' } )
|
|
461
477
|
const helmChart = await parseHelmChart()
|
|
462
|
-
const isMonoRepo = subPkgs?.length > 0
|
|
463
478
|
const rootPackageJson = await parseJsonFile( `${gitRoot}/package.json` )
|
|
464
479
|
const rootPyProjectToml = await parsePyProjectToml( `${gitRoot}/pyproject.toml` )
|
|
465
|
-
const isNpmWorkspace = rootPackageJson?.workspaces?.length > 0
|
|
466
480
|
|
|
467
481
|
return {
|
|
468
|
-
currentDir,
|
|
469
|
-
workingDir,
|
|
482
|
+
currentDir : process.cwd(),
|
|
483
|
+
workingDir : process.env.PWD,
|
|
470
484
|
gitBranch,
|
|
471
485
|
gitHooksPath,
|
|
472
486
|
gitRoot,
|
|
473
487
|
gitUpstream,
|
|
474
488
|
helmChart,
|
|
475
|
-
isGitRepo,
|
|
476
|
-
isMonoRepo,
|
|
477
|
-
|
|
489
|
+
isGitRepo : gitRoot !== undefined,
|
|
490
|
+
isMonoRepo : subPkgs?.length > 0,
|
|
491
|
+
isNodeJsProject : rootPackageJson !== undefined,
|
|
492
|
+
isNpmWorkspace : rootPackageJson?.workspaces?.length > 0,
|
|
493
|
+
isPythonProject : rootPyProjectToml !== undefined,
|
|
478
494
|
rootPackageJson,
|
|
479
495
|
rootPyProjectToml,
|
|
480
496
|
subPkgs,
|
|
@@ -487,6 +503,8 @@ export const analyzeRepository = async ( giveGuidance ) => {
|
|
|
487
503
|
subPkgs,
|
|
488
504
|
helmChart,
|
|
489
505
|
isMonoRepo,
|
|
506
|
+
isNodeJsProject,
|
|
507
|
+
isPythonProject,
|
|
490
508
|
rootPackageJson,
|
|
491
509
|
rootPyProjectToml,
|
|
492
510
|
isNpmWorkspace,
|
|
@@ -532,11 +550,20 @@ export const analyzeRepository = async ( giveGuidance ) => {
|
|
|
532
550
|
await shellCmd( 'npm run build' )
|
|
533
551
|
}
|
|
534
552
|
|
|
535
|
-
|
|
553
|
+
let buildToolsVersion
|
|
554
|
+
if ( isNodeJsProject ) {
|
|
555
|
+
buildToolsVersion = closestPackageJson?.devDependencies['@leverege/build-tools']
|
|
556
|
+
}
|
|
536
557
|
|
|
558
|
+
// if the build tools version is still undefined then assume we are using a globally installed bt
|
|
559
|
+
if ( buildToolsVersion === undefined ) {
|
|
560
|
+
const fromBuildTools = await shellCmd( 'build-tools --version' )
|
|
561
|
+
buildToolsVersion = fromBuildTools.match( /\d+\.\d+\.\d+$/ )[0]
|
|
562
|
+
}
|
|
563
|
+
|
|
537
564
|
const containerName = closestPackageJson?.name.replace( /^@[^/]+\//, '' ) || rootPyProjectToml?.project.name
|
|
538
|
-
const
|
|
539
|
-
const
|
|
565
|
+
const artifactRegistry = closestPackageJson?.leverege.registry || rootPyProjectToml?.leverege.registry
|
|
566
|
+
const artifactProject = closestPackageJson?.artifactRegistry.project || rootPyProjectToml?.artifactRegistry.project || 'unknown'
|
|
540
567
|
const packageVersion = `v${closestPackageJson?.version || rootPyProjectToml?.project.version}`
|
|
541
568
|
|
|
542
569
|
const currentDir = process.cwd()
|
|
@@ -568,6 +595,8 @@ export const analyzeRepository = async ( giveGuidance ) => {
|
|
|
568
595
|
helmChart,
|
|
569
596
|
isMonoRepo,
|
|
570
597
|
isNpmWorkspace,
|
|
598
|
+
isNodeJsProject,
|
|
599
|
+
isPythonProject,
|
|
571
600
|
rootPackageJson,
|
|
572
601
|
rootPyProjectToml,
|
|
573
602
|
closestPackageJson,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
*
|
|
2
|
+
/**
|
|
3
|
+
* DEPRECATED - DO NOT MODIFY
|
|
4
4
|
*/
|
|
5
5
|
import fs from 'node:fs'
|
|
6
6
|
import toml from 'toml'
|
|
7
7
|
import chalk from 'chalk'
|
|
8
8
|
|
|
9
9
|
import {
|
|
10
|
-
debug, log,
|
|
10
|
+
debug, log, warning,
|
|
11
11
|
errorExit,
|
|
12
12
|
getGitBranchAndUpstream,
|
|
13
13
|
gitRepoIsDirty,
|
|
@@ -23,6 +23,8 @@ import Docker from './DockerPy.mjs'
|
|
|
23
23
|
// log( refreshErr ) // most likely the token refreshed message
|
|
24
24
|
// }
|
|
25
25
|
|
|
26
|
+
warning( 'docker-to-registry-py has been DEPRECATED - use docker-to-registry' )
|
|
27
|
+
|
|
26
28
|
const options = {}
|
|
27
29
|
let imageVersion = null
|
|
28
30
|
// Expected to be invoked like docker-to-registry-py v1.2.3
|
|
@@ -91,9 +93,8 @@ const repoDescr = {
|
|
|
91
93
|
containerName : pyproject.project.name,
|
|
92
94
|
packageVersion : `v${pyproject.project.version}`,
|
|
93
95
|
artifactRegistry : pyproject.leverege.registry || 'us-docker.pkg.dev/leverege-registry/stack',
|
|
94
|
-
|
|
96
|
+
registryFolder : `${pyproject.leverege['registry-folder']}/images/${pyproject.project.name}`,
|
|
95
97
|
imageBase : pyproject.leverege['image-base'],
|
|
96
|
-
imagePlatform : pyproject.leverege['image-platform'] || 'linux/amd64',
|
|
97
98
|
helmChart : await parseHelmChart(),
|
|
98
99
|
}
|
|
99
100
|
|
|
@@ -215,7 +216,6 @@ log( `
|
|
|
215
216
|
${chalk.green.bold( 'Build Information:' )}
|
|
216
217
|
Container: ${chalk.green.bold( containerName )}
|
|
217
218
|
Version: ${chalk.green.bold( imageVersion )} ${tagInfo}
|
|
218
|
-
Platform: ${chalk.green.bold( repoDescr.imagePlatform )}
|
|
219
219
|
Registry: ${chalk.green.bold( artifactRegistry )}
|
|
220
220
|
Image Folder: ${chalk.yellow.bold( registryFolder )}
|
|
221
221
|
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
|
|
19
19
|
import docker from './Docker.mjs'
|
|
20
20
|
|
|
21
|
-
const minimumBuildToolsVersion = '2.
|
|
21
|
+
const minimumBuildToolsVersion = '2.68.0'
|
|
22
22
|
|
|
23
23
|
// refresh-npm-token does not throw so no need to try, but it emits in debug
|
|
24
24
|
const refreshErr = await shellCmd( 'refresh-npm-token' )
|
|
@@ -94,14 +94,6 @@ if ( semver.lt( semver.coerce( repoDescr.buildToolsVersion ), minimumBuildToolsV
|
|
|
94
94
|
errorExit( `Error: package.json @leverege/build-tools minimum version is ^${minimumBuildToolsVersion}` )
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
const dockerInfo = await docker.generateDockerfile( {
|
|
98
|
-
regvers : repoDescr.packageVersion,
|
|
99
|
-
imageBase : repoDescr.closestPackageJson.leverege?.imageBase,
|
|
100
|
-
buildEnv : repoDescr.closestPackageJson.leverege?.buildEnv || 'alpine',
|
|
101
|
-
nodeimage : repoDescr.closestPackageJson.leverege?.nodeimg, // left as nodeimg in package.json for backwards compat
|
|
102
|
-
} )
|
|
103
|
-
debug( { dockerInfo }, '<==The Docker Info' )
|
|
104
|
-
|
|
105
97
|
const {
|
|
106
98
|
artifactProject,
|
|
107
99
|
artifactRegistry,
|
|
@@ -109,17 +101,35 @@ const {
|
|
|
109
101
|
containerName,
|
|
110
102
|
helmChart,
|
|
111
103
|
isNpmWorkspace,
|
|
104
|
+
isNodeJsProject,
|
|
105
|
+
isPythonProject,
|
|
112
106
|
} = repoDescr
|
|
113
107
|
|
|
108
|
+
const leveregeStanza = isNodeJsProject ? repoDescr.closestPackageJson.leverege : repoDescr.rootPyProjectToml.leverege
|
|
109
|
+
|
|
110
|
+
const dockerInfo = await docker.generateDockerfile( {
|
|
111
|
+
isNodeJsProject,
|
|
112
|
+
isPythonProject,
|
|
113
|
+
buildEnv : leveregeStanza.buildEnv || leveregeStanza.buildenv || 'alpine',
|
|
114
|
+
imageBase : leveregeStanza.imageBase,
|
|
115
|
+
runuser : leveregeStanza.runUser || leveregeStanza.runuser || isNodeJsProject ? 'node' : 'python',
|
|
116
|
+
nodeimage : leveregeStanza.nodeimg, // left as nodeimg in package.json for backwards compat
|
|
117
|
+
regvers : repoDescr.packageVersion,
|
|
118
|
+
pythonVersion : repoDescr.rootPyProjectToml?.pythonVersion,
|
|
119
|
+
} )
|
|
120
|
+
debug( { dockerInfo }, '<==The Docker Info' )
|
|
121
|
+
|
|
114
122
|
if ( giveGuidance ) {
|
|
115
123
|
await docker.validateCloudBuildBucket( artifactProject )
|
|
116
124
|
}
|
|
117
125
|
|
|
118
126
|
const registryFolder = `${artifactRegistry}/images/${containerName}`
|
|
119
127
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
128
|
+
if ( isNodeJsProject ) {
|
|
129
|
+
// Update the dependencies...
|
|
130
|
+
log( chalk.green.bold( 'Updating dependencies and workspace...' ) )
|
|
131
|
+
await shellCmd( 'npm install', { stdio : 'inherit' } )
|
|
132
|
+
}
|
|
123
133
|
|
|
124
134
|
if ( giveGuidance ) {
|
|
125
135
|
await docker.repoCleanup() // adjusts gitignore files and removes cruft
|
|
@@ -214,10 +224,10 @@ log( `
|
|
|
214
224
|
Version: ${chalk.green.bold( imageVersion )} ${tagInfo}
|
|
215
225
|
Registry: ${chalk.green.bold( artifactRegistry )}
|
|
216
226
|
Image Folder: ${chalk.yellow.bold( registryFolder )}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
${chalk.green.bold( 'Docker Information:' )}
|
|
227
|
+
` )
|
|
228
|
+
if ( isNodeJsProject ) {
|
|
229
|
+
log( `
|
|
230
|
+
${chalk.green.bold( 'NodeJS Docker Information:' )}
|
|
221
231
|
NodeImage: ${chalk.green.bold( dockerInfo.imageBase || `node:${dockerInfo.nodeimage}` )}
|
|
222
232
|
Docker Env: ${chalk.green.bold( dockerInfo.buildEnv || 'alpine' )}
|
|
223
233
|
AddedPkgs: ${chalk.green.bold( dockerInfo.apkadds )}
|
|
@@ -226,7 +236,19 @@ log( `
|
|
|
226
236
|
DateStamp: ${chalk.green.bold( dockerInfo.date )}
|
|
227
237
|
NPM Logs: ${chalk.green.bold( dockerInfo.npmlogging )}
|
|
228
238
|
NPM Version: ${chalk.green.bold( dockerInfo.npmVersion )}
|
|
229
|
-
` )
|
|
239
|
+
` )
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if ( isPythonProject ) {
|
|
243
|
+
log( `
|
|
244
|
+
${chalk.green.bold( 'Python Docker Information:' )}
|
|
245
|
+
BaseImage: ${chalk.green.bold( dockerInfo.imageBase || `node:${dockerInfo.nodeimage}` )}
|
|
246
|
+
Python Ver: ${chalk.green.bold( dockerInfo.pythonVersion )}
|
|
247
|
+
Run User: ${chalk.green.bold( dockerInfo.runuser )}
|
|
248
|
+
Previous: ${chalk.yellow.bold( dockerInfo.previousBuild )}
|
|
249
|
+
DateStamp: ${chalk.green.bold( dockerInfo.date )}
|
|
250
|
+
` )
|
|
251
|
+
}
|
|
230
252
|
|
|
231
253
|
if ( imageVersion !== packageVersion ) {
|
|
232
254
|
log( `
|
|
@@ -281,7 +303,7 @@ if ( isNpmWorkspace ) {
|
|
|
281
303
|
await shellCmd( 'npm install --package-lock-only --workspaces false', { stdio : 'inherit' } )
|
|
282
304
|
}
|
|
283
305
|
|
|
284
|
-
await docker.buildContainerImage( { ...repoDescr,
|
|
306
|
+
await docker.buildContainerImage( { ...repoDescr, imageVersion } )
|
|
285
307
|
|
|
286
308
|
if ( willGitTag ) {
|
|
287
309
|
const tagDescription = `docker_${imageVersion}`
|
|
@@ -12,7 +12,7 @@ spec:
|
|
|
12
12
|
enablePodMonitor: false # set true once monitoring is setup
|
|
13
13
|
|
|
14
14
|
# https://console.cloud.google.com/artifacts/docker/leverege-registry/us/system/images%2Fleverege-pgsql?project=leverege-registry
|
|
15
|
-
imageName: us-docker.pkg.dev/leverege-registry/system/images/leverege-pgsql:17.
|
|
15
|
+
imageName: us-docker.pkg.dev/leverege-registry/system/images/leverege-pgsql:17.5-cnpg-lvrg-rel.1
|
|
16
16
|
description: "Leverege Stack PostgreSQL DB"
|
|
17
17
|
bootstrap:
|
|
18
18
|
initdb:
|
|
@@ -11,7 +11,7 @@ spec:
|
|
|
11
11
|
enablePodMonitor: false # set true once monitoring is setup
|
|
12
12
|
|
|
13
13
|
description: "Leverege Plain Timescale DB"
|
|
14
|
-
imageName: us-docker.pkg.dev/leverege-registry/system/images/leverege-pgsql:17.
|
|
14
|
+
imageName: us-docker.pkg.dev/leverege-registry/system/images/leverege-pgsql:17.5-cnpg-lvrg-rel.1
|
|
15
15
|
bootstrap:
|
|
16
16
|
initdb:
|
|
17
17
|
# database: imagine # let it default to cnpg app db
|
|
@@ -11,7 +11,7 @@ spec:
|
|
|
11
11
|
enablePodMonitor: false # set true once monitoring is setup
|
|
12
12
|
|
|
13
13
|
description: "Leverege Dense Timescale DB"
|
|
14
|
-
imageName: us-docker.pkg.dev/leverege-registry/system/images/leverege-pgsql:17.
|
|
14
|
+
imageName: us-docker.pkg.dev/leverege-registry/system/images/leverege-pgsql:17.5-cnpg-lvrg-rel.1
|
|
15
15
|
bootstrap:
|
|
16
16
|
initdb:
|
|
17
17
|
postInitTemplateSQL:
|
package/src/k8x.sh
CHANGED
|
@@ -4,10 +4,7 @@ options:
|
|
|
4
4
|
steps:
|
|
5
5
|
- name: 'gcr.io/cloud-builders/docker'
|
|
6
6
|
entrypoint: 'bash'
|
|
7
|
-
args: ['-c', 'docker pull
|
|
8
|
-
|
|
9
|
-
- name: 'gcr.io/cloud-builders/docker'
|
|
10
|
-
args: ['buildx', 'create', '--driver', 'docker-container', '--name', 'container', '--driver-opt', 'network=cloudbuild', '--use']
|
|
7
|
+
args: ['-c', 'docker pull {{imageName}}:latest || exit 0']
|
|
11
8
|
|
|
12
9
|
- name: 'gcr.io/cloud-builders/docker'
|
|
13
10
|
args:
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Template dockerfileTemplatePython
|
|
2
|
+
# Version {{regvers}} @ {{date}}
|
|
3
|
+
|
|
4
|
+
FROM {{image}}
|
|
5
|
+
|
|
6
|
+
ARG BUILD_ENV="{{buildEnv}}"
|
|
7
|
+
|
|
8
|
+
RUN useradd -ms /bin/bash {{runuser}} && \
|
|
9
|
+
mkdir -p /usr/src/app /home/{{runuser}} && \
|
|
10
|
+
chown -R {{runuser}} /usr/src/app /home/{{runuser}} && \
|
|
11
|
+
apt-get update && apt-get install -y \
|
|
12
|
+
wget git libgl1 libglib2.0-0 && \
|
|
13
|
+
rm -rf /var/lib/apt/lists/*
|
|
14
|
+
|
|
15
|
+
# Copy uv binary from distroless image
|
|
16
|
+
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
|
|
17
|
+
|
|
18
|
+
# Copy bashrc early
|
|
19
|
+
COPY --chown={{runuser}}:{{runuser}} ./bashrc /home/{{runuser}}/.bashrc
|
|
20
|
+
|
|
21
|
+
WORKDIR /usr/src/app
|
|
22
|
+
USER {{runuser}}
|
|
23
|
+
|
|
24
|
+
ENV GRPC_VERBOSITY=ERROR
|
|
25
|
+
ENV VIRTUAL_ENV=/usr/src/app/.venv
|
|
26
|
+
ENV PATH="$VIRTUAL_ENV/bin:$PATH:/home/{{runuser}}/.local/bin"
|
|
27
|
+
|
|
28
|
+
# Setup pip.conf for GCP Artifact Registry in case pip is needed for building
|
|
29
|
+
RUN mkdir -p /home/{{runuser}}/.config/pip && \
|
|
30
|
+
echo "[global]" >> /home/{{runuser}}/.config/pip/pip.conf && \
|
|
31
|
+
echo "break-system-packages = true" >> /home/{{runuser}}/.config/pip/pip.conf
|
|
32
|
+
|
|
33
|
+
# Set up venv and keyring tools before app copy
|
|
34
|
+
RUN uv venv && \
|
|
35
|
+
uv tool install keyring --with keyrings.google-artifactregistry-auth
|
|
36
|
+
|
|
37
|
+
# Pre-plugin block: models or pre-install commands
|
|
38
|
+
{{preInstallPluginfile}}
|
|
39
|
+
|
|
40
|
+
# Copy only dependency definitions first
|
|
41
|
+
COPY --chown=python:python ./workspace/pyproject.toml \
|
|
42
|
+
./workspace/uv.lock \
|
|
43
|
+
./workspace/.python-version \
|
|
44
|
+
./workspace/README.md \
|
|
45
|
+
./workspace/LICENSE.md \
|
|
46
|
+
/usr/src/app/
|
|
47
|
+
|
|
48
|
+
# Sync dependencies
|
|
49
|
+
RUN uv sync --keyring-provider subprocess \
|
|
50
|
+
--extra-index-url https://oauth2accesstoken@us-python.pkg.dev/leverege-registry/leverege-python-packages/simple \
|
|
51
|
+
&& rm -rf /home/{{runuser}}/.cache
|
|
52
|
+
|
|
53
|
+
# Copy application source AFTER venv + tool setup
|
|
54
|
+
COPY --chown={{runuser}}:{{runuser}} ./workspace/ /usr/src/app/
|
|
55
|
+
|
|
56
|
+
# Plugin block for additional pip packages
|
|
57
|
+
{{pluginfile}}
|
|
58
|
+
|
|
59
|
+
# Ensure src/ layout is importable from anywhere in the container
|
|
60
|
+
ENV PYTHONPATH="/usr/src/app/src"
|
|
61
|
+
|
|
62
|
+
# Show final venv state (optional)
|
|
63
|
+
RUN ls /usr/src/app/.venv/bin
|
|
64
|
+
|
|
65
|
+
CMD [ "/bin/bash", "-c", "source /home/{{runuser}}/.bashrc && python scripts/server.py" ]
|
package/.vscode/settings.json
DELETED
package/src/build-and-push.sh
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
application_name=$(awk -F'"' '/\[(tool\.poetry|project)\]/{flag=1;next} flag==1 && /^name = /{ print $2; exit }' ./pyproject.toml)
|
|
4
|
-
application_version=$(awk -F'"' '/\[(tool\.poetry|project)\]/{flag=1;next} flag==1 && /^version = /{ print $2; exit }' ./pyproject.toml)
|
|
5
|
-
gcp_project_id=$(awk -F'"' '/\[tool\.docker\]/{flag=1;next} flag==1 && /^gcp-project-id = /{ print $2; exit }' ./pyproject.toml)
|
|
6
|
-
gcp_repository_name=$(awk -F'"' '/\[tool\.docker\]/{flag=1;next} flag==1 && /^gcp-repository-name = /{ print $2; exit }' ./pyproject.toml)
|
|
7
|
-
platform=$(awk -F'[][]' '/\[tool\.docker\]/{flag=1;next} flag==1 && /^platform *=/ { gsub(/"/, "", $2); gsub(/, /, ",", $2); print $2; exit }' ./pyproject.toml)
|
|
8
|
-
# Check if the platform is empty
|
|
9
|
-
if [ -z "$platform" ]; then
|
|
10
|
-
platform="linux/amd64,linux/arm64"
|
|
11
|
-
fi
|
|
12
|
-
|
|
13
|
-
# Check if the version contains alpha, beta, rc, or a hyphen
|
|
14
|
-
if [[ $application_version =~ (alpha|beta|rc|-) ]]; then
|
|
15
|
-
is_stable_release="false"
|
|
16
|
-
else
|
|
17
|
-
is_stable_release="true"
|
|
18
|
-
fi
|
|
19
|
-
|
|
20
|
-
cache_path="$HOME/docker/$application_name"
|
|
21
|
-
|
|
22
|
-
echo -e "\n\033[0;32mBuild Information:\033[0m\n"
|
|
23
|
-
|
|
24
|
-
# List application name, application version, GCP project ID, GCP repository name, platform, and if it is a stable release.
|
|
25
|
-
echo -e "\033[0;32mApplication Name:\033[0m $application_name"
|
|
26
|
-
echo -e "\033[0;32mApplication Version:\033[0m $application_version"
|
|
27
|
-
echo -e "\033[0;32mGCP Project ID:\033[0m $gcp_project_id"
|
|
28
|
-
echo -e "\033[0;32mGCP Repository Name:\033[0m $gcp_repository_name"
|
|
29
|
-
echo -e "\033[0;32mPlatform:\033[0m $platform"
|
|
30
|
-
echo -e "\033[0;32mStable Release:\033[0m $is_stable_release"
|
|
31
|
-
|
|
32
|
-
# Prompt for confirmation
|
|
33
|
-
echo -e "\n"
|
|
34
|
-
read -p "Do you wish to proceed? (y/n): " -n 1 -r
|
|
35
|
-
echo -e "\n"
|
|
36
|
-
|
|
37
|
-
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
38
|
-
echo -e "\033[0;31mExiting...\033[0m\n\n"
|
|
39
|
-
exit 1
|
|
40
|
-
fi
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
echo -e "\n\033[0;32mBuilding, creating and pushing image(s)...\033[0m\n\n"
|
|
44
|
-
|
|
45
|
-
export GCLOUD_ACCESS_TOKEN=$(gcloud auth print-access-token)
|
|
46
|
-
|
|
47
|
-
if [ "$is_stable_release" = "true" ]; then
|
|
48
|
-
docker buildx build \
|
|
49
|
-
--platform $platform \
|
|
50
|
-
--build-arg APPLICATION_NAME=$application_name \
|
|
51
|
-
--build-arg APPLICATION_VERSION=$application_version \
|
|
52
|
-
--secret id=token,env=GCLOUD_ACCESS_TOKEN \
|
|
53
|
-
--secret="id=creds,src=$HOME/.config/gcloud/application_default_credentials.json" \
|
|
54
|
-
--tag us-docker.pkg.dev/$gcp_project_id/$gcp_repository_name/${application_name}:${application_version} \
|
|
55
|
-
--tag us-docker.pkg.dev/$gcp_project_id/$gcp_repository_name/${application_name}:latest \
|
|
56
|
-
--push \
|
|
57
|
-
.
|
|
58
|
-
else
|
|
59
|
-
docker buildx build \
|
|
60
|
-
--platform $platform \
|
|
61
|
-
--build-arg APPLICATION_NAME=$application_name \
|
|
62
|
-
--build-arg APPLICATION_VERSION=$application_version \
|
|
63
|
-
--secret id=token,env=GCLOUD_ACCESS_TOKEN \
|
|
64
|
-
--secret="id=creds,src=$HOME/.config/gcloud/application_default_credentials.json" \
|
|
65
|
-
--tag us-docker.pkg.dev/$gcp_project_id/$gcp_repository_name/${application_name}:${application_version} \
|
|
66
|
-
--push \
|
|
67
|
-
.
|
|
68
|
-
fi
|
|
69
|
-
|
|
70
|
-
if [ $? -eq 0 ]; then
|
|
71
|
-
echo -e "\n\n\033[0;32mBuilt and pushed us-docker.pkg.dev/$gcp_project_id/$gcp_repository_name/$application_name:$application_version for $platform\033[0m"
|
|
72
|
-
if [ "$is_stable_release" = "true" ]; then
|
|
73
|
-
echo -e "\033[0;32mAlso tagged as 'latest'\033[0m"
|
|
74
|
-
fi
|
|
75
|
-
echo -e "\n\n"
|
|
76
|
-
else
|
|
77
|
-
echo -e "\n\n\033[0;31mBuild and push failed!\033[0m\n\n"
|
|
78
|
-
fi
|