@nmakarov/cli-toolkit 0.59.0 → 0.61.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/index.cjs CHANGED
@@ -5819,10 +5819,47 @@ function isFreshOnline(proc, oldPid) {
5819
5819
  }
5820
5820
  return true;
5821
5821
  }
5822
+ async function deletePm2App(appName, options = {}) {
5823
+ const { dryRun = false, logger = console, waitTimeoutMs = 65e3, oldPid = null } = options;
5824
+ if (dryRun) {
5825
+ logger.info(`[dryRun] would pm2 delete ${appName}`);
5826
+ return;
5827
+ }
5828
+ const before = await getPm2Process(appName, { logger });
5829
+ if (!before) {
5830
+ logger.info(`pm2 ${appName}: not present (skip delete)`);
5831
+ return;
5832
+ }
5833
+ await runShell(`pm2 delete "${appName}"`, { logger });
5834
+ await waitPm2(
5835
+ appName,
5836
+ (proc) => {
5837
+ if (proc) return false;
5838
+ if (oldPid != null && isPidAlive(oldPid)) return false;
5839
+ return true;
5840
+ },
5841
+ { timeoutMs: waitTimeoutMs, logger, label: "deleted (process gone)" }
5842
+ );
5843
+ logger.info(`pm2 ${appName} deleted`);
5844
+ }
5845
+ async function startFromEcosystem(paths, options = {}) {
5846
+ const { dryRun = false, logger = console } = options;
5847
+ if (dryRun) {
5848
+ logger.info(`[dryRun] would pm2 start ${paths.ecosystem} --update-env`);
5849
+ return;
5850
+ }
5851
+ await runShell(
5852
+ `ENV=production NODE_ENV=production pm2 start "${paths.ecosystem}" --update-env`,
5853
+ { logger }
5854
+ );
5855
+ logger.info("pm2 started from ecosystem");
5856
+ }
5822
5857
  async function reloadPm2(paths, options = {}) {
5823
5858
  const { dryRun = false, logger = console, appName = null, waitTimeoutMs = 65e3 } = options;
5824
5859
  if (dryRun) {
5825
- logger.info(`[dryRun] would pm2 startOrReload ${paths.ecosystem} --update-env`);
5860
+ logger.info(
5861
+ `[dryRun] would pm2 delete${appName ? ` ${appName}` : ""} + start ${paths.ecosystem} --update-env`
5862
+ );
5826
5863
  return;
5827
5864
  }
5828
5865
  let oldPid = null;
@@ -5831,14 +5868,15 @@ async function reloadPm2(paths, options = {}) {
5831
5868
  const n = Number(before?.pid);
5832
5869
  if (Number.isFinite(n) && n > 0 && before?.pm2_env?.status === "online") {
5833
5870
  oldPid = n;
5834
- logger.info(`pm2 ${appName}: reloading (old pid=${oldPid})`);
5871
+ logger.info(`pm2 ${appName}: recreate (old pid=${oldPid})`);
5835
5872
  }
5873
+ await deletePm2App(appName, { dryRun, logger, waitTimeoutMs, oldPid });
5874
+ } else {
5875
+ logger.warn?.(
5876
+ "reloadPm2: appName missing; starting ecosystem without delete (pass appName so script/env always recreate cleanly)"
5877
+ );
5836
5878
  }
5837
- await runShell(
5838
- `ENV=production NODE_ENV=production pm2 startOrReload "${paths.ecosystem}" --update-env`,
5839
- { logger }
5840
- );
5841
- logger.info("pm2 reloaded");
5879
+ await startFromEcosystem(paths, { dryRun, logger });
5842
5880
  if (appName) {
5843
5881
  const proc = await waitPm2(
5844
5882
  appName,
@@ -5846,7 +5884,7 @@ async function reloadPm2(paths, options = {}) {
5846
5884
  {
5847
5885
  timeoutMs: waitTimeoutMs,
5848
5886
  logger,
5849
- label: oldPid ? `online on new pid (old ${oldPid} gone)` : "online after reload"
5887
+ label: oldPid ? `online on new pid (old ${oldPid} gone)` : "online after recreate"
5850
5888
  }
5851
5889
  );
5852
5890
  logger.info(`pm2 ${appName} online pid=${proc?.pid ?? "?"}`);
@@ -5883,14 +5921,15 @@ async function stopPm2(appName, options = {}) {
5883
5921
  async function startPm2(paths, options = {}) {
5884
5922
  const { dryRun = false, logger = console, appName = null, waitTimeoutMs = 65e3 } = options;
5885
5923
  if (dryRun) {
5886
- logger.info(`[dryRun] would pm2 start ${paths.ecosystem} --update-env`);
5924
+ logger.info(
5925
+ `[dryRun] would pm2 delete${appName ? ` ${appName}` : ""} + start ${paths.ecosystem} --update-env`
5926
+ );
5887
5927
  return;
5888
5928
  }
5889
- await runShell(
5890
- `ENV=production NODE_ENV=production pm2 start "${paths.ecosystem}" --update-env`,
5891
- { logger }
5892
- );
5893
- logger.info("pm2 started");
5929
+ if (appName) {
5930
+ await deletePm2App(appName, { dryRun, logger, waitTimeoutMs });
5931
+ }
5932
+ await startFromEcosystem(paths, { dryRun, logger });
5894
5933
  if (appName) {
5895
5934
  const proc = await waitPm2(
5896
5935
  appName,
@@ -6145,7 +6184,7 @@ function buildEnsureEnvScript() {
6145
6184
  return `/**
6146
6185
  * Written by cli-toolkit deploy (init-structure). Do not hand-edit.
6147
6186
  * Preloaded via pm2 node_args --require. Always set (do not only fill when unset):
6148
- * \`pm2 startOrReload --update-env\` can inject a non-production ENV from the
6187
+ * \`pm2 start \u2026 --update-env\` can inject a non-production ENV from the
6149
6188
  * deploy shell / prior dump, and a conditional assign would leave it in place.
6150
6189
  */
6151
6190
  process.env.ENV = "production";
@@ -6511,7 +6550,9 @@ async function rollbackService(service, options = {}) {
6511
6550
  logger.info(`rollback target: v${buildInfo.version} release=${buildInfo.release ?? rollbackTarget.name}`);
6512
6551
  }
6513
6552
  await activateRelease(rollbackTarget.path, paths, { dryRun, logger });
6514
- await reloadPm2(paths, { dryRun, logger });
6553
+ const appName = service.pm2?.appName ?? null;
6554
+ const waitTimeoutMs = 65e3;
6555
+ await reloadPm2(paths, { dryRun, logger, appName, waitTimeoutMs });
6515
6556
  const summary = `rollback ${activeName} \u2192 ${rollbackTarget.name} dryRun=${dryRun}`;
6516
6557
  if (!dryRun) await appendDeployLog(paths.deployLog, summary);
6517
6558
  return { from: activeName, to: rollbackTarget.name, path: rollbackTarget.path };