Repository navigation
feat(hooks): bound every hook with a timeout and close its stdin - #1300
Conversation
There was a problem hiding this comment.
One blocking finding: on unix, kill_tree shells out to kill instead of calling libc::kill. The repo already depends on libc and uses it in lock.rs, and if the binary is missing the hook's children survive. There's a suggestion inline. Three nits: the timeout doesn't cover pipe draining after the hook exits, Ctrl+C now leaves hooks orphaned, and timeout = 0 gets past serde. Apart from that the timeout resolution, the closed stdin and the tests look right.
There was a problem hiding this comment.
bf118d3 fixes all four earlier findings, including the blocking one: kill_tree now uses libc::kill on the group, the drain respects the deadline, timeout is NonZeroU64, and the Ctrl+C trade-off is documented. One new nit: the docs say a hook orphaned by Ctrl+C is still bounded by its timeout. It isn't, because the deadline dies with FerrFlow.
Closes #801
A hook that never returned held the release, and
.git/ferrflow.lock, until the CI job died on its wall-clock limit, with no output in the non-verbose path to say which hook it was.timeoutinhooks, in seconds, at workspace or package level (package wins), default 900. It sits next toonFailureand resolves the same way, through a newHookPolicythatrun_hooknow takes instead of a bareOnFailure.kill -KILL -<pgid>on Unix,taskkill /T /Fon Windows) and reported ashook [x] failed (timed out after Ns), soonFailureapplies as usual.onErrorkeeps forcingcontinue./dev/nullfor every hook, which turns thenpm login/gpgpassphrase / git credential prompt cases into an immediate failure.[point] still running after Nsevery minute. Output is captured on separate threads, so a chatty hook cannot fill a pipe and deadlock the wait.src/hooks/runner/process.rs;runner.rskeeps the hook logic.Schema (
schema/and its mirror underdocs/site/data/schema/) and the EN/FR config docs describetimeoutand the closed stdin.One trade-off: on Unix the hook now runs in its own process group so the whole tree can be killed. A Ctrl+C on the terminal running
ferrflow releasetherefore no longer reaches the hook directly. In CI that does not matter; interactively the hook is still bounded by its timeout.Tests: a hook past its timeout is killed and reported with E6001 well before its own sleep ends;
continueon a timed-out hook keeps the release going; a hook reading stdin gets EOF; on Unix, a background child started by the hook does not outlive the kill. Plus timeout resolution (default, workspace, package override). Full suite passes locally.