This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch ci-issue/reactor-timing-sigpipe in repository https://gitbox.apache.org/repos/asf/camel.git
commit 584f84a788374147c91aaadeb5795416fa9d378b Author: Claus Ibsen <[email protected]> AuthorDate: Thu Oct 1 07:24:34 2026 +0200 ci: limit the slowest modules with awk, not head, so sort does not fail the build render_top_slowest_modules piped sort into head -n. incremental-build.sh ignores SIGPIPE (trap '' PIPE, CAMEL-24777), so once head stops reading, sort gets EPIPE, prints "sort: write error" and exits 2; under pipefail that fails the job after a successful Maven build. awk reads all of its input, so the pipeline completes. A test runs a large reactor through the function with SIGPIPE ignored. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .github/actions/incremental-build/reactor_timing.sh | 5 ++++- .github/actions/incremental-build/reactor_timing_test.sh | 12 ++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/actions/incremental-build/reactor_timing.sh b/.github/actions/incremental-build/reactor_timing.sh index 291132cdb2c0..8d60ae9a1e26 100644 --- a/.github/actions/incremental-build/reactor_timing.sh +++ b/.github/actions/incremental-build/reactor_timing.sh @@ -133,10 +133,13 @@ sum_elapsed_seconds_from_tsv() { render_top_slowest_modules() { local tsv="$1" local limit="${2:-${TOP_SLOWEST_LIMIT}}" + # Limit with awk, which reads all its input, not head: incremental-build.sh + # ignores SIGPIPE, so sort fails with a write error once head stops reading, + # and pipefail turns that into a failed build (CAMEL-24777). echo "$tsv" | awk -F '\t' ' $2 != "" && $2 ~ /^[0-9]+(\.[0-9]+)?$/ { printf "%s\t%s\n", $2, $1 - }' | sort -t $'\t' -k1,1nr | head -n "$limit" | while IFS=$'\t' read -r seconds module; do + }' | sort -t $'\t' -k1,1nr | awk -v n="$limit" 'NR <= n' | while IFS=$'\t' read -r seconds module; do local formatted formatted=$(format_elapsed_seconds "$seconds") echo "- \`${module}\` (${formatted})" diff --git a/.github/actions/incremental-build/reactor_timing_test.sh b/.github/actions/incremental-build/reactor_timing_test.sh index c1e39b5c5c80..a878f996562b 100755 --- a/.github/actions/incremental-build/reactor_timing_test.sh +++ b/.github/actions/incremental-build/reactor_timing_test.sh @@ -115,6 +115,18 @@ append_reactor_timing_report "$empty_fixture" "$empty_report" "All tested module assert_eq "" "$(cat "$empty_report")" "empty log yields empty report" rm -f "$empty_fixture" "$empty_report" +# A large reactor with SIGPIPE ignored, as incremental-build.sh runs it: limiting +# the slowest modules must not fail the pipeline (CAMEL-24777) +large_tsv="$(seq 1 50000 | awk '{ printf "module-%d\t%d\tSUCCESS\n", $1, $1 }')" +if large_slowest="$(trap '' PIPE; render_top_slowest_modules "$large_tsv" 3 2>&1)"; then + pass=$((pass + 1)) +else + echo "FAIL: render_top_slowest_modules fails on a large reactor with SIGPIPE ignored" + fail=$((fail + 1)) +fi +assert_eq "3" "$(echo "$large_slowest" | grep -c .)" "large reactor lists only the limit" +assert_contains "$large_slowest" "\`module-50000\`" "large reactor lists the slowest module first" + echo "" echo "reactor_timing_test.sh: ${pass} passed, ${fail} failed" if [[ "$fail" -ne 0 ]]; then
