@leverege/build-tools 2.61.7 → 2.62.0-alpha.1
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 +13 -8
- package/src/Docker.mjs +18 -44
- package/src/DockerPy.mjs +257 -0
- package/src/Utils.mjs +0 -6
- package/src/bash-funcs +0 -4
- package/src/docker-to-registry-py.mjs +291 -0
- package/src/docker-to-registry.mjs +1 -3
- package/src/docker-to-registry.sh +1 -1
- package/src/helm-charts/cnpg-db-pgbench/cluster.yaml.ovh +3 -2
- package/src/helm-charts/cnpg-db-psql-stack/cluster.yaml.ovh +3 -2
- package/src/helm-charts/cnpg-db-recovery/cluster.yaml.ovh +3 -2
- package/src/helm-charts/cnpg-db-tsdb-basic/cluster.yaml.ovh +3 -2
- package/src/helm-charts/cnpg-db-tsdb-dense/cluster.yaml.ovh +3 -2
- package/src/helm-charts/prom-operator/helmup.plugin +1 -4
- package/src/hook-and-release/Config.mjs +0 -9
- package/src/templates/bashrcTemplatePy.hbs +1 -0
- package/src/templates/dockerfileTemplate.hbs +6 -6
- package/src/templates/dockerfileTemplatePy.hbs +75 -0
- package/src/build-cnpg-image.mjs +0 -176
- package/src/chart-compass.mjs +0 -97
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leverege/build-tools",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.62.0-alpha.1",
|
|
4
4
|
"description": "A collection of build / support tools for Leverege developers",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -16,13 +16,14 @@
|
|
|
16
16
|
"bin": {
|
|
17
17
|
"build-tools": "src/build-tools.mjs",
|
|
18
18
|
"build-and-push": "src/build-and-push.sh",
|
|
19
|
-
"build-cnpg-image": "src/build-cnpg-image.mjs",
|
|
20
19
|
"chart-to-registry": "src/chart-to-registry.mjs",
|
|
21
20
|
"circleate": "src/circleate.sh",
|
|
21
|
+
"cnpg-backup": "src/cnpg-backup.mjs",
|
|
22
22
|
"decrypt-secrets": "src/decrypt-secrets.sh",
|
|
23
23
|
"dirty-git": "src/dirty-git.sh",
|
|
24
24
|
"dockreate": "src/dockreate.sh",
|
|
25
25
|
"docker-to-registry": "src/docker-to-registry.mjs",
|
|
26
|
+
"docker-to-registry.sh": "src/docker-to-registry.sh",
|
|
26
27
|
"encrypt-secrets": "src/encrypt-secrets.sh",
|
|
27
28
|
"firebaseDeploy": "src/firebaseDeploy.mjs",
|
|
28
29
|
"firebaseServe": "src/firebaseServe.mjs",
|
|
@@ -36,7 +37,9 @@
|
|
|
36
37
|
"helminit": "src/helmup.sh",
|
|
37
38
|
"helmwhat": "src/helmup.sh",
|
|
38
39
|
"hook-and-release": "src/hook-and-release.mjs",
|
|
40
|
+
"k8cryo": "src/k8cryo.sh",
|
|
39
41
|
"k8scale": "src/k8scale.sh",
|
|
42
|
+
"k8thaw": "src/k8cryo.sh",
|
|
40
43
|
"k8x": "src/k8x.sh",
|
|
41
44
|
"klog": "src/klog.sh",
|
|
42
45
|
"npm-link": "src/npm-link.sh",
|
|
@@ -50,7 +53,6 @@
|
|
|
50
53
|
"refresh-npm-token": "src/refresh-npm-token.mjs",
|
|
51
54
|
"refresh-py-idx": "src/refresh-py-idx.sh",
|
|
52
55
|
"send-to-slack": "src/send-to-slack.mjs",
|
|
53
|
-
"snapshot-cnpg": "src/snapshot-cnpg.mjs",
|
|
54
56
|
"tag-release": "src/tag-release.mjs",
|
|
55
57
|
"unleash": "src/unleash.mjs"
|
|
56
58
|
},
|
|
@@ -59,28 +61,31 @@
|
|
|
59
61
|
"dependencies": {
|
|
60
62
|
"@google-cloud/artifact-registry": "^3.5.0",
|
|
61
63
|
"@leverege/jsdoc-template": "^1.0.1",
|
|
64
|
+
"ansi-colors": "^4.1.3",
|
|
62
65
|
"chalk": "^5.4.1",
|
|
63
66
|
"command-line-args": "^6.0.1",
|
|
64
67
|
"command-line-usage": "^7.0.3",
|
|
65
68
|
"deepmerge": "^4.3.1",
|
|
66
69
|
"enquirer": "^2.4.1",
|
|
67
70
|
"execa": "^9.5.2",
|
|
68
|
-
"glob": "^11.0.
|
|
71
|
+
"glob": "^11.0.0",
|
|
69
72
|
"handlebars": "^4.7.8",
|
|
70
|
-
"inquirer": "^12.
|
|
73
|
+
"inquirer": "^12.3.0",
|
|
71
74
|
"js-yaml": "^4.1.0",
|
|
72
75
|
"jsdoc": "^4.0.4",
|
|
73
76
|
"ms": "^2.1.3",
|
|
74
77
|
"npm-registry-fetch": "^18.0.2",
|
|
75
78
|
"package-up": "^5.0.0",
|
|
76
79
|
"parse-gitignore": "^2.0.0",
|
|
80
|
+
"read-pkg": "^9.0.1",
|
|
77
81
|
"readline-sync": "^1.4.10",
|
|
78
|
-
"semver": "^7.
|
|
82
|
+
"semver": "^7.6.3",
|
|
79
83
|
"simple-git": "^3.27.0",
|
|
80
|
-
"
|
|
84
|
+
"toml": "^3.0.0",
|
|
85
|
+
"zx": "^8.3.0"
|
|
81
86
|
},
|
|
82
87
|
"devDependencies": {
|
|
83
88
|
"@leverege/eslint-config-leverege": "^5.0.1",
|
|
84
|
-
"npm": "^11.
|
|
89
|
+
"npm": "^11.0.0"
|
|
85
90
|
}
|
|
86
91
|
}
|
package/src/Docker.mjs
CHANGED
|
@@ -24,7 +24,7 @@ const dockerfileNodeVersion = 'jod-alpine'
|
|
|
24
24
|
// the build-tools repository, but it just became simpler to pull the contents
|
|
25
25
|
// directly into these variables and forego the file loading.
|
|
26
26
|
//
|
|
27
|
-
const
|
|
27
|
+
const pluginTemplate = `
|
|
28
28
|
# Dockerfile.plugin - optionally extend the service Docker image
|
|
29
29
|
#
|
|
30
30
|
# This file may be used to run additional docker commands during the image
|
|
@@ -38,14 +38,6 @@ const dockerfilePluginTemplate = `
|
|
|
38
38
|
# Keep in mind that the Alpine Linux base image is used to keep image
|
|
39
39
|
# footprints small, so adding packages "just because" is not considered
|
|
40
40
|
# a best practice.
|
|
41
|
-
`
|
|
42
|
-
const bashrcPluginTemplate = `
|
|
43
|
-
|
|
44
|
-
# Bashrc.plugin - optionally extend the image .bashrc file
|
|
45
|
-
#
|
|
46
|
-
# This plugin file may contain additional .bashrc settigns / functions to
|
|
47
|
-
# provide on the target image.
|
|
48
|
-
|
|
49
41
|
`
|
|
50
42
|
const dockerfileTemplate = fs.readFileSync( path.join( DIRNAME, './templates/dockerfileTemplate.hbs' ), 'utf8' )
|
|
51
43
|
const bashrcTemplate = fs.readFileSync( path.join( DIRNAME, './templates/bashrcTemplate.hbs' ), 'utf8' )
|
|
@@ -74,10 +66,9 @@ const setPreviousBuild = ( version ) => {
|
|
|
74
66
|
fs.writeFileSync( previousFile, version )
|
|
75
67
|
}
|
|
76
68
|
|
|
77
|
-
const generateDockerfile =
|
|
69
|
+
const generateDockerfile = ( options ) => {
|
|
78
70
|
|
|
79
|
-
const
|
|
80
|
-
const settings = { gitReference, ...defaultSettings, ...options }
|
|
71
|
+
const settings = { ...defaultSettings, ...options }
|
|
81
72
|
|
|
82
73
|
// defaults to the current "official" version of node unless it gets
|
|
83
74
|
// overridden in the leverege.nodeimg package.json stanza
|
|
@@ -94,31 +85,24 @@ const generateDockerfile = async ( options ) => {
|
|
|
94
85
|
fs.mkdirSync( './docker' ) // TODO: blindly assumes the mkdir succeeds
|
|
95
86
|
}
|
|
96
87
|
|
|
97
|
-
// Create a bashrc plugin file if one does not already exist
|
|
98
|
-
const bashrcPluginFile = './docker/Bashrc.plugin'
|
|
99
|
-
if ( !fs.existsSync( bashrcPluginFile ) ) {
|
|
100
|
-
warning( `creating the missing ${bashrcPluginFile} file in the docker directory\n` )
|
|
101
|
-
fs.writeFileSync( bashrcPluginFile, bashrcPluginTemplate )
|
|
102
|
-
}
|
|
103
|
-
const bashrcPlugin = fs.readFileSync( bashrcPluginFile )
|
|
104
|
-
|
|
105
|
-
// Build the target bashrc file by using the template plus Bashrc.plugin
|
|
106
88
|
const bashrcFile = './docker/bashrc'
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
fs.
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
89
|
+
// DISABLING exists check. With addition of Bashrc.plugin, the file needs to
|
|
90
|
+
// always be created or we encounter errors
|
|
91
|
+
if ( true ) { // !fs.existsSync( bashrcFile ) ) {
|
|
92
|
+
let bf = bashrcTemplate
|
|
93
|
+
const bashrcFilePlugin = './docker/Bashrc.plugin'
|
|
94
|
+
if ( fs.existsSync( bashrcFilePlugin ) ) {
|
|
95
|
+
const bashrcAdditions = fs.readFileSync( bashrcFilePlugin )
|
|
96
|
+
bf = `${bf}\n${bashrcAdditions}`
|
|
97
|
+
}
|
|
98
|
+
warning( `creating the missing ${bashrcFile} file in the docker directory` )
|
|
99
|
+
fs.writeFileSync( bashrcFile, bf )
|
|
116
100
|
}
|
|
117
101
|
|
|
118
102
|
const dockerfilePlugin = './docker/Dockerfile.plugin'
|
|
119
103
|
if ( !fs.existsSync( dockerfilePlugin ) ) {
|
|
120
104
|
warning( `creating the missing ${dockerfilePlugin} file in the docker directory` )
|
|
121
|
-
fs.writeFileSync( dockerfilePlugin,
|
|
105
|
+
fs.writeFileSync( dockerfilePlugin, pluginTemplate )
|
|
122
106
|
}
|
|
123
107
|
|
|
124
108
|
try {
|
|
@@ -130,7 +114,7 @@ const generateDockerfile = async ( options ) => {
|
|
|
130
114
|
errorExit( `***ERROR: expected the ./build directory to exist - ${chalk.yellow( 'npm run build' )}` )
|
|
131
115
|
}
|
|
132
116
|
|
|
133
|
-
// At this point the
|
|
117
|
+
// At this point the plugin template better exist.
|
|
134
118
|
if ( fs.existsSync( dockerfilePlugin ) ) {
|
|
135
119
|
settings.pluginfile = fs.readFileSync( dockerfilePlugin )
|
|
136
120
|
} else {
|
|
@@ -189,22 +173,12 @@ const buildContainerImage = async ( {
|
|
|
189
173
|
// TODO: This is janky - I'll clean it up later
|
|
190
174
|
// NOTE: this is dealing with raw filesystem interactions, meaning there
|
|
191
175
|
// isn't a shell performing file globbing and what not
|
|
192
|
-
//
|
|
193
|
-
// Steps taken here attempt to minimize impact on legacy build setups
|
|
194
|
-
// 1. rename build dir to workspace
|
|
195
|
-
// 2. create the actual build dir and move workspace into it
|
|
196
|
-
// 3. move the Dockerfile into build and make a copy for image root
|
|
197
|
-
// 4. copy the bashrc file into build and .bashrc on the image root
|
|
198
|
-
// 5. drop a copy of dev's npmrc to use for build process
|
|
199
|
-
// 6. drop a copy of package.json and the lock into the image root
|
|
200
|
-
//
|
|
201
176
|
fs.renameSync( './build', './workspace' )
|
|
202
177
|
fs.mkdirSync( './build' )
|
|
203
178
|
fs.renameSync( './workspace', buildWorkspace )
|
|
204
179
|
fs.renameSync( './docker/Dockerfile', './build/Dockerfile' )
|
|
205
|
-
fs.cpSync( './build/Dockerfile', `${buildWorkspace}/Dockerfile` )
|
|
206
|
-
fs.renameSync( './docker/bashrc', './build/bashrc' )
|
|
207
180
|
fs.cpSync( `${process.env.HOME}/.npmrc`, './build/.npmrc' )
|
|
181
|
+
fs.cpSync( './docker/bashrc', './build/bashrc' )
|
|
208
182
|
fs.cpSync( './package.json', `${buildWorkspace}/package.json` )
|
|
209
183
|
fs.cpSync( './package-lock.json', `${buildWorkspace}/package-lock.json` )
|
|
210
184
|
if ( isNpmWorkspace ) {
|
|
@@ -214,7 +188,7 @@ const buildContainerImage = async ( {
|
|
|
214
188
|
setPreviousBuild( imageVersion ) // update docker/.previous file
|
|
215
189
|
|
|
216
190
|
const { fullName : builderName } = await getGcpAccount()
|
|
217
|
-
const gcloudBuild = `gcloud builds submit --project ${artifactProject}`
|
|
191
|
+
const gcloudBuild = `time gcloud builds submit --project ${artifactProject}`
|
|
218
192
|
const gcloudLogs = `--gcs-log-dir ${formCloudBuildBucketName( artifactProject )}/log`
|
|
219
193
|
let gcloudTags = `--tag ${imageName}:${imageVersion}`
|
|
220
194
|
|
package/src/DockerPy.mjs
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import url from 'node:url'
|
|
4
|
+
|
|
5
|
+
import chalk from 'chalk'
|
|
6
|
+
import handlebars from 'handlebars'
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
errorExit,
|
|
10
|
+
getDateTimestamp,
|
|
11
|
+
getGcpAccount,
|
|
12
|
+
log,
|
|
13
|
+
proceed,
|
|
14
|
+
shellCmd,
|
|
15
|
+
warning
|
|
16
|
+
} from './Utils.mjs'
|
|
17
|
+
|
|
18
|
+
const DIRNAME = path.dirname( url.fileURLToPath( import.meta.url ) )
|
|
19
|
+
|
|
20
|
+
// The contents of these variables were initially located in files that live in
|
|
21
|
+
// the build-tools repository, but it just became simpler to pull the contents
|
|
22
|
+
// directly into these variables and forego the file loading.
|
|
23
|
+
//
|
|
24
|
+
const pluginTemplate = `
|
|
25
|
+
# Dockerfile.plugin - optionally extend the service Docker image
|
|
26
|
+
#
|
|
27
|
+
# This file may be used to run additional docker commands during the image
|
|
28
|
+
# build process without needing to maintain a local custom Dockerfile. For
|
|
29
|
+
# example, uncommenting the following docker RUN command will cause the
|
|
30
|
+
# curl and vim packages to be added to the deployed image thus making them
|
|
31
|
+
# available from the pod's command line on k8s:
|
|
32
|
+
#
|
|
33
|
+
# RUN apk update && apk add --no-cache curl vim
|
|
34
|
+
#
|
|
35
|
+
# Keep in mind that the Alpine Linux base image is used to keep image
|
|
36
|
+
# footprints small, so adding packages "just because" is not considered
|
|
37
|
+
# a best practice.
|
|
38
|
+
`
|
|
39
|
+
const dockerfileTemplate = fs.readFileSync( path.join( DIRNAME, './templates/dockerfileTemplatePy.hbs' ), 'utf8' )
|
|
40
|
+
const cloudBuildSteps = fs.readFileSync( path.join( DIRNAME, './templates/cloudBuildSteps.hbs' ), 'utf8' )
|
|
41
|
+
let bashrcTemplate = fs.readFileSync( path.join( DIRNAME, './templates/bashrcTemplate.hbs' ), 'utf8' )
|
|
42
|
+
const bashrcPyTemplate = fs.readFileSync( path.join( DIRNAME, './templates/bashrcTemplatePy.hbs' ), 'utf8' )
|
|
43
|
+
bashrcTemplate = `${bashrcTemplate}\n${bashrcPyTemplate}`
|
|
44
|
+
|
|
45
|
+
const defaultSettings = {
|
|
46
|
+
apkadds : '',
|
|
47
|
+
date : getDateTimestamp(),
|
|
48
|
+
nodeimage : 'jod-alpine',
|
|
49
|
+
imageBase : 'node:jod-alpine',
|
|
50
|
+
npmlogging : process.env.VERBOSE_NPM_LOGGING ? '--ddd' : '--silent',
|
|
51
|
+
npmVersion : 'npm@11',
|
|
52
|
+
pluginfile : '# NO PLUGIN',
|
|
53
|
+
preInstallPluginfile : '# NO PRE-INSTALL PLUGIN',
|
|
54
|
+
regvers : 'package.version',
|
|
55
|
+
runuser : 'python',
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const previousFile = './docker/.previous'
|
|
59
|
+
|
|
60
|
+
function getPreviousBuild() {
|
|
61
|
+
return fs.existsSync( previousFile ) ? fs.readFileSync( previousFile ) : 'FIRST BUILD'
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const setPreviousBuild = ( version ) => {
|
|
65
|
+
fs.writeFileSync( previousFile, version )
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function generateDockerfile( options ) {
|
|
69
|
+
|
|
70
|
+
const settings = { ...defaultSettings, ...options }
|
|
71
|
+
|
|
72
|
+
if ( !settings.imageBase ) {
|
|
73
|
+
warning( 'using the default image python:3.12.8-slim-bookworm' )
|
|
74
|
+
settings.image = 'python:3.12.8-slim-bookworm'
|
|
75
|
+
} else {
|
|
76
|
+
settings.image = settings.imageBase
|
|
77
|
+
}
|
|
78
|
+
// Ensure the presence of the docker dir with plugin and bashrc - this code
|
|
79
|
+
// could probably be tightened up a little.
|
|
80
|
+
try {
|
|
81
|
+
fs.readdirSync( './docker' )
|
|
82
|
+
} catch ( err ) {
|
|
83
|
+
warning( 'creating the missing ./docker directory' )
|
|
84
|
+
fs.mkdirSync( './docker' ) // TODO: blindly assumes the mkdir succeeds
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const bashrcFile = './docker/bashrc'
|
|
88
|
+
let bf = bashrcTemplate
|
|
89
|
+
const bashrcFilePlugin = './docker/Bashrc.plugin'
|
|
90
|
+
if ( fs.existsSync( bashrcFilePlugin ) ) {
|
|
91
|
+
const bashrcAdditions = fs.readFileSync( bashrcFilePlugin )
|
|
92
|
+
bf = `${bf}\n${bashrcAdditions}`
|
|
93
|
+
}
|
|
94
|
+
fs.writeFileSync( bashrcFile, bf )
|
|
95
|
+
|
|
96
|
+
const dockerfilePlugin = './docker/Dockerfile.plugin'
|
|
97
|
+
if ( !fs.existsSync( dockerfilePlugin ) ) {
|
|
98
|
+
warning( `creating the missing ${dockerfilePlugin} file in the docker directory` )
|
|
99
|
+
fs.writeFileSync( dockerfilePlugin, pluginTemplate )
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
const build = fs.readdirSync( './build' )
|
|
104
|
+
if ( build.length === 0 ) {
|
|
105
|
+
errorExit( `***ERROR: the build dir is empty - ${chalk.yellow( 'npm run build' )}` )
|
|
106
|
+
}
|
|
107
|
+
} catch ( err ) {
|
|
108
|
+
errorExit( `***ERROR: expected the ./build directory to exist - ${chalk.yellow( 'npm run build' )}` )
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// At this point the plugin template better exist.
|
|
112
|
+
if ( fs.existsSync( dockerfilePlugin ) ) {
|
|
113
|
+
settings.pluginfile = fs.readFileSync( dockerfilePlugin )
|
|
114
|
+
} else {
|
|
115
|
+
errorExit( `***ERROR: something went wrong with ${dockerfilePlugin} plugin creation` )
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const dockerfilePrePlugin = './docker/DockerfilePreInstall.plugin'
|
|
119
|
+
if ( fs.existsSync( dockerfilePrePlugin ) ) {
|
|
120
|
+
settings.preInstallPluginfile = fs.readFileSync( dockerfilePrePlugin )
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const compiled = handlebars.compile( dockerfileTemplate, { noEscape : true } )
|
|
124
|
+
const replaced = compiled( settings )
|
|
125
|
+
// temporarily write the Dockerfile to the docker subdir - the container
|
|
126
|
+
// image builder will then move it over to the build subdir
|
|
127
|
+
const dockerfile = './docker/Dockerfile'
|
|
128
|
+
try {
|
|
129
|
+
fs.writeFileSync( dockerfile, replaced )
|
|
130
|
+
} catch ( err ) {
|
|
131
|
+
errorExit( `***ERROR: failed to write ${dockerfile}\n${err}` )
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const previousBuild = getPreviousBuild()
|
|
135
|
+
const dockerInfo = { dockerfile, previousBuild, ...settings }
|
|
136
|
+
delete dockerInfo.pluginfile
|
|
137
|
+
return dockerInfo
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function formCloudBuildBucketName( artifactProject ) {
|
|
141
|
+
return `gs://${artifactProject}_cloudbuild`
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async function validateCloudBuildBucket( artifactProject ) {
|
|
145
|
+
const bucketName = formCloudBuildBucketName( artifactProject )
|
|
146
|
+
log( chalk.green.bold( `Verifying the build bucket exists => ${bucketName}\n` ) )
|
|
147
|
+
try {
|
|
148
|
+
await shellCmd( `gsutil ls -p ${artifactProject} -b ${bucketName}` )
|
|
149
|
+
} catch ( error ) {
|
|
150
|
+
errorExit( `***Error: from Docker.validateCloudBuildBucket\n\n${chalk.bold.yellow( error )}` )
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function buildContainerImage( {
|
|
155
|
+
artifactProject, artifactRegistry, containerName,
|
|
156
|
+
imageVersion, isNpmWorkspace, options
|
|
157
|
+
} ) {
|
|
158
|
+
|
|
159
|
+
const useCloudBuildFile = true
|
|
160
|
+
const buildWorkspace = './build/workspace' // passed to Cloud Build
|
|
161
|
+
const imageName = `${artifactRegistry}/images/${containerName}`
|
|
162
|
+
|
|
163
|
+
if ( fs.existsSync( buildWorkspace ) ) {
|
|
164
|
+
fs.renameSync( buildWorkspace, `${buildWorkspace}-junk` )
|
|
165
|
+
try {
|
|
166
|
+
fs.rmSync( `${buildWorkspace}-junk`, { recursive : true } )
|
|
167
|
+
} catch ( err ) {
|
|
168
|
+
log( `***Error: from Docker.buildContainerImage\n\n${chalk.bold.yellow( err )}` )
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// TODO: This is janky - I'll clean it up later
|
|
173
|
+
// NOTE: this is dealing with raw filesystem interactions, meaning there
|
|
174
|
+
// isn't a shell performing file globbing and what not
|
|
175
|
+
fs.renameSync( './build', './workspace' )
|
|
176
|
+
fs.mkdirSync( './build' )
|
|
177
|
+
fs.renameSync( './workspace', buildWorkspace )
|
|
178
|
+
fs.renameSync( './docker/Dockerfile', './build/Dockerfile' )
|
|
179
|
+
// fs.cpSync( `${process.env.HOME}/.npmrc`, './build/.npmrc' )
|
|
180
|
+
fs.cpSync( './docker/bashrc', './build/bashrc' )
|
|
181
|
+
// fs.cpSync( './package.json', `${buildWorkspace}/package.json` )
|
|
182
|
+
// fs.cpSync( './package-lock.json', `${buildWorkspace}/package-lock.json` )
|
|
183
|
+
|
|
184
|
+
setPreviousBuild( imageVersion ) // update docker/.previous file
|
|
185
|
+
|
|
186
|
+
const { fullName : builderName } = await getGcpAccount()
|
|
187
|
+
const gcloudBuild = `time gcloud builds submit --project ${artifactProject}`
|
|
188
|
+
const gcloudLogs = `--gcs-log-dir ${formCloudBuildBucketName( artifactProject )}/log`
|
|
189
|
+
let gcloudTags = `--tag ${imageName}:${imageVersion}`
|
|
190
|
+
|
|
191
|
+
if ( useCloudBuildFile ) {
|
|
192
|
+
const cloudBuildFile = './docker/cloudbuild.yaml'
|
|
193
|
+
gcloudTags = `--config=${cloudBuildFile}`
|
|
194
|
+
const cbst = handlebars.compile( cloudBuildSteps, { noEscape : true } )
|
|
195
|
+
const cbs = cbst( { artifactProject, artifactRegistry, imageName, imageVersion } )
|
|
196
|
+
|
|
197
|
+
fs.writeFileSync( cloudBuildFile, cbs )
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
log( chalk.green.bold( `
|
|
201
|
+
*** Submitting Build as ${builderName} ***
|
|
202
|
+
${gcloudBuild} \\
|
|
203
|
+
${gcloudLogs} \\
|
|
204
|
+
${gcloudTags}
|
|
205
|
+
` ) )
|
|
206
|
+
|
|
207
|
+
if ( process.env.DRY_RUN === '1' ) {
|
|
208
|
+
log( '\n***Exiting from DRY_RUN\n' )
|
|
209
|
+
process.exit( 0 )
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
await shellCmd( `${gcloudBuild} ${gcloudLogs} ${gcloudTags} ./build`, { stdio : 'inherit' } )
|
|
213
|
+
|
|
214
|
+
const imageTag = `${defaultSettings.date}-${defaultSettings.nodeimage}-${builderName}`
|
|
215
|
+
await shellCmd(
|
|
216
|
+
`gcloud container images add-tag --quiet ${imageName}:${imageVersion} ${imageName}:${imageTag} ${imageName}:latest`
|
|
217
|
+
)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
async function repoCleanup() {
|
|
221
|
+
// remove garbage from the repo
|
|
222
|
+
const garbage = [
|
|
223
|
+
'build',
|
|
224
|
+
'dist',
|
|
225
|
+
'docker/.keep',
|
|
226
|
+
'docker/.npmrc',
|
|
227
|
+
'docker/.gitignore',
|
|
228
|
+
'docker/.previous',
|
|
229
|
+
'docker/Dockerfile',
|
|
230
|
+
'docker/workspace',
|
|
231
|
+
]
|
|
232
|
+
garbage.forEach( trash => fs.rmSync( trash, { recursive : true, force : true } ) )
|
|
233
|
+
|
|
234
|
+
fs.writeFileSync( 'docker/.gitignore', '.previous\nDockerfile' )
|
|
235
|
+
|
|
236
|
+
await shellCmd( 'git add -f docker' )
|
|
237
|
+
|
|
238
|
+
log( `
|
|
239
|
+
${chalk.yellow.bold( '***IMPORTANT***' )}
|
|
240
|
+
|
|
241
|
+
Please make the following .gitignore modifications:
|
|
242
|
+
change /dist to ${chalk.green.bold( '/build' )}
|
|
243
|
+
remove ${chalk.red.bold( '/docker' )}
|
|
244
|
+
` )
|
|
245
|
+
|
|
246
|
+
await proceed( 'Acknowledge the .gitignore mods were made?' )
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export default {
|
|
250
|
+
getPreviousBuild,
|
|
251
|
+
setPreviousBuild,
|
|
252
|
+
generateDockerfile,
|
|
253
|
+
formCloudBuildBucketName,
|
|
254
|
+
validateCloudBuildBucket,
|
|
255
|
+
buildContainerImage,
|
|
256
|
+
repoCleanup,
|
|
257
|
+
}
|
package/src/Utils.mjs
CHANGED
|
@@ -54,10 +54,6 @@ export const isString = ( s ) => {
|
|
|
54
54
|
* General "yes" to proceed function.
|
|
55
55
|
*/
|
|
56
56
|
export const proceed = async ( query = 'Do you wish to proceed?' ) => {
|
|
57
|
-
if ( process.env.CICD_PIPELINE === '1' ) {
|
|
58
|
-
log( '\n*** CICD Pipeline - skipping user prompts' )
|
|
59
|
-
return
|
|
60
|
-
}
|
|
61
57
|
await inquirer.prompt( [
|
|
62
58
|
{
|
|
63
59
|
type : 'confirm',
|
|
@@ -403,7 +399,6 @@ export const getRepositoryDescr = async () => {
|
|
|
403
399
|
const currentDir = process.cwd()
|
|
404
400
|
const workingDir = process.env.PWD
|
|
405
401
|
const gitRoot = await getGitRootDirectory()
|
|
406
|
-
const isGitRepo = gitRoot !== undefined
|
|
407
402
|
const gitHooksPath = await getGitHooksPath()
|
|
408
403
|
const { branch : gitBranch, upstream : gitUpstream } = await getGitBranchAndUpstream()
|
|
409
404
|
const subPkgs = await glob( `${gitRoot}/packages/**/package.json`, { ignore : '/**/node_modules/**' } )
|
|
@@ -425,7 +420,6 @@ export const getRepositoryDescr = async () => {
|
|
|
425
420
|
gitRoot,
|
|
426
421
|
gitUpstream,
|
|
427
422
|
helmChart,
|
|
428
|
-
isGitRepo,
|
|
429
423
|
isMonoRepo,
|
|
430
424
|
isNpmWorkspace,
|
|
431
425
|
rootPackageJson,
|