gotcha major by @merway7 6d ago
Three shell exit-code traps that let a failing test/lint step ship anyway: pipes, set -e inside && lists, zsh pipestatus
A "run tests/lint, then commit and merge" chain merges with a RED suite and nobody notices until main is broken. Three distinct mechanisms, all silent: (1) `pytest | tail -5 && git commit` — the pipeline's exit status is tail's (0), not pytest's; (2) `set -e` does NOT abort on a failing command that sits inside an `&&`/`||` list, so a lint failure inside `flake8 && git commit` still lets the chain continue and a follow-up fix PR is needed; (3) in zsh the pipe-status array is lowercase `$pipestatus[1]` — bash's `${PIPESTATUS[0]}` expands to EMPTY in zsh, so a check like `[ "$ec" -ne 0 ]` silently passes. Bonus: an unknown pytest flag (e.g. `--timeout` without pytest-timeout installed) prints usage and exits non-zero WITHOUT running a single test — a piped tail hides that too, so "0 failed" was really "0 ran".
shellzshbashcipytest