@nmakarov/cli-toolkit 0.47.0 → 0.49.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.js CHANGED
@@ -5793,10 +5793,9 @@ function buildEcosystemConfig(service, paths) {
5793
5793
  const outLog = join9(paths.logs, `${pm2.appName}.out.log`);
5794
5794
  const errLog = join9(paths.logs, `${pm2.appName}.err.log`);
5795
5795
  return `/**
5796
- * pm2 ecosystem for ${service.name} \u2014 seeded by cli-toolkit deploy (init).
5797
- *
5798
- * cwd points at the \`current\` symlink (created on first deploy).
5799
- * Tweak \`args\` here, then: pm2 reload ${paths.ecosystem} --update-env
5796
+ * pm2 ecosystem for ${service.name} \u2014 written by cli-toolkit deploy from the
5797
+ * service manifest (init/deploy). Do not hand-edit; change pm2.* in the
5798
+ * manifest and redeploy. cwd \u2192 \`current\` symlink.
5800
5799
  */
5801
5800
  module.exports = {
5802
5801
  apps: [
@@ -5804,7 +5803,7 @@ module.exports = {
5804
5803
  name: "${pm2.appName}",
5805
5804
  script: "${pm2.script}",
5806
5805
  cwd: "${paths.current}",
5807
- args: "${pm2.args}",
5806
+ args: "${pm2.args ?? ""}",
5808
5807
  instances: 1,
5809
5808
  exec_mode: "fork",
5810
5809
  autorestart: true,
@@ -5843,17 +5842,17 @@ async function initServiceStructure(service, options = {}) {
5843
5842
  if (!dryRun) await mkdir6(dir, { recursive: true });
5844
5843
  created.push(dir);
5845
5844
  }
5846
- let ecosystemCreated = false;
5847
- if (await pathExists4(paths.ecosystem)) {
5848
- skipped.push(paths.ecosystem);
5845
+ const ecosystemExisted = await pathExists4(paths.ecosystem);
5846
+ if (!dryRun) {
5847
+ await writeFile5(paths.ecosystem, buildEcosystemConfig(service, paths), { mode: 420 });
5848
+ }
5849
+ if (ecosystemExisted) {
5850
+ logger.info(`synced ${paths.ecosystem} from manifest`);
5849
5851
  } else {
5850
- if (!dryRun) {
5851
- await writeFile5(paths.ecosystem, buildEcosystemConfig(service, paths), { mode: 420 });
5852
- }
5853
- ecosystemCreated = true;
5854
5852
  created.push(paths.ecosystem);
5853
+ logger.info(`seeded ${paths.ecosystem}`);
5855
5854
  }
5856
- const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] init-structure service=${service.name} dryRun=${dryRun} created=${created.length} skipped=${skipped.length}
5855
+ const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] init-structure service=${service.name} dryRun=${dryRun} created=${created.length} skipped=${skipped.length} ecosystem=synced
5857
5856
  `;
5858
5857
  if (!dryRun) {
5859
5858
  await mkdir6(paths.logs, { recursive: true });
@@ -5862,8 +5861,7 @@ async function initServiceStructure(service, options = {}) {
5862
5861
  logger.info(`service=${service.name} appsRoot=${paths.root}`);
5863
5862
  logger.info(`created: ${created.length ? created.join(", ") : "(none)"}`);
5864
5863
  logger.info(`already present: ${skipped.length ? skipped.join(", ") : "(none)"}`);
5865
- if (ecosystemCreated) logger.info(`seeded ${paths.ecosystem}`);
5866
- return { paths, created, skipped, ecosystemCreated };
5864
+ return { paths, created, skipped, ecosystemCreated: !ecosystemExisted, ecosystemSynced: true };
5867
5865
  }
5868
5866
 
5869
5867
  // src/deploy/bootstrap-host.js
@@ -5960,11 +5958,55 @@ async function installLogrotate(service, options = {}) {
5960
5958
  await runShell(`sudo cp '${tmp}' '${conf}'`, { logger });
5961
5959
  logger.info(`logrotate config written: ${conf}`);
5962
5960
  }
5961
+ var OPERATOR_SHELL_BEGIN = "# >>> mlsfarm-operator >>>";
5962
+ var OPERATOR_SHELL_END = "# <<< mlsfarm-operator <<<";
5963
+ async function installOperatorShell(service, options = {}) {
5964
+ const { user = "ubuntu", dryRun = false, logger = console } = options;
5965
+ const appsRoot = service.appsRoot;
5966
+ if (!appsRoot) {
5967
+ logger.warn("installOperatorShell: service.appsRoot missing \u2014 skipped");
5968
+ return;
5969
+ }
5970
+ const home = user === "ubuntu" || user === process.env.USER ? join10(homedir(), ".bashrc") : `/home/${user}/.bashrc`;
5971
+ const currentDir = join10(appsRoot, "current");
5972
+ const block = [
5973
+ OPERATOR_SHELL_BEGIN,
5974
+ "# Managed by cli-toolkit deploy bootstrap \u2014 do not edit by hand.",
5975
+ "export ENV=production",
5976
+ `if [ -d "${currentDir}" ]; then`,
5977
+ ` cd "${currentDir}" || true`,
5978
+ "fi",
5979
+ OPERATOR_SHELL_END,
5980
+ ""
5981
+ ].join("\n");
5982
+ if (dryRun) {
5983
+ logger.info(`[dryRun] would update ${home} (ENV=production, cd ${currentDir})`);
5984
+ return;
5985
+ }
5986
+ let existing = "";
5987
+ if (await pathExists5(home)) {
5988
+ existing = await readFile4(home, "utf8");
5989
+ }
5990
+ const begin = existing.indexOf(OPERATOR_SHELL_BEGIN);
5991
+ const end = existing.indexOf(OPERATOR_SHELL_END);
5992
+ let next;
5993
+ if (begin !== -1 && end !== -1 && end > begin) {
5994
+ const afterEnd = end + OPERATOR_SHELL_END.length;
5995
+ const rest = existing.slice(afterEnd).replace(/^\n/, "");
5996
+ next = `${existing.slice(0, begin).replace(/\s*$/, "\n")}${block}${rest}`;
5997
+ } else {
5998
+ next = `${existing.replace(/\s*$/, "\n")}
5999
+ ${block}`;
6000
+ }
6001
+ await writeFile6(home, next, { mode: 420 });
6002
+ logger.info(`operator shell: ${home} \u2192 ENV=production, cd ${currentDir}`);
6003
+ }
5963
6004
  async function bootstrapHost(service, options = {}) {
5964
6005
  const { deployKey = service.deployKey, user = "ubuntu", dryRun = false, logger = console } = options;
5965
6006
  await ensurePm2Startup({ user, dryRun, logger });
5966
6007
  if (deployKey) await installDeployKey(deployKey, { dryRun, logger });
5967
6008
  await installLogrotate(service, { dryRun, logger });
6009
+ await installOperatorShell(service, { user, dryRun, logger });
5968
6010
  logger.info("bootstrap-host complete");
5969
6011
  }
5970
6012
 
@@ -8702,6 +8744,7 @@ export {
8702
8744
  createElement2 as h,
8703
8745
  initServiceStructure,
8704
8746
  installDeps,
8747
+ installOperatorShell,
8705
8748
  ipcFileLogsTableNameForSourceResource,
8706
8749
  joiEdateType,
8707
8750
  joiStringArrayType,