underpost 3.2.12 → 3.2.21
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/.github/workflows/ghpkg.ci.yml +1 -0
- package/.github/workflows/npmpkg.ci.yml +9 -5
- package/CHANGELOG.md +114 -1
- package/CLI-HELP.md +973 -1130
- package/README.md +47 -41
- package/bin/build.js +88 -137
- package/bin/build.template.js +25 -179
- package/bin/deploy.js +4 -1
- package/bin/index.js +2 -2
- package/conf.js +11 -37
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +2 -2
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/package.json +9 -14
- package/scripts/link-local-underpost-cli.sh +6 -0
- package/scripts/test-monitor.sh +86 -0
- package/src/cli/deploy.js +195 -274
- package/src/cli/env.js +1 -4
- package/src/cli/image.js +58 -4
- package/src/cli/index.js +39 -0
- package/src/cli/monitor.js +302 -6
- package/src/cli/release.js +26 -11
- package/src/cli/repository.js +98 -7
- package/src/cli/run.js +137 -69
- package/src/db/mongo/MongooseDB.js +2 -1
- package/src/index.js +1 -1
- package/src/runtime/wp/Dockerfile +3 -3
- package/src/server/catalog-underpost.js +61 -0
- package/src/server/catalog.js +77 -0
- package/src/server/conf.js +365 -56
- package/src/server/runtime-status.js +235 -0
- package/src/server/start.js +17 -8
- package/test/deploy-monitor.test.js +223 -0
- package/manifests/deployment/dd-test-development/deployment.yaml +0 -256
- package/manifests/deployment/dd-test-development/proxy.yaml +0 -102
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
<div align="center">
|
|
18
18
|
|
|
19
|
-
[](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml) [](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml) [](https://www.npmjs.com/package/underpost) [](https://www.jsdelivr.com/package/npm/underpost) [](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml) [](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml) [](https://www.npmjs.com/package/underpost) [](https://www.jsdelivr.com/package/npm/underpost) [](https://socket.dev/npm/package/underpost/overview/3.2.21) [](https://coveralls.io/github/underpostnet/engine?branch=master) [](https://www.npmjs.org/package/underpost) [](https://www.npmjs.com/package/underpost)
|
|
20
20
|
|
|
21
21
|
</div>
|
|
22
22
|
|
|
@@ -86,46 +86,52 @@ npm run dev
|
|
|
86
86
|
<a target="_top" href="https://www.nexodev.org/docs?cid=src">See Docs.</a>
|
|
87
87
|
|
|
88
88
|
<!-- cli-index-start -->
|
|
89
|
-
##
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
89
|
+
## Underpost CLI
|
|
90
|
+
|
|
91
|
+
> underpost ci/cd cli v3.2.21
|
|
92
|
+
|
|
93
|
+
**Usage:** `underpost [options] [command]`
|
|
94
|
+
|
|
95
|
+
### Global options
|
|
96
|
+
|
|
97
|
+
| Option | Description |
|
|
98
|
+
| --- | --- |
|
|
99
|
+
| `-V, --version` | output the version number |
|
|
100
|
+
| `-h, --help` | display help for command |
|
|
101
|
+
|
|
102
|
+
### Commands
|
|
103
|
+
|
|
104
|
+
| Command | Description |
|
|
105
|
+
| --- | --- |
|
|
106
|
+
| [`new`](CLI-HELP.md#underpost-new) | Initializes a new Underpost project, service, or configuration. |
|
|
107
|
+
| [`client`](CLI-HELP.md#underpost-client) | Builds client assets, single replicas, and/or syncs environment ports. |
|
|
108
|
+
| [`start`](CLI-HELP.md#underpost-start) | Initiates application servers, build pipelines, or other defined services based on the deployment ID. |
|
|
109
|
+
| [`clone`](CLI-HELP.md#underpost-clone) | Clones a specified GitHub repository into the current directory. |
|
|
110
|
+
| [`pull`](CLI-HELP.md#underpost-pull) | Pulls the latest changes from a specified GitHub repository. |
|
|
111
|
+
| [`cmt`](CLI-HELP.md#underpost-cmt) | Manages commits to a GitHub repository, supporting various commit types and options. |
|
|
112
|
+
| [`push`](CLI-HELP.md#underpost-push) | Pushes committed changes from a local repository to a remote GitHub repository. |
|
|
113
|
+
| [`env`](CLI-HELP.md#underpost-env) | Sets environment variables and configurations related to a specific deployment ID. |
|
|
114
|
+
| [`static`](CLI-HELP.md#underpost-static) | Manages static build of page, bundles, and documentation with comprehensive customization options. |
|
|
115
|
+
| [`config`](CLI-HELP.md#underpost-config) | Manages Underpost configurations using various operators. |
|
|
116
|
+
| [`root`](CLI-HELP.md#underpost-root) | Displays the root path of the npm installation. |
|
|
117
|
+
| [`ip`](CLI-HELP.md#underpost-ip) | Displays the current public machine IP addresses. |
|
|
118
|
+
| [`cluster`](CLI-HELP.md#underpost-cluster) | Manages Kubernetes clusters, defaulting to Kind cluster initialization. |
|
|
119
|
+
| [`deploy`](CLI-HELP.md#underpost-deploy) | Manages application deployments, defaulting to deploying development pods. |
|
|
120
|
+
| [`secret`](CLI-HELP.md#underpost-secret) | Manages secrets for various platforms. |
|
|
121
|
+
| [`image`](CLI-HELP.md#underpost-image) | Manages Docker images, including building, saving, and loading into Kubernetes clusters. |
|
|
122
|
+
| [`install`](CLI-HELP.md#underpost-install) | Quickly imports Underpost npm dependencies by copying them. |
|
|
123
|
+
| [`db`](CLI-HELP.md#underpost-db) | Manages database operations with support for MariaDB and MongoDB, including import/export, multi-pod targeting, and Git integration. |
|
|
124
|
+
| [`metadata`](CLI-HELP.md#underpost-metadata) | Manages cluster metadata operations, including import and export. |
|
|
125
|
+
| [`cron`](CLI-HELP.md#underpost-cron) | Manages cron jobs: execute jobs directly or generate and apply K8s CronJob manifests. |
|
|
126
|
+
| [`fs`](CLI-HELP.md#underpost-fs) | Manages file storage, defaulting to file upload operations. |
|
|
127
|
+
| [`test`](CLI-HELP.md#underpost-test) | Manages and runs tests, defaulting to the current Underpost default test suite. |
|
|
128
|
+
| [`monitor`](CLI-HELP.md#underpost-monitor) | Manages health server monitoring for specified deployments. |
|
|
129
|
+
| [`ssh`](CLI-HELP.md#underpost-ssh) | Manages SSH credentials and sessions for remote access to cluster nodes or services. |
|
|
130
|
+
| [`run`](CLI-HELP.md#underpost-run) | Runs specified scripts using various runners. |
|
|
131
|
+
| [`lxd`](CLI-HELP.md#underpost-lxd) | Manages LXD virtual machines as K3s nodes (control plane or workers). |
|
|
132
|
+
| [`baremetal`](CLI-HELP.md#underpost-baremetal) | Manages baremetal server operations, including installation, database setup, commissioning, and user management. |
|
|
133
|
+
| [`release`](CLI-HELP.md#underpost-release) | Release orchestrator for building new versions and deploying releases of the Underpost CLI. |
|
|
134
|
+
|
|
129
135
|
<!-- cli-index-end -->
|
|
130
136
|
|
|
131
137
|
<a target="_top" href="https://github.com/underpostnet/pwa-microservices-template/blob/master/CLI-HELP.md">See CLI Docs.</a>
|
package/bin/build.js
CHANGED
|
@@ -1,105 +1,64 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander';
|
|
1
4
|
import fs from 'fs-extra';
|
|
2
|
-
import { loggerFactory } from '../src/server/logger.js';
|
|
3
|
-
import { shellExec } from '../src/server/process.js';
|
|
4
5
|
import dotenv from 'dotenv';
|
|
6
|
+
import { loggerFactory } from '../src/server/logger.js';
|
|
5
7
|
import { getCapVariableName } from '../src/client/components/core/CommonJs.js';
|
|
6
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
getPathsSSR,
|
|
10
|
+
resolveDeployList,
|
|
11
|
+
syncPrivateConf,
|
|
12
|
+
syncDeployIdSources,
|
|
13
|
+
buildTemplate,
|
|
14
|
+
} from '../src/server/conf.js';
|
|
15
|
+
import { loadDeployCatalog } from '../src/server/catalog.js';
|
|
16
|
+
import UnderpostRepository from '../src/cli/repository.js';
|
|
7
17
|
|
|
8
18
|
const baseConfPath = './engine-private/conf/dd-cron/.env.production';
|
|
9
19
|
if (fs.existsSync(baseConfPath)) dotenv.config({ path: baseConfPath, override: true });
|
|
10
20
|
|
|
11
21
|
const logger = loggerFactory(import.meta);
|
|
12
22
|
|
|
13
|
-
const confName = process.argv[2];
|
|
14
23
|
const basePath = '../pwa-microservices-template';
|
|
15
|
-
const repoName = `engine-${confName.split('dd-')[1]}`;
|
|
16
|
-
const deployList = (confName === 'dd' ? fs.readFileSync(`./engine-private/deploy/dd.router`, 'utf8') : confName).split(
|
|
17
|
-
',',
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
logger.info('Build repository', {
|
|
21
|
-
confName,
|
|
22
|
-
repoName,
|
|
23
|
-
basePath,
|
|
24
|
-
deployList,
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
if (process.argv.includes('conf')) {
|
|
28
|
-
for (const _confName of deployList) {
|
|
29
|
-
const _repoName = `engine-${_confName.split('dd-')[1]}`;
|
|
30
|
-
const privateRepoName = `${_repoName}-private`;
|
|
31
|
-
const privateGitUri = `${process.env.GITHUB_USERNAME}/${privateRepoName}`;
|
|
32
|
-
|
|
33
|
-
if (!fs.existsSync(`../${privateRepoName}`)) {
|
|
34
|
-
shellExec(`cd .. && underpost clone ${privateGitUri}`, { silent: true });
|
|
35
|
-
} else {
|
|
36
|
-
shellExec(`cd ../${privateRepoName} && git checkout . && git clean -f -d && underpost pull . ${privateGitUri}`, {
|
|
37
|
-
silent: true,
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
const toPath = `../${privateRepoName}/conf/${_confName}`;
|
|
41
|
-
fs.removeSync(toPath);
|
|
42
|
-
fs.mkdirSync(toPath, { recursive: true });
|
|
43
|
-
fs.copySync(`./engine-private/conf/${_confName}`, toPath);
|
|
44
|
-
fs.removeSync(`../${privateRepoName}/replica`);
|
|
45
|
-
if (fs.existsSync(`./engine-private/replica`)) {
|
|
46
|
-
const replicas = await fs.readdir(`./engine-private/replica`);
|
|
47
|
-
for (const replica of replicas)
|
|
48
|
-
if (replica.match(_confName))
|
|
49
|
-
fs.copySync(`./engine-private/replica/${replica}`, `../${privateRepoName}/replica/${replica}`);
|
|
50
|
-
}
|
|
51
24
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
shellExec(
|
|
66
|
-
`cd ../${privateRepoName}` +
|
|
67
|
-
` && git add .` +
|
|
68
|
-
` && underpost cmt . ci engine-core-conf 'Update ${_confName} conf'` +
|
|
69
|
-
` && underpost push . ${privateGitUri}`,
|
|
70
|
-
{
|
|
71
|
-
silent: true,
|
|
72
|
-
silentOnError: true,
|
|
73
|
-
},
|
|
74
|
-
);
|
|
25
|
+
/**
|
|
26
|
+
* Assembles a single deploy id's public template under {@link basePath}: pulls in
|
|
27
|
+
* its deploy-id-specific public sources, then mirrors the APIs, client components,
|
|
28
|
+
* SSR assets, manifests, and packaging declared by its conf into the template repo.
|
|
29
|
+
* @param {string} confName - A concrete deploy id (e.g. `dd-prototype`).
|
|
30
|
+
*/
|
|
31
|
+
const buildDeployTemplate = async (confName) => {
|
|
32
|
+
const repoName = `engine-${confName.split('dd-')[1]}`;
|
|
33
|
+
const catalog = await loadDeployCatalog(confName);
|
|
34
|
+
|
|
35
|
+
if (catalog.sourceMoves.length) {
|
|
36
|
+
UnderpostRepository.API.sparseCheckoutDirectory(`conf/${confName}`);
|
|
37
|
+
if (catalog.sourceMoves.some(([src]) => !fs.existsSync(src))) UnderpostRepository.API.pullSourceRepo(repoName);
|
|
75
38
|
}
|
|
76
|
-
|
|
77
|
-
}
|
|
39
|
+
syncDeployIdSources(catalog.sourceMoves);
|
|
78
40
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
41
|
+
const confDir = `./engine-private/conf/${confName}`;
|
|
42
|
+
const DefaultConf = {
|
|
43
|
+
server: JSON.parse(fs.readFileSync(`${confDir}/conf.server.json`, 'utf8')),
|
|
44
|
+
client: JSON.parse(fs.readFileSync(`${confDir}/conf.client.json`, 'utf8')),
|
|
45
|
+
ssr: JSON.parse(fs.readFileSync(`${confDir}/conf.ssr.json`, 'utf8')),
|
|
46
|
+
};
|
|
85
47
|
|
|
86
|
-
const { DefaultConf } = await import(`../conf.${confName}.js`);
|
|
87
|
-
|
|
88
|
-
{
|
|
89
48
|
for (const host of Object.keys(DefaultConf.server)) {
|
|
90
49
|
for (const path of Object.keys(DefaultConf.server[host])) {
|
|
91
50
|
const { apis, ws } = DefaultConf.server[host][path];
|
|
92
51
|
if (apis)
|
|
93
52
|
for (const api of apis) {
|
|
94
|
-
{
|
|
95
|
-
|
|
96
|
-
logger.info(`Build`,
|
|
97
|
-
fs.copySync(
|
|
53
|
+
const apiSrc = `./src/api/${api}`;
|
|
54
|
+
if (fs.existsSync(apiSrc)) {
|
|
55
|
+
logger.info(`Build`, apiSrc);
|
|
56
|
+
fs.copySync(apiSrc, `${basePath}/src/api/${api}`);
|
|
98
57
|
}
|
|
99
|
-
{
|
|
100
|
-
|
|
101
|
-
logger.info(`Build`,
|
|
102
|
-
fs.copySync(
|
|
58
|
+
const serviceSrc = `./src/client/services/${api}`;
|
|
59
|
+
if (fs.existsSync(serviceSrc)) {
|
|
60
|
+
logger.info(`Build`, serviceSrc);
|
|
61
|
+
fs.copySync(serviceSrc, `${basePath}/src/client/services/${api}`);
|
|
103
62
|
}
|
|
104
63
|
}
|
|
105
64
|
|
|
@@ -108,9 +67,7 @@ const { DefaultConf } = await import(`../conf.${confName}.js`);
|
|
|
108
67
|
}
|
|
109
68
|
}
|
|
110
69
|
}
|
|
111
|
-
}
|
|
112
70
|
|
|
113
|
-
{
|
|
114
71
|
for (const client of Object.keys(DefaultConf.client)) {
|
|
115
72
|
const capName = getCapVariableName(client);
|
|
116
73
|
for (const component of Object.keys(DefaultConf.client[client].components)) {
|
|
@@ -135,9 +92,7 @@ const { DefaultConf } = await import(`../conf.${confName}.js`);
|
|
|
135
92
|
}
|
|
136
93
|
}
|
|
137
94
|
}
|
|
138
|
-
}
|
|
139
95
|
|
|
140
|
-
{
|
|
141
96
|
for (const client of Object.keys(DefaultConf.ssr)) {
|
|
142
97
|
const ssrPaths = getPathsSSR(DefaultConf.ssr[client]);
|
|
143
98
|
for (const originPath of ssrPaths) {
|
|
@@ -149,16 +104,14 @@ const { DefaultConf } = await import(`../conf.${confName}.js`);
|
|
|
149
104
|
}
|
|
150
105
|
|
|
151
106
|
if (!fs.existsSync(`${basePath}/.github/workflows`))
|
|
152
|
-
fs.mkdirSync(`${basePath}/.github/workflows`, {
|
|
153
|
-
recursive: true,
|
|
154
|
-
});
|
|
107
|
+
fs.mkdirSync(`${basePath}/.github/workflows`, { recursive: true });
|
|
155
108
|
|
|
156
109
|
const originPackageJson = JSON.parse(fs.readFileSync(`./package.json`, 'utf8'));
|
|
157
110
|
const packageJson = JSON.parse(fs.readFileSync(`${basePath}/package.json`, 'utf8'));
|
|
158
111
|
packageJson.name = repoName.replace('engine-', '');
|
|
159
112
|
|
|
160
113
|
switch (confName) {
|
|
161
|
-
case 'dd-cyberia':
|
|
114
|
+
case 'dd-cyberia': {
|
|
162
115
|
fs.copyFileSync(`./bin/cyberia.js`, `${basePath}/bin/cyberia.js`);
|
|
163
116
|
fs.copyFileSync(
|
|
164
117
|
`./.github/workflows/publish.cyberia.ci.yml`,
|
|
@@ -167,59 +120,24 @@ const { DefaultConf } = await import(`../conf.${confName}.js`);
|
|
|
167
120
|
if (packageJson.bin) delete packageJson.bin.underpost;
|
|
168
121
|
if (!packageJson.bin) packageJson.bin = {};
|
|
169
122
|
packageJson.bin.cyberia = 'bin/index.js';
|
|
170
|
-
packageJson.keywords =
|
|
171
|
-
|
|
172
|
-
'cyberia-cli',
|
|
173
|
-
'engine-cyberia',
|
|
174
|
-
'sidecar',
|
|
175
|
-
'data-layer',
|
|
176
|
-
'engine-cyberia',
|
|
177
|
-
'object-layer',
|
|
178
|
-
'atlas-sprite-sheet',
|
|
179
|
-
'ipfs',
|
|
180
|
-
'erc-1155',
|
|
181
|
-
'object-layer-token',
|
|
182
|
-
'hardhat',
|
|
183
|
-
'hyperledger-besu',
|
|
184
|
-
'blockchain',
|
|
185
|
-
'web3',
|
|
186
|
-
'underpost-platform',
|
|
187
|
-
'mmorpg',
|
|
188
|
-
];
|
|
189
|
-
packageJson.description =
|
|
190
|
-
'Cyberia CLI — toolchain for the Cyberia MMO data layer, content pipeline, persistence, gRPC services, and ERC-1155 lifecycle on Hyperledger Besu.';
|
|
123
|
+
packageJson.keywords = catalog.keywords;
|
|
124
|
+
packageJson.description = catalog.description;
|
|
191
125
|
const { CyberiaDependencies } = await import(`../src/api/cyberia-server-defaults/cyberia-server-defaults.js`);
|
|
192
126
|
packageJson.dependencies = {
|
|
193
127
|
...originPackageJson.dependencies,
|
|
194
128
|
...CyberiaDependencies,
|
|
195
129
|
};
|
|
196
130
|
fs.writeFileSync(`${basePath}/bin/index.js`, fs.readFileSync(`./bin/cyberia.js`, 'utf8'), 'utf8');
|
|
131
|
+
// Canonical Cyberia doc; engine-cyberia/README.md is a generated copy — never hand-edited.
|
|
197
132
|
fs.writeFileSync(
|
|
198
133
|
`${basePath}/README.md`,
|
|
199
|
-
fs.readFileSync(`./src/client/public/cyberia-docs/CYBERIA
|
|
134
|
+
fs.readFileSync(`./src/client/public/cyberia-docs/CYBERIA.md`, 'utf8'),
|
|
200
135
|
'utf8',
|
|
201
136
|
);
|
|
202
137
|
fs.copySync(`./hardhat`, `${basePath}/hardhat`);
|
|
203
|
-
for (const path of
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
'/src/server/object-layer.js',
|
|
207
|
-
'/src/server/atlas-sprite-sheet-generator.js',
|
|
208
|
-
'/src/server/shape-generator.js',
|
|
209
|
-
'/src/server/semantic-layer-generator.js',
|
|
210
|
-
'/src/server/semantic-layer-generator-floor.js',
|
|
211
|
-
'/src/server/semantic-layer-generator-skin.js',
|
|
212
|
-
'/src/server/semantic-layer-generator-resource.js',
|
|
213
|
-
'/test/shape-generator.test.js',
|
|
214
|
-
'/src/server/besu-genesis-generator.js',
|
|
215
|
-
'/src/runtime/cyberia-server',
|
|
216
|
-
'/src/runtime/cyberia-client',
|
|
217
|
-
'/.github/workflows/hardhat.ci.yml',
|
|
218
|
-
'/src/client/public/cyberia-docs',
|
|
219
|
-
'/src/api/cyberia-server-defaults',
|
|
220
|
-
])
|
|
221
|
-
fs.copySync(`.${path}`, `${basePath}${path}`);
|
|
222
|
-
|
|
138
|
+
for (const path of catalog.templatePaths) fs.copySync(`.${path}`, `${basePath}${path}`);
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
223
141
|
default:
|
|
224
142
|
break;
|
|
225
143
|
}
|
|
@@ -247,8 +165,6 @@ const { DefaultConf } = await import(`../conf.${confName}.js`);
|
|
|
247
165
|
`${basePath}/manifests/deployment/${confName}-development`,
|
|
248
166
|
);
|
|
249
167
|
|
|
250
|
-
// Copy conf.<deploy-id>.js to conf.js for the respective deployment
|
|
251
|
-
fs.copyFileSync(`./conf.${confName}.js`, `${basePath}/conf.js`);
|
|
252
168
|
fs.copyFileSync(`./manifests/deployment/${confName}-development/proxy.yaml`, `${basePath}/proxy.yaml`);
|
|
253
169
|
fs.copyFileSync(`./manifests/deployment/${confName}-development/deployment.yaml`, `${basePath}/deployment.yaml`);
|
|
254
170
|
const pvPvcPath = `./manifests/deployment/${confName}-development/pv-pvc.yaml`;
|
|
@@ -257,6 +173,41 @@ const { DefaultConf } = await import(`../conf.${confName}.js`);
|
|
|
257
173
|
if (fs.existsSync(`./src/ws/${confName.split('-')[1]}`)) {
|
|
258
174
|
fs.copySync(`./src/ws/${confName.split('-')[1]}`, `${basePath}/src/ws/${confName.split('-')[1]}`);
|
|
259
175
|
}
|
|
260
|
-
fs.
|
|
261
|
-
|
|
262
|
-
|
|
176
|
+
fs.writeFileSync(
|
|
177
|
+
`${basePath}/.gitignore`,
|
|
178
|
+
fs.readFileSync(`.gitignore`, 'utf8').split('# Ignore ERP / CRM custom prototypes src')[0],
|
|
179
|
+
);
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
const program = new Command();
|
|
183
|
+
|
|
184
|
+
program
|
|
185
|
+
.name('build')
|
|
186
|
+
.description('Assemble deploy id public templates and sync their private configuration repos.')
|
|
187
|
+
.argument('<conf-name>', 'Deploy id, comma-separated list, or the "dd" meta id (fans out via dd.router).')
|
|
188
|
+
.argument('[env]', 'Environment label (informational; kept for CI invocation compatibility).')
|
|
189
|
+
.option('--conf', 'Sync each deploy id private configuration repo and exit (no template assembly).')
|
|
190
|
+
.option(
|
|
191
|
+
'--no-template-rebuild',
|
|
192
|
+
'Skip the from-scratch base template reconstruction before assembly (assemble onto the existing template).',
|
|
193
|
+
)
|
|
194
|
+
.action(async (confName, env, options) => {
|
|
195
|
+
const deployList = resolveDeployList(confName);
|
|
196
|
+
logger.info('Build repository', { confName, basePath, deployList, conf: !!options.conf });
|
|
197
|
+
|
|
198
|
+
if (options.conf) {
|
|
199
|
+
for (const deployId of deployList) {
|
|
200
|
+
const { privateConfPaths } = await loadDeployCatalog(deployId);
|
|
201
|
+
syncPrivateConf(deployId, privateConfPaths);
|
|
202
|
+
}
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Reconstruct the base template from 0 before assembly so no src from a previous
|
|
207
|
+
// build run leaks into this one. Opt out with --no-template-rebuild.
|
|
208
|
+
if (options.templateRebuild) await buildTemplate({ toPath: basePath });
|
|
209
|
+
|
|
210
|
+
for (const deployId of deployList) await buildDeployTemplate(deployId);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
await program.parseAsync();
|
package/bin/build.template.js
CHANGED
|
@@ -1,187 +1,33 @@
|
|
|
1
|
-
|
|
1
|
+
#! /usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import { shellExec } from '../src/server/process.js';
|
|
6
|
-
import walk from 'ignore-walk';
|
|
7
|
-
import { validateTemplatePath } from '../src/server/conf.js';
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import fs from 'fs-extra';
|
|
8
5
|
import dotenv from 'dotenv';
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
import { loggerFactory } from '../src/server/logger.js';
|
|
7
|
+
import { buildTemplate, updatePrivateTemplateRepo } from '../src/server/conf.js';
|
|
11
8
|
|
|
12
9
|
if (fs.existsSync('./engine-private/conf/dd-cron/.env.production'))
|
|
13
|
-
dotenv.config({
|
|
14
|
-
path: `./engine-private/conf/dd-cron/.env.production`,
|
|
15
|
-
override: true,
|
|
16
|
-
});
|
|
10
|
+
dotenv.config({ path: `./engine-private/conf/dd-cron/.env.production`, override: true });
|
|
17
11
|
else dotenv.config();
|
|
18
12
|
|
|
19
|
-
|
|
20
|
-
const TEMPLATE_DELETE_PATHS = [
|
|
21
|
-
'./.github',
|
|
22
|
-
'./manifests/deployment/dd-lampp-development',
|
|
23
|
-
'./manifests/deployment/dd-cyberia-development',
|
|
24
|
-
'./manifests/deployment/dd-core-development',
|
|
25
|
-
'./manifests/deployment/dd-template-development',
|
|
26
|
-
'./src/server/object-layer.js',
|
|
27
|
-
'./src/server/atlas-sprite-sheet-generator.js',
|
|
28
|
-
'./src/server/shape-generator.js',
|
|
29
|
-
'./src/server/semantic-layer-generator.js',
|
|
30
|
-
'./src/server/semantic-layer-generator-floor.js',
|
|
31
|
-
'./src/server/semantic-layer-generator-skin.js',
|
|
32
|
-
'./src/server/semantic-layer-generator-resource.js',
|
|
33
|
-
'./src/server/besu-genesis-generator.js',
|
|
34
|
-
'./src/grpc/cyberia',
|
|
35
|
-
'./src/runtime/cyberia-server',
|
|
36
|
-
'./src/runtime/cyberia-client',
|
|
37
|
-
'./test/shape-generator.test.js',
|
|
38
|
-
'./src/client/public/cyberia-docs',
|
|
39
|
-
'bin/cyberia.js',
|
|
40
|
-
'./hardhat',
|
|
41
|
-
];
|
|
42
|
-
|
|
43
|
-
// Workflow + service files re-added to the template after the engine-only strip above.
|
|
44
|
-
const TEMPLATE_RESTORE_PATHS = [
|
|
45
|
-
`./.github/workflows/pwa-microservices-template-page.cd.yml`,
|
|
46
|
-
`./.github/workflows/pwa-microservices-template-test.ci.yml`,
|
|
47
|
-
`./.github/workflows/npmpkg.ci.yml`,
|
|
48
|
-
`./.github/workflows/ghpkg.ci.yml`,
|
|
49
|
-
`./.github/workflows/gitlab.ci.yml`,
|
|
50
|
-
`./.github/workflows/publish.ci.yml`,
|
|
51
|
-
`./.github/workflows/release.cd.yml`,
|
|
52
|
-
`./src/client/services/user/guest.service.js`,
|
|
53
|
-
'./src/api/user/guest.service.js',
|
|
54
|
-
'./src/ws/IoInterface.js',
|
|
55
|
-
'./src/ws/IoServer.js',
|
|
56
|
-
];
|
|
57
|
-
|
|
58
|
-
const TEMPLATE_KEYWORDS = [
|
|
59
|
-
'underpost',
|
|
60
|
-
'underpost-platform',
|
|
61
|
-
'cli',
|
|
62
|
-
'toolchain',
|
|
63
|
-
'ci-cd',
|
|
64
|
-
'devops',
|
|
65
|
-
'kubernetes',
|
|
66
|
-
'k3s',
|
|
67
|
-
'kubeadm',
|
|
68
|
-
'lxd',
|
|
69
|
-
'bare-metal',
|
|
70
|
-
'container-orchestration',
|
|
71
|
-
'image-management',
|
|
72
|
-
'pwa',
|
|
73
|
-
'workbox',
|
|
74
|
-
'microservices',
|
|
75
|
-
];
|
|
76
|
-
|
|
77
|
-
const TEMPLATE_DESCRIPTION =
|
|
78
|
-
'Underpost Platform — end-to-end CI/CD and application-delivery toolchain CLI. Covers bare metal, Kubernetes, K3s, kubeadm, LXD, container/image orchestration, secrets, databases, cron jobs, monitoring, SSH, runners, PWA + Workbox delivery, and release orchestration. Extensible via downstream CLIs.';
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Builds the pwa-microservices-template from scratch out of the current engine source tree.
|
|
82
|
-
*
|
|
83
|
-
* Clones (or resets) the template repo next to the engine, syncs every engine-tracked file the
|
|
84
|
-
* template is allowed to carry (validateTemplatePath), strips engine-only modules, restores the
|
|
85
|
-
* template's own CI workflows + guest services, and rewrites package.json / package-lock.json /
|
|
86
|
-
* README so the template is a standalone, installable project.
|
|
87
|
-
*
|
|
88
|
-
* Usage: node bin/build.template [srcPath=./] [toPath=../pwa-microservices-template]
|
|
89
|
-
*/
|
|
90
|
-
const srcPath = (process.argv[2] ?? './').replaceAll(`'`, '');
|
|
91
|
-
const toPath = (process.argv[3] ?? '../pwa-microservices-template').replaceAll(`'`, '');
|
|
92
|
-
const githubUsername = process.env.GITHUB_USERNAME;
|
|
93
|
-
|
|
94
|
-
logger.info('Build template', { srcPath, toPath });
|
|
95
|
-
|
|
96
|
-
try {
|
|
97
|
-
const sourceFiles = (
|
|
98
|
-
await new Promise((resolve) =>
|
|
99
|
-
walk(
|
|
100
|
-
{
|
|
101
|
-
path: srcPath,
|
|
102
|
-
ignoreFiles: [`.gitignore`],
|
|
103
|
-
includeEmpty: false,
|
|
104
|
-
follow: false,
|
|
105
|
-
},
|
|
106
|
-
(...args) => resolve(args[1]),
|
|
107
|
-
),
|
|
108
|
-
)
|
|
109
|
-
).filter((p) => !p.startsWith('.git'));
|
|
110
|
-
|
|
111
|
-
// Clone the template from 0 if missing; otherwise reset it to a clean pristine checkout.
|
|
112
|
-
if (!fs.existsSync(toPath)) {
|
|
113
|
-
shellExec(`cd .. && node engine/bin clone ${githubUsername}/pwa-microservices-template`);
|
|
114
|
-
} else {
|
|
115
|
-
shellExec(`cd ${toPath} && git reset && git checkout . && git clean -f -d`);
|
|
116
|
-
shellExec(`node bin pull ${toPath} ${githubUsername}/pwa-microservices-template`);
|
|
117
|
-
shellExec(`sudo rm -rf ${toPath}/engine-private`);
|
|
118
|
-
shellExec(`sudo rm -rf ${toPath}/logs`);
|
|
119
|
-
}
|
|
120
|
-
shellExec(`cd ${toPath} && git config core.filemode false`);
|
|
121
|
-
|
|
122
|
-
for (const copyPath of sourceFiles) {
|
|
123
|
-
if (copyPath === 'NaN') continue;
|
|
124
|
-
const absolutePath = `${srcPath}/${copyPath}`;
|
|
125
|
-
if (!validateTemplatePath(absolutePath)) continue;
|
|
126
|
-
|
|
127
|
-
const folder = getDirname(`${toPath}/${copyPath}`);
|
|
128
|
-
if (!fs.existsSync(folder)) fs.mkdirSync(folder, { recursive: true });
|
|
129
|
-
|
|
130
|
-
logger.info('build', `${toPath}/${copyPath}`);
|
|
131
|
-
fs.copyFileSync(absolutePath, `${toPath}/${copyPath}`);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
fs.copySync(`./.vscode`, `${toPath}/.vscode`);
|
|
135
|
-
fs.copySync(`./src/client/public/default`, `${toPath}/src/client/public/default`);
|
|
136
|
-
|
|
137
|
-
// Preserve the template's own README + package.json identity before merging engine metadata.
|
|
138
|
-
for (const checkoutPath of ['README.md', 'package.json']) shellExec(`cd ${toPath} && git checkout ${checkoutPath}`);
|
|
139
|
-
|
|
140
|
-
for (const deletePath of TEMPLATE_DELETE_PATHS) {
|
|
141
|
-
const target = `${toPath}/${deletePath}`;
|
|
142
|
-
if (fs.existsSync(target)) fs.removeSync(target);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
fs.mkdirSync(`${toPath}/.github/workflows`, { recursive: true });
|
|
146
|
-
for (const restorePath of TEMPLATE_RESTORE_PATHS) fs.copyFileSync(restorePath, `${toPath}/${restorePath}`);
|
|
147
|
-
|
|
148
|
-
// ── package.json: take engine deps/scripts/version, keep template identity. ──
|
|
149
|
-
const originPackageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
|
|
150
|
-
const templatePackageJson = JSON.parse(fs.readFileSync(`${toPath}/package.json`, 'utf8'));
|
|
151
|
-
const templateName = templatePackageJson.name;
|
|
152
|
-
|
|
153
|
-
templatePackageJson.dependencies = originPackageJson.dependencies;
|
|
154
|
-
templatePackageJson.devDependencies = originPackageJson.devDependencies;
|
|
155
|
-
templatePackageJson.version = originPackageJson.version;
|
|
156
|
-
templatePackageJson.scripts = originPackageJson.scripts;
|
|
157
|
-
templatePackageJson.overrides = originPackageJson.overrides;
|
|
158
|
-
templatePackageJson.name = templateName;
|
|
159
|
-
templatePackageJson.description = TEMPLATE_DESCRIPTION;
|
|
160
|
-
templatePackageJson.keywords = uniqueArray(TEMPLATE_KEYWORDS.concat(templatePackageJson.keywords || []));
|
|
161
|
-
delete templatePackageJson.scripts['update:template'];
|
|
162
|
-
fs.writeFileSync(`${toPath}/package.json`, JSON.stringify(templatePackageJson, null, 4), 'utf8');
|
|
13
|
+
const logger = loggerFactory(import.meta);
|
|
163
14
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
15
|
+
const program = new Command();
|
|
16
|
+
|
|
17
|
+
program
|
|
18
|
+
.name('build.template')
|
|
19
|
+
.description('Rebuild the standalone pwa-microservices-template from scratch out of the engine source tree.')
|
|
20
|
+
.argument('[src-path]', 'Engine source root to sync from.', './')
|
|
21
|
+
.argument('[to-path]', 'Template output path.', '../pwa-microservices-template')
|
|
22
|
+
.option('--update-private', 'Update private template repository', false)
|
|
23
|
+
.action(async (srcPath, toPath, options) => {
|
|
24
|
+
try {
|
|
25
|
+
if (options.updatePrivate) return await updatePrivateTemplateRepo();
|
|
26
|
+
await buildTemplate({ srcPath: srcPath.replaceAll(`'`, ''), toPath: toPath.replaceAll(`'`, '') });
|
|
27
|
+
} catch (error) {
|
|
28
|
+
logger.error(error, error.stack);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
176
32
|
|
|
177
|
-
|
|
178
|
-
`${toPath}/README.md`,
|
|
179
|
-
fs
|
|
180
|
-
.readFileSync('./README.md', 'utf8')
|
|
181
|
-
.replace('<!-- template-title -->', '#### Base template for pwa/api-rest projects.'),
|
|
182
|
-
'utf8',
|
|
183
|
-
);
|
|
184
|
-
} catch (error) {
|
|
185
|
-
logger.error(error, error.stack);
|
|
186
|
-
process.exit(1);
|
|
187
|
-
}
|
|
33
|
+
await program.parseAsync();
|
package/bin/deploy.js
CHANGED
|
@@ -283,7 +283,10 @@ ${shellExec(`git log | grep Author: | sort -u`, { stdout: true }).split(`\n`).jo
|
|
|
283
283
|
}
|
|
284
284
|
|
|
285
285
|
case 'cli-docs': {
|
|
286
|
-
|
|
286
|
+
const version = Underpost.version;
|
|
287
|
+
const newVersion =
|
|
288
|
+
process.argv[4] && !process.argv[4].startsWith('v') ? `v${process.argv[4]}` : process.argv[4] || version;
|
|
289
|
+
buildCliDoc(program, process.argv[3] || version, newVersion);
|
|
287
290
|
break;
|
|
288
291
|
}
|
|
289
292
|
|