scripts-orchestrator 2.3.0 ā 2.4.1
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/lib/orchestrator.js +11 -1
- package/lib/process-manager.js +39 -0
- package/package.json +1 -1
package/lib/orchestrator.js
CHANGED
|
@@ -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
|
}
|
package/lib/process-manager.js
CHANGED
|
@@ -76,6 +76,16 @@ export class ProcessManager {
|
|
|
76
76
|
const processGroupId = processInstance.pid;
|
|
77
77
|
this.logger.verbose(`Background process spawned with PID: ${processGroupId}`);
|
|
78
78
|
|
|
79
|
+
// Track process exit for background processes
|
|
80
|
+
let processExited = false;
|
|
81
|
+
let processExitCode = null;
|
|
82
|
+
|
|
83
|
+
processInstance.on('exit', (code, signal) => {
|
|
84
|
+
processExited = true;
|
|
85
|
+
processExitCode = code;
|
|
86
|
+
this.logger.verbose(`Background process ${cmd} (PID: ${processGroupId}) exited with code: ${code}, signal: ${signal}`);
|
|
87
|
+
});
|
|
88
|
+
|
|
79
89
|
processInstance.stdout.on('data', (data) => {
|
|
80
90
|
try {
|
|
81
91
|
fs.appendFileSync(LOG_FILE, data.toString());
|
|
@@ -98,10 +108,39 @@ export class ProcessManager {
|
|
|
98
108
|
|
|
99
109
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
100
110
|
try {
|
|
111
|
+
// First check if the process has already exited with an error
|
|
112
|
+
if (processExited && processExitCode !== 0) {
|
|
113
|
+
this.logger.error(`Background process ${cmd} exited with code ${processExitCode}`);
|
|
114
|
+
let output = '';
|
|
115
|
+
try {
|
|
116
|
+
output = fs.readFileSync(LOG_FILE, 'utf8');
|
|
117
|
+
this.logger.verbose(`Process output: ${output}`);
|
|
118
|
+
} catch (error) {
|
|
119
|
+
this.logger.error(`Failed to read log file: ${error.message}`);
|
|
120
|
+
}
|
|
121
|
+
return { success: false, output };
|
|
122
|
+
}
|
|
123
|
+
|
|
101
124
|
this.logger.verbose(`Verifying process ${processGroupId} (attempt ${attempt}/${maxAttempts})`);
|
|
102
125
|
process.kill(processGroupId, 0);
|
|
103
126
|
this.logger.verbose(`Process ${processGroupId} is running`);
|
|
104
127
|
|
|
128
|
+
// Wait a bit more to ensure the process doesn't exit immediately after verification
|
|
129
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
130
|
+
|
|
131
|
+
// Check again if the process exited during our wait
|
|
132
|
+
if (processExited && processExitCode !== 0) {
|
|
133
|
+
this.logger.error(`Background process ${cmd} exited with code ${processExitCode} shortly after starting`);
|
|
134
|
+
let output = '';
|
|
135
|
+
try {
|
|
136
|
+
output = fs.readFileSync(LOG_FILE, 'utf8');
|
|
137
|
+
this.logger.verbose(`Process output: ${output}`);
|
|
138
|
+
} catch (error) {
|
|
139
|
+
this.logger.error(`Failed to read log file: ${error.message}`);
|
|
140
|
+
}
|
|
141
|
+
return { success: false, output };
|
|
142
|
+
}
|
|
143
|
+
|
|
105
144
|
this.backgroundProcesses.push(processGroupId);
|
|
106
145
|
this.backgroundProcessesDetails.push({
|
|
107
146
|
command: cmd,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scripts-orchestrator",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.1",
|
|
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",
|