@nmakarov/cli-toolkit 0.59.0 → 0.63.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/dist/cli-runner.cjs +51 -4
- package/dist/cli-runner.cjs.map +1 -1
- package/dist/cli-runner.js +51 -4
- package/dist/cli-runner.js.map +1 -1
- package/dist/db.cjs +16 -3
- package/dist/db.cjs.map +1 -1
- package/dist/db.js +16 -3
- package/dist/db.js.map +1 -1
- package/dist/deploy.cjs +57 -16
- package/dist/deploy.cjs.map +1 -1
- package/dist/deploy.js +57 -16
- package/dist/deploy.js.map +1 -1
- package/dist/index.cjs +110 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +109 -20
- package/dist/index.js.map +1 -1
- package/dist/init.cjs +5 -0
- package/dist/init.cjs.map +1 -1
- package/dist/init.js +5 -0
- package/dist/init.js.map +1 -1
- package/dist/logger.cjs +5 -0
- package/dist/logger.cjs.map +1 -1
- package/dist/logger.js +5 -0
- package/dist/logger.js.map +1 -1
- package/dist/tasks.cjs +32 -1
- package/dist/tasks.cjs.map +1 -1
- package/dist/tasks.js +31 -1
- package/dist/tasks.js.map +1 -1
- package/package.json +1 -1
- package/scripts/deploy/cli.js +2 -2
package/dist/index.js
CHANGED
|
@@ -3503,13 +3503,15 @@ var CONNECTION_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
|
3503
3503
|
"57P02",
|
|
3504
3504
|
"57P03"
|
|
3505
3505
|
]);
|
|
3506
|
-
var CONNECTION_ERROR_MESSAGE_RE = /connection (terminated|ended|closed|destroyed|reset|refused|not open)|Connection terminated unexpectedly|Client has encountered a connection error|server closed the connection|Cannot use a pool after calling end|This socket has been ended|connect ECONNRESET
|
|
3506
|
+
var CONNECTION_ERROR_MESSAGE_RE = /connection (terminated|ended|closed|destroyed|reset|refused|not open)|Connection terminated unexpectedly|Client has encountered a connection error|server closed the connection|Cannot use a pool after calling end|This socket has been ended|connect ECONNRESET/i;
|
|
3507
3507
|
var Db = class _Db {
|
|
3508
3508
|
static async init(context, options = {}) {
|
|
3509
3509
|
const buildConfig = async () => {
|
|
3510
3510
|
const defs = {
|
|
3511
3511
|
dbName: "string",
|
|
3512
|
-
dbProfile: "boolean default false"
|
|
3512
|
+
dbProfile: "boolean default false",
|
|
3513
|
+
/** Cap knex pool size (default 10). Size ≈ expected concurrency + headroom. */
|
|
3514
|
+
dbPoolMax: "number"
|
|
3513
3515
|
};
|
|
3514
3516
|
const discovered = context?.params?.getAllForModule?.("db", defs) ?? {};
|
|
3515
3517
|
const merged = { ...discovered, ...options };
|
|
@@ -3568,12 +3570,23 @@ var Db = class _Db {
|
|
|
3568
3570
|
context?.args?.env,
|
|
3569
3571
|
merged.name
|
|
3570
3572
|
);
|
|
3573
|
+
const poolMaxRaw = merged.dbPoolMax ?? merged.pool?.max;
|
|
3574
|
+
const poolMax = Number(poolMaxRaw);
|
|
3575
|
+
const pool = {
|
|
3576
|
+
...KNEX_DEFAULTS.pool,
|
|
3577
|
+
...merged.pool && typeof merged.pool === "object" ? merged.pool : {}
|
|
3578
|
+
};
|
|
3579
|
+
if (Number.isFinite(poolMax) && poolMax >= 1) {
|
|
3580
|
+
pool.max = Math.floor(poolMax);
|
|
3581
|
+
}
|
|
3571
3582
|
return {
|
|
3572
3583
|
...KNEX_DEFAULTS,
|
|
3573
3584
|
connectionString: dbConnectionString,
|
|
3574
3585
|
name: displayName,
|
|
3575
3586
|
profile: !!dbProfile,
|
|
3576
|
-
logger: context.logger
|
|
3587
|
+
logger: context.logger,
|
|
3588
|
+
pool,
|
|
3589
|
+
...merged.acquireConnectionTimeout != null ? { acquireConnectionTimeout: merged.acquireConnectionTimeout } : {}
|
|
3577
3590
|
};
|
|
3578
3591
|
};
|
|
3579
3592
|
const config2 = context?.params?.runWithModuleAsync ? await context.params.runWithModuleAsync("db", buildConfig) : await buildConfig();
|
|
@@ -5026,6 +5039,9 @@ var Logger = class _Logger {
|
|
|
5026
5039
|
const message = this.inspectChunks([operation, ...chunks]);
|
|
5027
5040
|
this.out({ level: "response", message });
|
|
5028
5041
|
}
|
|
5042
|
+
/**
|
|
5043
|
+
* @returns {boolean} true when the progress line was emitted (not throttled)
|
|
5044
|
+
*/
|
|
5029
5045
|
progress(message, opts) {
|
|
5030
5046
|
const { prefix, count, total } = opts;
|
|
5031
5047
|
const paddedTotal = String(total).length;
|
|
@@ -5059,7 +5075,9 @@ var Logger = class _Logger {
|
|
|
5059
5075
|
if (this.options.progressThrottle && prefix) {
|
|
5060
5076
|
this.lastProgressTimes[prefix] = Date.now();
|
|
5061
5077
|
}
|
|
5078
|
+
return true;
|
|
5062
5079
|
}
|
|
5080
|
+
return false;
|
|
5063
5081
|
}
|
|
5064
5082
|
shouldOutputProgress(prefix, count, total) {
|
|
5065
5083
|
if (!this.options.progressThrottle) {
|
|
@@ -5655,10 +5673,47 @@ function isFreshOnline(proc, oldPid) {
|
|
|
5655
5673
|
}
|
|
5656
5674
|
return true;
|
|
5657
5675
|
}
|
|
5676
|
+
async function deletePm2App(appName, options = {}) {
|
|
5677
|
+
const { dryRun = false, logger = console, waitTimeoutMs = 65e3, oldPid = null } = options;
|
|
5678
|
+
if (dryRun) {
|
|
5679
|
+
logger.info(`[dryRun] would pm2 delete ${appName}`);
|
|
5680
|
+
return;
|
|
5681
|
+
}
|
|
5682
|
+
const before = await getPm2Process(appName, { logger });
|
|
5683
|
+
if (!before) {
|
|
5684
|
+
logger.info(`pm2 ${appName}: not present (skip delete)`);
|
|
5685
|
+
return;
|
|
5686
|
+
}
|
|
5687
|
+
await runShell(`pm2 delete "${appName}"`, { logger });
|
|
5688
|
+
await waitPm2(
|
|
5689
|
+
appName,
|
|
5690
|
+
(proc) => {
|
|
5691
|
+
if (proc) return false;
|
|
5692
|
+
if (oldPid != null && isPidAlive(oldPid)) return false;
|
|
5693
|
+
return true;
|
|
5694
|
+
},
|
|
5695
|
+
{ timeoutMs: waitTimeoutMs, logger, label: "deleted (process gone)" }
|
|
5696
|
+
);
|
|
5697
|
+
logger.info(`pm2 ${appName} deleted`);
|
|
5698
|
+
}
|
|
5699
|
+
async function startFromEcosystem(paths, options = {}) {
|
|
5700
|
+
const { dryRun = false, logger = console } = options;
|
|
5701
|
+
if (dryRun) {
|
|
5702
|
+
logger.info(`[dryRun] would pm2 start ${paths.ecosystem} --update-env`);
|
|
5703
|
+
return;
|
|
5704
|
+
}
|
|
5705
|
+
await runShell(
|
|
5706
|
+
`ENV=production NODE_ENV=production pm2 start "${paths.ecosystem}" --update-env`,
|
|
5707
|
+
{ logger }
|
|
5708
|
+
);
|
|
5709
|
+
logger.info("pm2 started from ecosystem");
|
|
5710
|
+
}
|
|
5658
5711
|
async function reloadPm2(paths, options = {}) {
|
|
5659
5712
|
const { dryRun = false, logger = console, appName = null, waitTimeoutMs = 65e3 } = options;
|
|
5660
5713
|
if (dryRun) {
|
|
5661
|
-
logger.info(
|
|
5714
|
+
logger.info(
|
|
5715
|
+
`[dryRun] would pm2 delete${appName ? ` ${appName}` : ""} + start ${paths.ecosystem} --update-env`
|
|
5716
|
+
);
|
|
5662
5717
|
return;
|
|
5663
5718
|
}
|
|
5664
5719
|
let oldPid = null;
|
|
@@ -5667,14 +5722,15 @@ async function reloadPm2(paths, options = {}) {
|
|
|
5667
5722
|
const n = Number(before?.pid);
|
|
5668
5723
|
if (Number.isFinite(n) && n > 0 && before?.pm2_env?.status === "online") {
|
|
5669
5724
|
oldPid = n;
|
|
5670
|
-
logger.info(`pm2 ${appName}:
|
|
5725
|
+
logger.info(`pm2 ${appName}: recreate (old pid=${oldPid})`);
|
|
5671
5726
|
}
|
|
5727
|
+
await deletePm2App(appName, { dryRun, logger, waitTimeoutMs, oldPid });
|
|
5728
|
+
} else {
|
|
5729
|
+
logger.warn?.(
|
|
5730
|
+
"reloadPm2: appName missing; starting ecosystem without delete (pass appName so script/env always recreate cleanly)"
|
|
5731
|
+
);
|
|
5672
5732
|
}
|
|
5673
|
-
await
|
|
5674
|
-
`ENV=production NODE_ENV=production pm2 startOrReload "${paths.ecosystem}" --update-env`,
|
|
5675
|
-
{ logger }
|
|
5676
|
-
);
|
|
5677
|
-
logger.info("pm2 reloaded");
|
|
5733
|
+
await startFromEcosystem(paths, { dryRun, logger });
|
|
5678
5734
|
if (appName) {
|
|
5679
5735
|
const proc = await waitPm2(
|
|
5680
5736
|
appName,
|
|
@@ -5682,7 +5738,7 @@ async function reloadPm2(paths, options = {}) {
|
|
|
5682
5738
|
{
|
|
5683
5739
|
timeoutMs: waitTimeoutMs,
|
|
5684
5740
|
logger,
|
|
5685
|
-
label: oldPid ? `online on new pid (old ${oldPid} gone)` : "online after
|
|
5741
|
+
label: oldPid ? `online on new pid (old ${oldPid} gone)` : "online after recreate"
|
|
5686
5742
|
}
|
|
5687
5743
|
);
|
|
5688
5744
|
logger.info(`pm2 ${appName} online pid=${proc?.pid ?? "?"}`);
|
|
@@ -5719,14 +5775,15 @@ async function stopPm2(appName, options = {}) {
|
|
|
5719
5775
|
async function startPm2(paths, options = {}) {
|
|
5720
5776
|
const { dryRun = false, logger = console, appName = null, waitTimeoutMs = 65e3 } = options;
|
|
5721
5777
|
if (dryRun) {
|
|
5722
|
-
logger.info(
|
|
5778
|
+
logger.info(
|
|
5779
|
+
`[dryRun] would pm2 delete${appName ? ` ${appName}` : ""} + start ${paths.ecosystem} --update-env`
|
|
5780
|
+
);
|
|
5723
5781
|
return;
|
|
5724
5782
|
}
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
);
|
|
5729
|
-
logger.info("pm2 started");
|
|
5783
|
+
if (appName) {
|
|
5784
|
+
await deletePm2App(appName, { dryRun, logger, waitTimeoutMs });
|
|
5785
|
+
}
|
|
5786
|
+
await startFromEcosystem(paths, { dryRun, logger });
|
|
5730
5787
|
if (appName) {
|
|
5731
5788
|
const proc = await waitPm2(
|
|
5732
5789
|
appName,
|
|
@@ -5981,7 +6038,7 @@ function buildEnsureEnvScript() {
|
|
|
5981
6038
|
return `/**
|
|
5982
6039
|
* Written by cli-toolkit deploy (init-structure). Do not hand-edit.
|
|
5983
6040
|
* Preloaded via pm2 node_args --require. Always set (do not only fill when unset):
|
|
5984
|
-
* \`pm2
|
|
6041
|
+
* \`pm2 start \u2026 --update-env\` can inject a non-production ENV from the
|
|
5985
6042
|
* deploy shell / prior dump, and a conditional assign would leave it in place.
|
|
5986
6043
|
*/
|
|
5987
6044
|
process.env.ENV = "production";
|
|
@@ -6347,7 +6404,9 @@ async function rollbackService(service, options = {}) {
|
|
|
6347
6404
|
logger.info(`rollback target: v${buildInfo.version} release=${buildInfo.release ?? rollbackTarget.name}`);
|
|
6348
6405
|
}
|
|
6349
6406
|
await activateRelease(rollbackTarget.path, paths, { dryRun, logger });
|
|
6350
|
-
|
|
6407
|
+
const appName = service.pm2?.appName ?? null;
|
|
6408
|
+
const waitTimeoutMs = 65e3;
|
|
6409
|
+
await reloadPm2(paths, { dryRun, logger, appName, waitTimeoutMs });
|
|
6351
6410
|
const summary = `rollback ${activeName} \u2192 ${rollbackTarget.name} dryRun=${dryRun}`;
|
|
6352
6411
|
if (!dryRun) await appendDeployLog(paths.deployLog, summary);
|
|
6353
6412
|
return { from: activeName, to: rollbackTarget.name, path: rollbackTarget.path };
|
|
@@ -6858,6 +6917,34 @@ async function updateTaskProgress(context, tasksTable, taskId, progress) {
|
|
|
6858
6917
|
progress: typeof progress === "string" ? progress : JSON.stringify(progress)
|
|
6859
6918
|
});
|
|
6860
6919
|
}
|
|
6920
|
+
function createTaskProgressReporter(context, tasksTable, taskId) {
|
|
6921
|
+
let pump = null;
|
|
6922
|
+
let pending = void 0;
|
|
6923
|
+
let hasPending = false;
|
|
6924
|
+
return (progress) => {
|
|
6925
|
+
pending = progress;
|
|
6926
|
+
hasPending = true;
|
|
6927
|
+
if (pump) return pump;
|
|
6928
|
+
pump = (async () => {
|
|
6929
|
+
try {
|
|
6930
|
+
while (hasPending) {
|
|
6931
|
+
hasPending = false;
|
|
6932
|
+
const value = pending;
|
|
6933
|
+
try {
|
|
6934
|
+
await updateTaskProgress(context, tasksTable, taskId, value);
|
|
6935
|
+
} catch (err) {
|
|
6936
|
+
context.logger?.warn?.(
|
|
6937
|
+
`[tasks] progress update failed for ${taskId}: ${err?.message ?? err}`
|
|
6938
|
+
);
|
|
6939
|
+
}
|
|
6940
|
+
}
|
|
6941
|
+
} finally {
|
|
6942
|
+
pump = null;
|
|
6943
|
+
}
|
|
6944
|
+
})();
|
|
6945
|
+
return pump;
|
|
6946
|
+
};
|
|
6947
|
+
}
|
|
6861
6948
|
|
|
6862
6949
|
// src/tasks/servicesRegistry.js
|
|
6863
6950
|
function getDb2(context) {
|
|
@@ -8709,7 +8796,8 @@ async function executeClaimedTask(context, tasksTable, historyTable, row, regist
|
|
|
8709
8796
|
try {
|
|
8710
8797
|
taskInstance = new TaskClass(context, row);
|
|
8711
8798
|
runningTaskInstances.set(row.id, taskInstance);
|
|
8712
|
-
const
|
|
8799
|
+
const reportProgress = createTaskProgressReporter(context, tasksTable, row.id);
|
|
8800
|
+
const runResult = await taskInstance.run(reportProgress);
|
|
8713
8801
|
success = !!runResult?.success;
|
|
8714
8802
|
results = runResult?.results ?? null;
|
|
8715
8803
|
} catch (error) {
|
|
@@ -9256,6 +9344,7 @@ export {
|
|
|
9256
9344
|
controlLaneTaskNames,
|
|
9257
9345
|
convertPattern,
|
|
9258
9346
|
createRelease,
|
|
9347
|
+
createTaskProgressReporter,
|
|
9259
9348
|
defaultFileSynopsisFunction,
|
|
9260
9349
|
defaultTasksRegistry,
|
|
9261
9350
|
defaultVersionSynopsisFunction,
|