cyberia 3.2.12 → 3.2.22
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/engine-cyberia.cd.yml +1 -0
- package/.github/workflows/engine-cyberia.ci.yml +14 -2
- package/.github/workflows/ghpkg.ci.yml +1 -0
- package/.github/workflows/npmpkg.ci.yml +9 -5
- package/CHANGELOG.md +151 -1
- package/CLI-HELP.md +975 -1130
- package/bin/build.js +97 -136
- package/bin/build.template.js +25 -179
- package/bin/cyberia.js +11 -6
- package/bin/deploy.js +4 -1
- package/bin/index.js +11 -6
- package/conf.js +1 -0
- package/deployment.yaml +74 -2
- package/hardhat/package-lock.json +4 -4
- package/hardhat/package.json +1 -1
- 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-cyberia-development/deployment.yaml +74 -2
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/package.json +7 -7
- package/scripts/link-local-underpost-cli.sh +6 -0
- package/scripts/test-monitor.sh +250 -0
- package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +7 -0
- package/src/cli/deploy.js +200 -282
- package/src/cli/env.js +1 -4
- package/src/cli/image.js +58 -4
- package/src/cli/index.js +47 -0
- package/src/cli/monitor.js +387 -6
- package/src/cli/release.js +26 -11
- package/src/cli/repository.js +101 -7
- package/src/cli/run.js +159 -73
- package/src/client/components/core/PanelForm.js +44 -44
- package/src/client/components/cyberia/SharedDefaultsCyberia.js +1 -1
- package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +55 -1
- package/src/client/public/cyberia-docs/ARCHITECTURE.md +272 -50
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +20 -11
- package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +23 -1
- package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
- package/src/db/mongo/MongooseDB.js +2 -1
- package/src/index.js +1 -1
- package/src/runtime/cyberia-client/Dockerfile +4 -22
- package/src/runtime/cyberia-client/Dockerfile.dev +3 -18
- package/src/runtime/cyberia-server/Dockerfile +3 -23
- package/src/runtime/cyberia-server/Dockerfile.dev +3 -27
- 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 +414 -56
- package/src/server/ipfs-client.js +5 -3
- package/src/server/runtime-status.js +235 -0
- package/src/server/start.js +32 -11
- package/test/deploy-monitor.test.js +251 -0
- package/manifests/deployment/dd-test-development/deployment.yaml +0 -256
- package/manifests/deployment/dd-test-development/proxy.yaml +0 -102
package/src/cli/release.js
CHANGED
|
@@ -264,18 +264,29 @@ const ISOLATED_ENV = 'env -i HOME="$HOME" PATH="$PATH" USER="$USER" LOGNAME="$LO
|
|
|
264
264
|
*
|
|
265
265
|
* @returns {boolean} true when the template started cleanly, false otherwise.
|
|
266
266
|
*/
|
|
267
|
-
async function buildAndTestTemplate() {
|
|
267
|
+
async function buildAndTestTemplate(opts = {}) {
|
|
268
268
|
killDevServers();
|
|
269
269
|
Underpost.repo.clean({ paths: ['/home/dd/engine', '/home/dd/engine/engine-private '] });
|
|
270
270
|
shellExec(`node bin pull . ${process.env.GITHUB_USERNAME}/engine`);
|
|
271
|
-
|
|
271
|
+
fs.removeSync(TEMPLATE_PATH);
|
|
272
|
+
shellExec(`npm run build:template`);
|
|
272
273
|
shellExec(`node bin run shared-dir ${TEMPLATE_PATH}`);
|
|
273
274
|
|
|
275
|
+
const upsertEnvVar = (content, key, value) => {
|
|
276
|
+
const re = new RegExp(`^(${key}=).*`, 'm');
|
|
277
|
+
if (re.test(content)) return content.replace(re, `$1${value}`);
|
|
278
|
+
return `${content.trimEnd()}\n${key}=${value}\n`;
|
|
279
|
+
};
|
|
280
|
+
|
|
274
281
|
const dhcpHostIp = Dns.getLocalIPv4Address();
|
|
275
282
|
logger.info(`DHCP host IP for template test: ${dhcpHostIp}`);
|
|
276
283
|
let envContent = fs.readFileSync(`${TEMPLATE_PATH}/.env.example`, 'utf8');
|
|
277
284
|
if (dhcpHostIp) envContent = envContent.replace(/127\.0\.0\.1/g, dhcpHostIp);
|
|
278
|
-
envContent = envContent
|
|
285
|
+
envContent = upsertEnvVar(envContent, 'ENABLE_FILE_LOGS', 'true');
|
|
286
|
+
if (opts.mongoHost) envContent = upsertEnvVar(envContent, 'DB_HOST', opts.mongoHost);
|
|
287
|
+
if (opts.mongoUser) envContent = upsertEnvVar(envContent, 'DB_USER', opts.mongoUser);
|
|
288
|
+
if (opts.mongoPassword) envContent = upsertEnvVar(envContent, 'DB_PASSWORD', opts.mongoPassword);
|
|
289
|
+
if (opts.valkeyHost) envContent = upsertEnvVar(envContent, 'VALKEY_HOST', opts.valkeyHost);
|
|
279
290
|
// fs.writeFileSync(`${TEMPLATE_PATH}/.env`, envContent, 'utf8');
|
|
280
291
|
fs.writeFileSync(`${TEMPLATE_PATH}/.env.example`, envContent, 'utf8');
|
|
281
292
|
shellExec(`cd ${TEMPLATE_PATH} && npm install`);
|
|
@@ -337,7 +348,12 @@ class UnderpostRelease {
|
|
|
337
348
|
*
|
|
338
349
|
* @method build
|
|
339
350
|
* @param {string} [newVersion] - The new version string to set. Defaults to current version if not provided.
|
|
340
|
-
* @param {{dryRun?: boolean}} [options] - Commander options.
|
|
351
|
+
* @param {{dryRun?: boolean, mongoHost?: string, mongoUser?: string, mongoPassword?: string, valkeyHost?: string}} [options] - Commander options.
|
|
352
|
+
* `--dry-run` previews changes without writing files.
|
|
353
|
+
* `--mongo-host` overrides `DB_HOST` in the template `.env.example` smoke test.
|
|
354
|
+
* `--mongo-user` overrides `DB_USER` in the template `.env.example` smoke test.
|
|
355
|
+
* `--mongo-password` overrides `DB_PASSWORD` in the template `.env.example` smoke test.
|
|
356
|
+
* `--valkey-host` overrides `VALKEY_HOST` in the template `.env.example` smoke test.
|
|
341
357
|
* @memberof UnderpostRelease
|
|
342
358
|
*/
|
|
343
359
|
async build(newVersion, options = {}) {
|
|
@@ -352,7 +368,7 @@ class UnderpostRelease {
|
|
|
352
368
|
logger.info(`Release build — bumping ${version} → ${newVersion}${dryRun ? ' (dry-run)' : ''}`);
|
|
353
369
|
|
|
354
370
|
if (!dryRun) {
|
|
355
|
-
const templateOk = await buildAndTestTemplate();
|
|
371
|
+
const templateOk = await buildAndTestTemplate(options);
|
|
356
372
|
if (!templateOk) return;
|
|
357
373
|
}
|
|
358
374
|
|
|
@@ -390,9 +406,8 @@ class UnderpostRelease {
|
|
|
390
406
|
shellExec(`node bin/deploy cli-docs ${version} ${newVersion}`);
|
|
391
407
|
shellExec(`node bin/deploy update-dependencies`);
|
|
392
408
|
shellExec(`node bin/build dd`);
|
|
393
|
-
shellExec(`node bin
|
|
394
|
-
shellExec(`node bin
|
|
395
|
-
shellExec(`node bin/deploy build-default-confs`);
|
|
409
|
+
shellExec(`node bin run build-cluster-deployment-manifests`);
|
|
410
|
+
shellExec(`node bin new --default-conf --conf-workflow-id template`);
|
|
396
411
|
shellExec(`sudo rm -rf ./engine-private/conf/dd-default`);
|
|
397
412
|
shellExec(`node bin new --deploy-id dd-default`);
|
|
398
413
|
console.log(fs.existsSync(`./engine-private/conf/dd-default`));
|
|
@@ -460,7 +475,7 @@ class UnderpostRelease {
|
|
|
460
475
|
* Runs the pwa-microservices-template update and push flow locally.
|
|
461
476
|
*
|
|
462
477
|
* Always removes and re-clones pwa-microservices-template, then:
|
|
463
|
-
* 1. Runs
|
|
478
|
+
* 1. Runs build:template (node bin/build.template) to sync engine sources.
|
|
464
479
|
* 2. Installs dependencies and builds the template.
|
|
465
480
|
* 3. Commits and pushes to the pwa-microservices-template remote repository.
|
|
466
481
|
*
|
|
@@ -488,7 +503,7 @@ class UnderpostRelease {
|
|
|
488
503
|
shellExec(`sudo rm -rf /home/dd/pwa-microservices-template`);
|
|
489
504
|
shellExec(`node engine/bin clone ${githubOrg}/pwa-microservices-template`);
|
|
490
505
|
shellCd('/home/dd/engine');
|
|
491
|
-
shellExec(`npm run
|
|
506
|
+
shellExec(`npm run build:template`);
|
|
492
507
|
shellExec(`cd ../pwa-microservices-template && npm install && npm run build`);
|
|
493
508
|
shellCd('/home/dd/pwa-microservices-template');
|
|
494
509
|
shellExec(`git add .`);
|
|
@@ -520,7 +535,7 @@ class UnderpostRelease {
|
|
|
520
535
|
shellExec(
|
|
521
536
|
`node bin secret underpost --create-from-file /home/dd/engine/engine-private/conf/dd-cron/.env.production`,
|
|
522
537
|
);
|
|
523
|
-
shellExec(`node bin/build dd conf`);
|
|
538
|
+
shellExec(`node bin/build dd --conf`);
|
|
524
539
|
shellExec(`git add . && cd ./engine-private && git add .`);
|
|
525
540
|
shellExec(`node bin cmt . ci package-pwa-microservices-template 'New release v:${version}'`);
|
|
526
541
|
shellExec(`node bin cmt ./engine-private ci package-pwa-microservices-template`);
|
package/src/cli/repository.js
CHANGED
|
@@ -8,6 +8,7 @@ import dotenv from 'dotenv';
|
|
|
8
8
|
import { commitData } from '../client/components/core/CommonJs.js';
|
|
9
9
|
import { pbcopy, shellCd, shellExec } from '../server/process.js';
|
|
10
10
|
import { actionInitLog, loggerFactory } from '../server/logger.js';
|
|
11
|
+
import path from 'path';
|
|
11
12
|
import fs from 'fs-extra';
|
|
12
13
|
import {
|
|
13
14
|
getNpmRootPath,
|
|
@@ -133,10 +134,21 @@ class UnderpostRepository {
|
|
|
133
134
|
p: undefined,
|
|
134
135
|
bc: '',
|
|
135
136
|
isRemoteRepo: '',
|
|
137
|
+
hasChanges: false,
|
|
136
138
|
},
|
|
137
139
|
) {
|
|
138
140
|
if (!repoPath) repoPath = '.';
|
|
139
141
|
|
|
142
|
+
if (options.hasChanges) {
|
|
143
|
+
const status = shellExec(`cd ${repoPath} && git status --porcelain`, {
|
|
144
|
+
stdout: true,
|
|
145
|
+
silent: true,
|
|
146
|
+
disableLog: true,
|
|
147
|
+
}).trim();
|
|
148
|
+
process.stdout.write(status ? '1' : '');
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
140
152
|
if (options.isRemoteRepo) {
|
|
141
153
|
const accessible = Underpost.repo.isRemoteRepo(options.isRemoteRepo);
|
|
142
154
|
console.log(accessible);
|
|
@@ -556,7 +568,7 @@ class UnderpostRepository {
|
|
|
556
568
|
// Handle sync-conf operation
|
|
557
569
|
if (options.syncConf) {
|
|
558
570
|
logger.info(`Syncing configuration for deploy ID: ${deployId}`);
|
|
559
|
-
shellExec(`node bin/build ${deployId} conf`);
|
|
571
|
+
shellExec(`node bin/build ${deployId} --conf`);
|
|
560
572
|
logger.info('Configuration synced successfully');
|
|
561
573
|
return resolve(true);
|
|
562
574
|
}
|
|
@@ -608,7 +620,8 @@ class UnderpostRepository {
|
|
|
608
620
|
const npmRoot = getNpmRootPath();
|
|
609
621
|
const underpostRoot = options?.dev === true ? '.' : `${npmRoot}/underpost`;
|
|
610
622
|
const destFolder = `./${projectName}`;
|
|
611
|
-
|
|
623
|
+
const deployId = projectName.startsWith('dd-') ? projectName : `dd-${projectName}`;
|
|
624
|
+
logger.info('build app', { destFolder, deployId });
|
|
612
625
|
if (fs.existsSync(destFolder)) fs.removeSync(destFolder);
|
|
613
626
|
fs.mkdirSync(destFolder, { recursive: true });
|
|
614
627
|
if (!options.dev) {
|
|
@@ -621,8 +634,9 @@ class UnderpostRepository {
|
|
|
621
634
|
UnderpostRepository.API.initLocalRepo({ path: destFolder });
|
|
622
635
|
shellExec(`cd ${destFolder} && git add . && git commit -m "Base template implementation"`);
|
|
623
636
|
}
|
|
624
|
-
shellExec(`cd ${destFolder} &&
|
|
625
|
-
shellExec(`cd ${destFolder} &&
|
|
637
|
+
shellExec(`cd ${destFolder} && node bin new --deploy-id ${deployId} --default-conf`);
|
|
638
|
+
shellExec(`cd ${destFolder} && node bin client ${deployId}`);
|
|
639
|
+
shellExec(`cd ${destFolder} && DEPLOY_ID=${deployId} npm run dev`);
|
|
626
640
|
}
|
|
627
641
|
return resolve(true);
|
|
628
642
|
} catch (error) {
|
|
@@ -852,6 +866,7 @@ class UnderpostRepository {
|
|
|
852
866
|
}
|
|
853
867
|
}
|
|
854
868
|
await buildClient({
|
|
869
|
+
deployId: resolvedDeployId,
|
|
855
870
|
buildZip: options.buildZip || false,
|
|
856
871
|
split: options.split || '',
|
|
857
872
|
fullBuild: options.liteBuild ? false : true,
|
|
@@ -862,7 +877,12 @@ class UnderpostRepository {
|
|
|
862
877
|
logger.warn('Skip replica client build: replica folder not found', { replicaDeployId });
|
|
863
878
|
continue;
|
|
864
879
|
}
|
|
865
|
-
await Underpost.repo.client(replicaDeployId
|
|
880
|
+
await Underpost.repo.client(replicaDeployId, '', '', '', {
|
|
881
|
+
buildZip: options.buildZip || false,
|
|
882
|
+
split: options.split || '',
|
|
883
|
+
liteBuild: options.liteBuild || false,
|
|
884
|
+
iconsBuild: options.iconsBuild || false,
|
|
885
|
+
});
|
|
866
886
|
}
|
|
867
887
|
|
|
868
888
|
return resolve(true);
|
|
@@ -937,7 +957,7 @@ Prevent build private config repo.`,
|
|
|
937
957
|
deployVersion: packageJsonDeploy.version,
|
|
938
958
|
};
|
|
939
959
|
}
|
|
940
|
-
shellExec(`node bin/build ${deployId} conf`);
|
|
960
|
+
shellExec(`node bin/build ${deployId} --conf`);
|
|
941
961
|
return {
|
|
942
962
|
validVersion: true,
|
|
943
963
|
engineVersion: packageJsonEngine.version,
|
|
@@ -1374,8 +1394,9 @@ Prevent build private config repo.`,
|
|
|
1374
1394
|
const gitEmail = process.env.GITHUB_EMAIL || `development@underpost.net`;
|
|
1375
1395
|
|
|
1376
1396
|
if (!fs.existsSync(`${repoPath}/.git`)) {
|
|
1377
|
-
shellExec(`
|
|
1397
|
+
shellExec(`mkdir -p "${repoPath}" && git init "${repoPath}"`);
|
|
1378
1398
|
}
|
|
1399
|
+
|
|
1379
1400
|
shellExec(`cd "${repoPath}" && git config user.name '${gitUsername}'`);
|
|
1380
1401
|
shellExec(`cd "${repoPath}" && git config user.email '${gitEmail}'`);
|
|
1381
1402
|
shellExec(`cd "${repoPath}" && git config core.filemode false`);
|
|
@@ -1653,6 +1674,79 @@ Prevent build private config repo.`,
|
|
|
1653
1674
|
}
|
|
1654
1675
|
return fallback;
|
|
1655
1676
|
},
|
|
1677
|
+
|
|
1678
|
+
/**
|
|
1679
|
+
* Performs a shallow sparse Git checkout of a single subdirectory from any
|
|
1680
|
+
* GitHub repository into a local target directory.
|
|
1681
|
+
*
|
|
1682
|
+
* Uses `--depth 1 --no-checkout` + `git sparse-checkout` so only the
|
|
1683
|
+
* requested path is fetched — no full clone of the remote repo.
|
|
1684
|
+
* Skips the clone entirely when `<targetDir>/<subPath>` already exists on
|
|
1685
|
+
* disk (idempotent).
|
|
1686
|
+
*
|
|
1687
|
+
* Requires `GITHUB_TOKEN` to be set in the environment for authenticated
|
|
1688
|
+
* access to private repositories.
|
|
1689
|
+
*
|
|
1690
|
+
* @param {string} subPath - The subdirectory path within the remote repo to
|
|
1691
|
+
* check out (e.g. `'conf/dd-prototype'`, `'src/api/payments'`).
|
|
1692
|
+
* @param {object} [options]
|
|
1693
|
+
* @param {string} [options.repoOwner='underpostnet'] - GitHub organisation or
|
|
1694
|
+
* user that owns the repository.
|
|
1695
|
+
* @param {string} [options.repoName='engine-private'] - Name of the
|
|
1696
|
+
* repository on GitHub.
|
|
1697
|
+
* @param {string} [options.targetDir='./engine-private'] - Local directory
|
|
1698
|
+
* where the repo will be cloned.
|
|
1699
|
+
* @returns {boolean} `true` when the checkout was performed, `false` when it
|
|
1700
|
+
* was skipped because the target path already existed.
|
|
1701
|
+
* @memberof UnderpostRepository
|
|
1702
|
+
*/
|
|
1703
|
+
sparseCheckoutDirectory(
|
|
1704
|
+
subPath,
|
|
1705
|
+
options = { repoOwner: 'underpostnet', repoName: 'engine-private', targetDir: './engine-private' },
|
|
1706
|
+
) {
|
|
1707
|
+
const { repoOwner = 'underpostnet', repoName = 'engine-private', targetDir = './engine-private' } = options;
|
|
1708
|
+
const localPath = `${targetDir}/${subPath}`;
|
|
1709
|
+
if (fs.existsSync(localPath)) {
|
|
1710
|
+
logger.info('[sparseCheckoutDirectory] path already present, skipping', localPath);
|
|
1711
|
+
return false;
|
|
1712
|
+
}
|
|
1713
|
+
const authUrl = `https://${process.env.GITHUB_TOKEN}@github.com/${repoOwner}/${repoName}.git`;
|
|
1714
|
+
shellExec(`git clone --depth 1 --no-checkout ${authUrl} ${targetDir}`, { disableLog: true });
|
|
1715
|
+
shellExec(`cd ${targetDir} && git sparse-checkout set ${subPath} && git checkout`, { disableLog: true });
|
|
1716
|
+
logger.info('[sparseCheckoutDirectory] sparse checkout complete', localPath);
|
|
1717
|
+
return true;
|
|
1718
|
+
},
|
|
1719
|
+
|
|
1720
|
+
/**
|
|
1721
|
+
* Ensures a deploy's public source repo (e.g. `engine-prototype`) is present
|
|
1722
|
+
* next to the engine and reset to a pristine HEAD, so catalog `sourceMoves`
|
|
1723
|
+
* can (re)pull custom sources even after a previous build moved them out of
|
|
1724
|
+
* the source tree.
|
|
1725
|
+
*
|
|
1726
|
+
* Clones `../<repoName>` when missing; otherwise restores a clean checkout
|
|
1727
|
+
* (`git checkout .` brings back any moved-out tracked files) and pulls latest.
|
|
1728
|
+
* Mirrors the sibling-repo handling used by `syncPrivateConf`.
|
|
1729
|
+
*
|
|
1730
|
+
* @param {string} repoName - Public source repo name (e.g. `engine-prototype`).
|
|
1731
|
+
* @returns {boolean} `true` when the repo is available on disk.
|
|
1732
|
+
* @memberof UnderpostRepository
|
|
1733
|
+
*/
|
|
1734
|
+
pullSourceRepo(repoName) {
|
|
1735
|
+
const username = process.env.GITHUB_USERNAME;
|
|
1736
|
+
if (!username || !repoName) return false;
|
|
1737
|
+
const repoPath = `../${repoName}`;
|
|
1738
|
+
const gitUri = `${username}/${repoName}`;
|
|
1739
|
+
if (!fs.existsSync(repoPath)) {
|
|
1740
|
+
shellExec(`cd .. && underpost clone ${gitUri}`, { silent: true });
|
|
1741
|
+
} else {
|
|
1742
|
+
const repoAbsPath = path.resolve(repoPath);
|
|
1743
|
+
shellExec(`git config --global --add safe.directory '${repoAbsPath}'`);
|
|
1744
|
+
shellExec(`cd ${repoPath} && git checkout . && git clean -f -d && underpost pull . ${gitUri}`, {
|
|
1745
|
+
silent: true,
|
|
1746
|
+
});
|
|
1747
|
+
}
|
|
1748
|
+
return fs.existsSync(repoPath);
|
|
1749
|
+
},
|
|
1656
1750
|
};
|
|
1657
1751
|
}
|
|
1658
1752
|
|