prefix bash-task invocations with set -o pipefail

This commit is contained in:
damocles 2026-08-02 16:04:48 +02:00 committed by mara
commit 1aa88463a0

View file

@ -601,6 +601,16 @@ async fn run_task(mut task: TaskFile, socket: &Path) {
/// mode, which disables bashisms — arrays, `[[ … ]]`, `local`, process
/// substitution), invoked via `/usr/bin/env bash`.
///
/// The invocation is prefixed with `set -o pipefail` so a pipeline's exit
/// status reflects its last *failing* stage, not just its last stage — a
/// piped `cargo build 2>&1 | tail -40 && cargo test ...` chain silently
/// reports success off `tail`'s exit code otherwise, masking a real build
/// failure from every downstream `&&`/exit-code check. `-e`/`-u`/`-x` are
/// deliberately NOT forced on: unlike `pipefail` (a pure exit-status
/// reporting fix), each of those changes control flow or output volume in
/// ways plenty of ad-hoc one-liners don't expect — an opt-in a task's own
/// command string can request, not a safe default for every task.
///
/// The task is cancellable via `cancel` (set `force` first): on cancel the
/// whole process group is signalled — `SIGKILL` if `force`, else `SIGINT` —
/// so children of the shell die too, not just the shell. The timeout path
@ -622,7 +632,7 @@ async fn exec_cmd(
cmd_builder
.arg("bash")
.arg("-c")
.arg(cmd)
.arg(format!("set -o pipefail; {cmd}"))
.stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::piped());
// SAFETY: `setpgid`/`nice` are async-signal-safe and only touch the