fix(merge): round-2 CI failures — pipefail sites, verify:release mirror, format
ci/woodpecker/pr/ci Pipeline failed

Pipeline 2534 (018d96a), two test-step failures plus the format failure
root-caused by rev-code-01 (id 202):

1. pipefail-early-exit.test.mjs: main's window wrote the test but never
   wired scripts/*.test.mjs into its own CI, so its tools/install.sh pipes
   were never executed against it; next's test wiring runs them and flags
   two load-bearing pipes. Both rewritten pipefail-safe via process
   substitution (newest_matching_file ls|head, check_fleet_transport
   sed|head|tr|awk). Test now 7/7 locally.

2. verify-release.test.mjs: merge kept main's 9-command ci.yml sanitization
   but next's 4-command canonical stage. Canonical updated to mirror ci.yml
   exactly (9=9, order verified). upgrade-guard checked equal (4=4).

3. format: docs/reports/quality/1099-pipefail-sweep.md (from main f158be8)
   prettier-formatted under pinned 3.8.1.

Enumeration guard re-verified: population 60, enumerated 45, excluded 16.
This commit is contained in:
2026-08-19 17:27:30 -05:00
parent 018d96a412
commit 2508f0aa99
3 changed files with 82 additions and 64 deletions
+17 -4
View File
@@ -161,7 +161,11 @@ newest_matching_file() {
shopt -u nullglob
[[ "${#matches[@]}" -gt 0 ]] || return 0
# shellcheck disable=SC2012 # Need portable mtime sorting across Linux/macOS.
ls -1t "${matches[@]}" 2>/dev/null | head -1
# pipefail-safe: take the first line via process substitution; piping into
# an early-exiting consumer would inherit ls's exit status under pipefail (#1099).
local newest=""
while IFS= read -r newest; do break; done < <(ls -1t "${matches[@]}" 2>/dev/null)
if [[ -n "$newest" ]]; then printf '%s\n' "$newest"; fi
}
# ─── uninstall path ───────────────────────────────────────────────────────────
@@ -413,9 +417,18 @@ check_fleet_transport() {
local declared=""
if [[ -f "$roster" ]]; then
declared="$(sed -n 's/^[[:space:]]*transport:[[:space:]]*//p' "$roster" | head -1 |
tr -d '"'\''' | tr -d '\r' | awk '{print $1}')"
[[ -n "$declared" ]] && transport="$declared"
# pipefail-safe: consume the first match via process substitution, then
# strip quotes/CR and keep the first field without piping into a consumer (#1099).
local first_transport=""
while IFS= read -r first_transport; do break; done < \
<(sed -n 's/^[[:space:]]*transport:[[:space:]]*//p' "$roster")
if [[ -n "$first_transport" ]]; then
declared="${first_transport//\"/}"
declared="${declared//\'/}"
declared="${declared//$'\r'/}"
declared="${declared%%[[:space:]]*}"
[[ -n "$declared" ]] && transport="$declared"
fi
fi
command -v "$transport" &>/dev/null && return 0