scripts-orchestrator 2.4.0 → 2.4.2

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.
@@ -225,6 +225,7 @@ export class Orchestrator {
225
225
  async run() {
226
226
  try {
227
227
  let hasFailures = false;
228
+ let phaseFailed = false;
228
229
 
229
230
  // Handle both old array format and new phases format
230
231
  if (Array.isArray(this.config)) {
@@ -237,6 +238,15 @@ export class Orchestrator {
237
238
  } else if (this.config.phases) {
238
239
  // New: Run phases sequentially, commands within phases in parallel
239
240
  for (const phase of this.config.phases) {
241
+ if (phaseFailed) {
242
+ // Mark all commands in remaining phases as skipped
243
+ phase.parallel.forEach(({ command }) => {
244
+ this.skippedCommands.push(command);
245
+ this.commandTimings.set(command, 0);
246
+ });
247
+ continue;
248
+ }
249
+
240
250
  this.logger.info(`\nšŸ”„ Starting phase: ${phase.name}`);
241
251
 
242
252
  const tasks = phase.parallel.map((commandConfig) =>
@@ -248,8 +258,8 @@ export class Orchestrator {
248
258
 
249
259
  if (phaseHasFailures) {
250
260
  hasFailures = true;
261
+ phaseFailed = true;
251
262
  this.logger.error(`āŒ Phase "${phase.name}" completed with failures`);
252
- break; // Stop executing remaining phases on failure
253
263
  } else {
254
264
  this.logger.success(`āœ… Phase "${phase.name}" completed successfully`);
255
265
  }
@@ -266,16 +276,32 @@ export class Orchestrator {
266
276
 
267
277
  this.summarizeResults();
268
278
 
269
- // Exit with appropriate status
279
+ // Cleanup before exit since finally blocks don't run after process.exit()
280
+ try {
281
+ await this.processManager.cleanup();
282
+ } catch (error) {
283
+ this.logger.error(`Cleanup failed: ${error.message}`);
284
+ }
285
+
286
+ // Force exit with appropriate status
270
287
  if (hasFailures) {
288
+ this.logger.info('Exiting with failure status...');
271
289
  process.exit(1);
290
+ } else {
291
+ this.logger.info('Exiting with success status...');
292
+ process.exit(0);
272
293
  }
273
- } finally {
294
+ } catch (error) {
295
+ this.logger.error(`Orchestrator failed: ${error.message}`);
296
+
297
+ // Cleanup on error
274
298
  try {
275
299
  await this.processManager.cleanup();
276
- } catch (error) {
277
- this.logger.error(`Cleanup failed: ${error.message}`);
300
+ } catch (cleanupError) {
301
+ this.logger.error(`Cleanup failed: ${cleanupError.message}`);
278
302
  }
303
+
304
+ process.exit(1);
279
305
  }
280
306
  }
281
307
  }
@@ -246,25 +246,29 @@ export class ProcessManager {
246
246
  }
247
247
 
248
248
  async cleanup() {
249
- this.logger.info('\nCleaning up background processes...');
249
+ try {
250
+ this.logger.info('\nCleaning up background processes...');
250
251
 
251
- // Debug: Log the number of processes we're tracking
252
- this.logger.info(`- Found ${this.backgroundProcessesDetails.length} background processes to clean up`);
252
+ // Debug: Log the number of processes we're tracking
253
+ this.logger.info(`- Found ${this.backgroundProcessesDetails.length} background processes to clean up`);
253
254
 
254
- // Debug: Log each process details
255
- this.backgroundProcessesDetails.forEach(({ command, pgid, url, startedByScript, kill_command }, index) => {
256
- this.logger.verbose(`- Process ${index + 1}: command=${command}, pgid=${pgid}, url=${url}, startedByScript=${startedByScript}, kill_command=${kill_command}`);
257
- });
255
+ // Debug: Log each process details
256
+ this.backgroundProcessesDetails.forEach(({ command, pgid, url, startedByScript, kill_command }, index) => {
257
+ this.logger.verbose(`- Process ${index + 1}: command=${command}, pgid=${pgid}, url=${url}, startedByScript=${startedByScript}, kill_command=${kill_command}`);
258
+ });
258
259
 
259
- const killPromises = this.backgroundProcessesDetails.map(
260
- async ({ command, pgid, url, startedByScript, kill_command }) => {
261
- await this.cleanupProcess({ command, pgid, url, startedByScript, kill_command });
262
- },
263
- );
260
+ const killPromises = this.backgroundProcessesDetails.map(
261
+ async ({ command, pgid, url, startedByScript, kill_command }) => {
262
+ await this.cleanupProcess({ command, pgid, url, startedByScript, kill_command });
263
+ },
264
+ );
264
265
 
265
- await Promise.all(killPromises);
266
- this.backgroundProcesses = [];
267
- this.backgroundProcessesDetails = [];
266
+ await Promise.allSettled(killPromises);
267
+ this.backgroundProcesses = [];
268
+ this.backgroundProcessesDetails = [];
269
+ } catch (error) {
270
+ this.logger.error(`Cleanup failed: ${error.message}`);
271
+ }
268
272
  }
269
273
 
270
274
  async cleanupCommand(commandName) {
@@ -288,7 +292,7 @@ export class ProcessManager {
288
292
  }
289
293
  );
290
294
 
291
- await Promise.all(killPromises);
295
+ await Promise.allSettled(killPromises);
292
296
 
293
297
  // Remove the cleaned up processes from our tracking arrays
294
298
  this.backgroundProcesses = this.backgroundProcesses.filter(pgid =>
@@ -359,17 +363,19 @@ export class ProcessManager {
359
363
  process.kill(pgid, 'SIGTERM');
360
364
 
361
365
  await new Promise((resolve, reject) => {
362
- const timeout = setTimeout(() => {
363
- clearInterval(checkInterval);
366
+ let timeout, checkInterval;
367
+
368
+ timeout = setTimeout(() => {
369
+ if (checkInterval) clearInterval(checkInterval);
364
370
  reject(new Error('Process termination timeout'));
365
371
  }, 5000);
366
372
 
367
- const checkInterval = setInterval(() => {
373
+ checkInterval = setInterval(() => {
368
374
  try {
369
375
  process.kill(pgid, 0);
370
376
  } catch (error) {
371
- clearInterval(checkInterval);
372
- clearTimeout(timeout);
377
+ if (checkInterval) clearInterval(checkInterval);
378
+ if (timeout) clearTimeout(timeout);
373
379
  resolve();
374
380
  }
375
381
  }, 100);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scripts-orchestrator",
3
- "version": "2.4.0",
3
+ "version": "2.4.2",
4
4
  "description": "A powerful script orchestrator for running parallel commands with dependency management, background processes, and health checks",
5
5
  "main": "lib/index.js",
6
6
  "type": "module",