Skip to content

Commit

Permalink
fix(core): run-commands should handle signals correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
jaysoo committed Dec 6, 2023
1 parent 3befa3a commit 2cb9f0d
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 5 deletions.
32 changes: 31 additions & 1 deletion e2e/nx-misc/src/extras.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import {
cleanupProject,
isNotWindows,
newProject,
readFile,
readJson,
runCLI,
runCommandUntil,
setMaxWorkers,
uniq,
updateFile,
readFile,
updateJson,
} from '@nx/e2e/utils';
import { join } from 'path';
Expand Down Expand Up @@ -265,6 +266,35 @@ describe('Extra Nx Misc Tests', () => {
runCLI(`build ${mylib}`);
checkFilesExist(`${folder}/dummy.txt`);
}, 120000);

it('should handle SIGTERM signal gracefully', async () => {
updateFile(
'main.js',
`
const fs = require('fs');
console.log('Started');
const t = setInterval(() => {
// Keep alive
}, 1000);
process.on('SIGTERM', () => {
fs.writeFileSync('exited.txt', '');
clearInterval(t);
});
`
);
runCLI(
`generate @nx/workspace:run-commands serve --command="node main.js" --project=${mylib}`
);

const p = await runCommandUntil(`serve ${mylib}`, (output) =>
output.includes('Started')
);
const exited = new Promise<void>((res) => p.on('exit', () => res()));

p.kill('SIGTERM');
await exited;
checkFilesExist('exited.txt');
});
});

describe('generate --quiet', () => {
Expand Down
14 changes: 10 additions & 4 deletions packages/nx/src/executors/run-commands/run-commands.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ async function loadEnvVars(path?: string) {
}
}

export type Json = { [k: string]: any };
export type Json = {
[k: string]: any;
};

export interface RunCommandsOptions extends Json {
command?: string;
Expand Down Expand Up @@ -65,13 +67,17 @@ export interface NormalizedRunCommandsOptions extends RunCommandsOptions {
command: string;
forwardAllArgs?: boolean;
}[];
parsedArgs: { [k: string]: any };
parsedArgs: {
[k: string]: any;
};
}

export default async function (
options: RunCommandsOptions,
context: ExecutorContext
): Promise<{ success: boolean }> {
): Promise<{
success: boolean;
}> {
await loadEnvVars(options.envFile);
const normalized = normalizeOptions(options);

Expand Down Expand Up @@ -215,7 +221,7 @@ function createProcess(
/**
* Ensure the child process is killed when the parent exits
*/
const processExitListener = (signal?: number | NodeJS.Signals) => () =>
const processExitListener = (signal?: number | NodeJS.Signals) =>
childProcess.kill(signal);

process.on('exit', processExitListener);
Expand Down

0 comments on commit 2cb9f0d

Please sign in to comment.