@netlify/build
Version:
Netlify build module
70 lines (69 loc) • 2.92 kB
JavaScript
import psList from 'ps-list';
import { logLingeringProcesses } from '../log/messages/core.js';
// Print a warning when some build processes are still running.
// We cannot rely on using the process tree:
// - This is because it is impossible to know whether a process was a child of
// another once its parent process has exited. When that happens, the s
// child becomes inherited by `init`, changing its `ppid`. The information
// about the original parent is then lost.
// - The only way to implement this would be to repeatedly list processes as
// the build command is ongoing. However, this would fail to detect processes
// spawned just before the build commands ends.
// We cannot list processes before and after the build command and use the
// difference.
// - This is because other processes (unrelated to @netlify/build) might be
// running at the same time. This includes OS background processes.
// Therefore, we run this in a controlled environment only (the buildbot) and
// exclude specific processes manually. This is a lesser evil, although still
// quite hacky.
export const warnOnLingeringProcesses = async function ({ mode, logs, testOpts: { silentLingeringProcesses = false }, }) {
if (mode !== 'buildbot' || silentLingeringProcesses) {
return;
}
const processes = await psList();
const commands = processes.map(getCommand).filter(isNotIgnoredCommand);
if (commands.length === 0) {
return;
}
logLingeringProcesses(logs, commands);
};
// `cmd` is only available on Unix. Unlike `name`, it includes the arguments.
const getCommand = function ({ name, cmd = name }) {
return cmd;
};
// We ignore any command known to be internal to the buildbot.
// We also ignore commands known not to complete properly in builds if they are
// widely used.
const isNotIgnoredCommand = function (command) {
return !IGNORED_COMMANDS.some((ignoredCommand) => matchesIgnoredCommand(command, ignoredCommand));
};
const matchesIgnoredCommand = function (command, ignoredCommand) {
if (typeof ignoredCommand === 'string') {
return command.includes(ignoredCommand);
}
return ignoredCommand.test(command);
};
const IGNORED_COMMANDS = [
// TODO: Those can most likely be removed
'ps',
'grep',
'bash',
// Internal buildbot commands
'[build]',
'sleep 5',
/buildbot.*\[node]/,
// buildbot's main Bash script
'/opt/build-bin/build',
// `@netlify/build` binary itself
'netlify-build',
// Plugin child processes spawned by @netlify/build
'@netlify/build',
// Shown for parent processes with currently running child processes.
// Happens on `ps` itself.
'defunct',
// Processes often left running. We should report those but don't because of
// how common those are in production builds
'gatsby-telemetry',
'jest-worker',
'broccoli-babel-transpiler',
];