@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.cjs CHANGED
@@ -1142,6 +1142,7 @@ __export(src_exports, {
1142
1142
  h: () => import_react5.createElement,
1143
1143
  initServiceStructure: () => initServiceStructure,
1144
1144
  installDeps: () => installDeps,
1145
+ installOperatorShell: () => installOperatorShell,
1145
1146
  ipcFileLogsTableNameForSourceResource: () => ipcFileLogsTableNameForSourceResource,
1146
1147
  joiEdateType: () => joiEdateType,
1147
1148
  joiStringArrayType: () => joiStringArrayType,
@@ -5940,10 +5941,9 @@ function buildEcosystemConfig(service, paths) {
5940
5941
  const outLog = (0, import_node_path8.join)(paths.logs, `${pm2.appName}.out.log`);
5941
5942
  const errLog = (0, import_node_path8.join)(paths.logs, `${pm2.appName}.err.log`);
5942
5943
  return `/**
5943
- * pm2 ecosystem for ${service.name} \u2014 seeded by cli-toolkit deploy (init).
5944
- *
5945
- * cwd points at the \`current\` symlink (created on first deploy).
5946
- * Tweak \`args\` here, then: pm2 reload ${paths.ecosystem} --update-env
5944
+ * pm2 ecosystem for ${service.name} \u2014 written by cli-toolkit deploy from the
5945
+ * service manifest (init/deploy). Do not hand-edit; change pm2.* in the
5946
+ * manifest and redeploy. cwd \u2192 \`current\` symlink.
5947
5947
  */
5948
5948
  module.exports = {
5949
5949
  apps: [
@@ -5951,7 +5951,7 @@ module.exports = {
5951
5951
  name: "${pm2.appName}",
5952
5952
  script: "${pm2.script}",
5953
5953
  cwd: "${paths.current}",
5954
- args: "${pm2.args}",
5954
+ args: "${pm2.args ?? ""}",
5955
5955
  instances: 1,
5956
5956
  exec_mode: "fork",
5957
5957
  autorestart: true,
@@ -5990,17 +5990,17 @@ async function initServiceStructure(service, options = {}) {
5990
5990
  if (!dryRun) await (0, import_promises11.mkdir)(dir, { recursive: true });
5991
5991
  created.push(dir);
5992
5992
  }
5993
- let ecosystemCreated = false;
5994
- if (await pathExists4(paths.ecosystem)) {
5995
- skipped.push(paths.ecosystem);
5993
+ const ecosystemExisted = await pathExists4(paths.ecosystem);
5994
+ if (!dryRun) {
5995
+ await (0, import_promises11.writeFile)(paths.ecosystem, buildEcosystemConfig(service, paths), { mode: 420 });
5996
+ }
5997
+ if (ecosystemExisted) {
5998
+ logger.info(`synced ${paths.ecosystem} from manifest`);
5996
5999
  } else {
5997
- if (!dryRun) {
5998
- await (0, import_promises11.writeFile)(paths.ecosystem, buildEcosystemConfig(service, paths), { mode: 420 });
5999
- }
6000
- ecosystemCreated = true;
6001
6000
  created.push(paths.ecosystem);
6001
+ logger.info(`seeded ${paths.ecosystem}`);
6002
6002
  }
6003
- const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] init-structure service=${service.name} dryRun=${dryRun} created=${created.length} skipped=${skipped.length}
6003
+ const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] init-structure service=${service.name} dryRun=${dryRun} created=${created.length} skipped=${skipped.length} ecosystem=synced
6004
6004
  `;
6005
6005
  if (!dryRun) {
6006
6006
  await (0, import_promises11.mkdir)(paths.logs, { recursive: true });
@@ -6009,8 +6009,7 @@ async function initServiceStructure(service, options = {}) {
6009
6009
  logger.info(`service=${service.name} appsRoot=${paths.root}`);
6010
6010
  logger.info(`created: ${created.length ? created.join(", ") : "(none)"}`);
6011
6011
  logger.info(`already present: ${skipped.length ? skipped.join(", ") : "(none)"}`);
6012
- if (ecosystemCreated) logger.info(`seeded ${paths.ecosystem}`);
6013
- return { paths, created, skipped, ecosystemCreated };
6012
+ return { paths, created, skipped, ecosystemCreated: !ecosystemExisted, ecosystemSynced: true };
6014
6013
  }
6015
6014
 
6016
6015
  // src/deploy/bootstrap-host.js
@@ -6107,11 +6106,55 @@ async function installLogrotate(service, options = {}) {
6107
6106
  await runShell(`sudo cp '${tmp}' '${conf}'`, { logger });
6108
6107
  logger.info(`logrotate config written: ${conf}`);
6109
6108
  }
6109
+ var OPERATOR_SHELL_BEGIN = "# >>> mlsfarm-operator >>>";
6110
+ var OPERATOR_SHELL_END = "# <<< mlsfarm-operator <<<";
6111
+ async function installOperatorShell(service, options = {}) {
6112
+ const { user = "ubuntu", dryRun = false, logger = console } = options;
6113
+ const appsRoot = service.appsRoot;
6114
+ if (!appsRoot) {
6115
+ logger.warn("installOperatorShell: service.appsRoot missing \u2014 skipped");
6116
+ return;
6117
+ }
6118
+ const home = user === "ubuntu" || user === process.env.USER ? (0, import_node_path9.join)((0, import_node_os2.homedir)(), ".bashrc") : `/home/${user}/.bashrc`;
6119
+ const currentDir = (0, import_node_path9.join)(appsRoot, "current");
6120
+ const block = [
6121
+ OPERATOR_SHELL_BEGIN,
6122
+ "# Managed by cli-toolkit deploy bootstrap \u2014 do not edit by hand.",
6123
+ "export ENV=production",
6124
+ `if [ -d "${currentDir}" ]; then`,
6125
+ ` cd "${currentDir}" || true`,
6126
+ "fi",
6127
+ OPERATOR_SHELL_END,
6128
+ ""
6129
+ ].join("\n");
6130
+ if (dryRun) {
6131
+ logger.info(`[dryRun] would update ${home} (ENV=production, cd ${currentDir})`);
6132
+ return;
6133
+ }
6134
+ let existing = "";
6135
+ if (await pathExists5(home)) {
6136
+ existing = await (0, import_promises12.readFile)(home, "utf8");
6137
+ }
6138
+ const begin = existing.indexOf(OPERATOR_SHELL_BEGIN);
6139
+ const end = existing.indexOf(OPERATOR_SHELL_END);
6140
+ let next;
6141
+ if (begin !== -1 && end !== -1 && end > begin) {
6142
+ const afterEnd = end + OPERATOR_SHELL_END.length;
6143
+ const rest = existing.slice(afterEnd).replace(/^\n/, "");
6144
+ next = `${existing.slice(0, begin).replace(/\s*$/, "\n")}${block}${rest}`;
6145
+ } else {
6146
+ next = `${existing.replace(/\s*$/, "\n")}
6147
+ ${block}`;
6148
+ }
6149
+ await (0, import_promises12.writeFile)(home, next, { mode: 420 });
6150
+ logger.info(`operator shell: ${home} \u2192 ENV=production, cd ${currentDir}`);
6151
+ }
6110
6152
  async function bootstrapHost(service, options = {}) {
6111
6153
  const { deployKey = service.deployKey, user = "ubuntu", dryRun = false, logger = console } = options;
6112
6154
  await ensurePm2Startup({ user, dryRun, logger });
6113
6155
  if (deployKey) await installDeployKey(deployKey, { dryRun, logger });
6114
6156
  await installLogrotate(service, { dryRun, logger });
6157
+ await installOperatorShell(service, { user, dryRun, logger });
6115
6158
  logger.info("bootstrap-host complete");
6116
6159
  }
6117
6160
 
@@ -8850,6 +8893,7 @@ var TasksManager = class _TasksManager {
8850
8893
  h,
8851
8894
  initServiceStructure,
8852
8895
  installDeps,
8896
+ installOperatorShell,
8853
8897
  ipcFileLogsTableNameForSourceResource,
8854
8898
  joiEdateType,
8855
8899
  joiStringArrayType,