From 752868b04351403e6c444ef1238856306b97d6f9 Mon Sep 17 00:00:00 2001 From: John McLear Date: Tue, 9 Jun 2026 13:55:46 +0100 Subject: [PATCH 1/3] ci(downstream): robust per-client error handling in run-clients.sh (Qodo) - Move clone/fetch/checkout inside the per-client guarded block with explicit '|| exit 1' on every step. set -e is suspended inside a subshell used as an '||' operand, so relying on it silently swallowed clone/checkout failures (and continued from the wrong cwd); explicit guards make one client's failure a per-client fail=1 while the loop continues, and the run exits non-zero. - Stop suppressing fetch errors; fetch only when the pinned commit isn't already reachable, and surface the real error. - Run manifest commands via 'bash -c' instead of 'eval' (trusted in-repo allowlist; avoids double-parsing / leaking into this script's shell). Verified: two bogus clients -> both reported, loop continues, exit 1; happy path (cli, no server) -> vectors pass, smoke skips, exit 0. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/tests/downstream/run-clients.sh | 35 +++++++++++++++++++---------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/tests/downstream/run-clients.sh b/src/tests/downstream/run-clients.sh index 4ffa7e9a51c..53070174347 100755 --- a/src/tests/downstream/run-clients.sh +++ b/src/tests/downstream/run-clients.sh @@ -46,28 +46,39 @@ fail=0 while IFS=$'\t' read -r name repo ref kind vectorTest smokeCmd; do echo "::group::$name ($kind) @ ${ref:0:12}" dir="$WORK/$name" - git clone --quiet "$repo" "$dir" - # Fetch the exact pinned commit (works even when it is not a branch tip). - git -C "$dir" fetch --quiet origin "$ref" 2>/dev/null || true - git -C "$dir" checkout --quiet "$ref" - + # Everything — clone, checkout, AND the tests — runs inside one guarded + # subshell so a single client's failure becomes a per-client failure (fail=1) + # and the loop continues to the rest. NOTE: `set -e` is suspended inside a + # subshell used as an `||` operand, so every step is guarded with an explicit + # `|| exit 1` rather than relying on `set -e`. The manifest commands are a + # trusted in-repo allowlist; running them via `bash -c` (not `eval`) keeps + # them out of this script's own shell. ( - cd "$dir" + git clone --quiet "$repo" "$dir" || exit 1 + # A default clone has all branch heads; fetch the pinned commit only if it + # is not already reachable (e.g. a non-branch-tip SHA). Fetch errors are + # NOT suppressed so the real cause surfaces instead of a vague checkout fail. + if ! git -C "$dir" cat-file -e "${ref}^{commit}" 2>/dev/null; then + git -C "$dir" fetch --quiet origin "$ref" || exit 1 + fi + git -C "$dir" checkout --quiet "$ref" || exit 1 + + cd "$dir" || exit 1 case "$kind" in rust) - eval "$vectorTest" - eval "$smokeCmd" + bash -c "$vectorTest" || exit 1 + bash -c "$smokeCmd" || exit 1 ;; node|desktop) - pnpm install - eval "$vectorTest" - eval "$smokeCmd" + pnpm install || exit 1 + bash -c "$vectorTest" || exit 1 + bash -c "$smokeCmd" || exit 1 ;; *) echo "::error::unknown client kind: $kind"; exit 1 ;; esac - ) || { echo "::error::downstream client '$name' failed"; fail=1; } + ) || { echo "::error::downstream client '$name' failed (clone/checkout/test)"; fail=1; } echo "::endgroup::" done < "$WORK/clients.tsv" From 3315065b3284e86a0fb7500b225434165654307e Mon Sep 17 00:00:00 2001 From: John McLear Date: Tue, 9 Jun 2026 14:08:25 +0100 Subject: [PATCH 2/3] ci(downstream): pin clients to their merged-commit SHAs The three client Phase-2 PRs merged; bump each manifest ref from its pre-merge PR-branch tip (now deleted / unfetchable) to its squash-merge commit on main: etherpad-pad -> 91620c6 (ether/pad#1) etherpad-cli-client -> ebc516e (ether/etherpad-cli-client#136) etherpad-desktop -> ab83da6 (ether/etherpad-desktop#78) Verified each merged main carries the test entry points (vectors.rs/smoke.rs; test:vectors/test:smoke scripts). Co-Authored-By: Claude Opus 4.8 (1M context) --- src/tests/downstream/clients.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tests/downstream/clients.json b/src/tests/downstream/clients.json index 82a9c997ae7..b4013a72f22 100644 --- a/src/tests/downstream/clients.json +++ b/src/tests/downstream/clients.json @@ -2,7 +2,7 @@ { "name": "etherpad-pad", "repo": "https://github.com/ether/pad.git", - "ref": "ada8cafd33b4ab31206226b4c3db80b2aa00125a", + "ref": "91620c67c49536bb77e90b39f298ea70ae93c4a0", "kind": "rust", "enabled": true, "vectorTest": "cargo test --test vectors", @@ -11,7 +11,7 @@ { "name": "etherpad-cli-client", "repo": "https://github.com/ether/etherpad-cli-client.git", - "ref": "e4b4643c7185c2059375c430e07ca2e65d01999a", + "ref": "ebc516ef1a4e7a0c97ccd7a3f2db65e99f8e177c", "kind": "node", "enabled": true, "vectorTest": "pnpm run test:vectors", @@ -20,7 +20,7 @@ { "name": "etherpad-desktop", "repo": "https://github.com/ether/etherpad-desktop.git", - "ref": "9e02fd06b2be3f0eeb91d636b7bddc547210399d", + "ref": "ab83da645b8683afbbc203e4a3fa6f3622a55709", "kind": "desktop", "enabled": true, "vectorTest": "pnpm run test:vectors", From a3008804c5546c72e7bfe9b7637a3189ce2788d2 Mon Sep 17 00:00:00 2001 From: John McLear Date: Tue, 9 Jun 2026 14:11:55 +0100 Subject: [PATCH 3/3] ci(downstream): run manifest commands under bash strict mode (Qodo) bash -c spawns a fresh shell without -e/-u/-o pipefail, so a pipeline-stage failure inside a client's vectorTest/smokeCmd could be masked. Use 'bash -euo pipefail -c' so those failures surface as a non-zero exit. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/tests/downstream/run-clients.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/tests/downstream/run-clients.sh b/src/tests/downstream/run-clients.sh index 53070174347..e2f3868208f 100755 --- a/src/tests/downstream/run-clients.sh +++ b/src/tests/downstream/run-clients.sh @@ -51,8 +51,9 @@ while IFS=$'\t' read -r name repo ref kind vectorTest smokeCmd; do # and the loop continues to the rest. NOTE: `set -e` is suspended inside a # subshell used as an `||` operand, so every step is guarded with an explicit # `|| exit 1` rather than relying on `set -e`. The manifest commands are a - # trusted in-repo allowlist; running them via `bash -c` (not `eval`) keeps - # them out of this script's own shell. + # trusted in-repo allowlist; running them via `bash -euo pipefail -c` (not + # `eval`) keeps them out of this script's own shell and applies strict mode + # (pipeline-stage failures surface) inside the child. ( git clone --quiet "$repo" "$dir" || exit 1 # A default clone has all branch heads; fetch the pinned commit only if it @@ -66,13 +67,13 @@ while IFS=$'\t' read -r name repo ref kind vectorTest smokeCmd; do cd "$dir" || exit 1 case "$kind" in rust) - bash -c "$vectorTest" || exit 1 - bash -c "$smokeCmd" || exit 1 + bash -euo pipefail -c "$vectorTest" || exit 1 + bash -euo pipefail -c "$smokeCmd" || exit 1 ;; node|desktop) pnpm install || exit 1 - bash -c "$vectorTest" || exit 1 - bash -c "$smokeCmd" || exit 1 + bash -euo pipefail -c "$vectorTest" || exit 1 + bash -euo pipefail -c "$smokeCmd" || exit 1 ;; *) echo "::error::unknown client kind: $kind"; exit 1