Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/build-gossamer-gui.yml
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,9 @@ jobs:
if [ -z "$cli" ]; then
echo "::error::No ephapax CLI binary produced by 'cargo build --release --workspace'."
echo "Contents of $release_dir:"
ls -la "$release_dir" 2>/dev/null || true
# No mask: this branch fails either way, and a failing `ls`
# (missing dir) is itself the diagnosis, so let its error show.
ls -la "$release_dir"
exit 1
fi

Expand Down
18 changes: 14 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,20 @@ jobs:
# legitimately mention these tokens as documentation
# ("Zero believe_me." in src/Hypatia/ABI/RuleEngine.idr is the canonical
# example).
DANGEROUS=$(find lib src \( -name '*.idr' -o -name '*.v' -o -name '*.lean' -o -name '*.hs' \) \
-not -path 'lib/rules/*' \
-exec grep -Hn 'believe_me\|assert_total\|\bsorry\b\|\bAdmitted\b\|unsafeCoerce' {} + 2>/dev/null \
| grep -v ':[[:space:]]*--' || true)
#
# grep exits 1 when nothing matches, which is the PASS case, and 2
# on a real error. Test the status rather than masking both with
# `|| true` (`lib/rules` is the only `rules` directory under lib/src).
set -euo pipefail
status=0
HITS=$(grep -rHn --include='*.idr' --include='*.v' --include='*.lean' --include='*.hs' \
--exclude-dir=rules \
'believe_me\|assert_total\|\bsorry\b\|\bAdmitted\b\|unsafeCoerce' lib src) || status=$?
if [ "$status" -gt 1 ]; then
echo "FAIL: grep error (exit $status)"
exit "$status"
fi
DANGEROUS=$(printf '%s' "$HITS" | sed '/:[[:space:]]*--/d')
if [ -n "$DANGEROUS" ]; then
echo "FAIL: Dangerous patterns found"
echo "$DANGEROUS"
Expand Down
12 changes: 11 additions & 1 deletion lib/rules/research_extensions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,9 @@ defmodule Hypatia.Rules.ResearchExtensions do
suite goes green while real failures pile up. Provenance: Datadog
CI Visibility flake-masking patterns.

`|| true` on a `trap …` line is not counted: the handler runs after the
step's status is decided and cannot mask it.

Severity: `:warn`. Action: `:report`.
"""
def re005_test_swallows_exit(repo_path) do
Expand Down Expand Up @@ -619,7 +622,14 @@ defmodule Hypatia.Rules.ResearchExtensions do

has_continue_on_error? = Regex.match?(~r/continue-on-error:\s*true\b/, stripped_body)

has_or_true? = Regex.match?(~r/\|\|\s*true\b/, stripped_body)
# A `trap` handler's `|| true` is not a swallow. The step's exit status
# is decided before the EXIT trap runs, and a failing handler command
# under `set -e` (e.g. `kill` of an already-exited PID) would itself
# turn a PASSING step red, so the `|| true` is what keeps it honest.
has_or_true? =
stripped_body
|> String.replace(~r/^[ \t]*trap[ \t].*$/m, "")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve test commands embedded in trap handlers

When a test-named step puts the tested command inside a handler, such as trap 'cargo test || true' EXIT, deleting the entire trap line makes RE005 return no findings even though a failing test is swallowed and the shell exits successfully. The same blind spot applies to any real swallow placed after the trap command on that physical line, so the exemption should remove only verified cleanup-handler content rather than every line beginning with trap.

Useful? React with 👍 / 👎.

|> then(&Regex.match?(~r/\|\|\s*true\b/, &1))

# A step carrying `hypatia:ignore RE005 -- <reason>` (or the
# `hypatia: allow research_extensions/RE005` spelling) is reviewed —
Expand Down
35 changes: 35 additions & 0 deletions test/research_extensions_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,41 @@ defmodule Hypatia.Rules.ResearchExtensionsTest do
File.rm_rf!(repo)
end

test "ignores || true inside a trap handler (cleanup, not the step's status)" do
repo =
create_repo_with_workflow("""
jobs:
x:
steps:
- name: Test suite under stress
run: |
set -euo pipefail
stress-ng --cpu 4 &
STRESS_PID=$!
trap 'kill "$STRESS_PID" 2>/dev/null || true' EXIT
cargo test
""")

assert ResearchExtensions.re005_test_swallows_exit(repo) == []
File.rm_rf!(repo)
end

test "a trap does not hide a real swallow elsewhere in the step" do
repo =
create_repo_with_workflow("""
jobs:
x:
steps:
- name: Test suite under stress
run: |
trap 'kill "$PID" 2>/dev/null || true' EXIT
cargo test || true
""")

assert [%{rule: "RE005"}] = ResearchExtensions.re005_test_swallows_exit(repo)
File.rm_rf!(repo)
end

test "ignores non-test steps with continue-on-error" do
repo =
create_repo_with_workflow("""
Expand Down
Loading