From dbbfa2536962ab193df4c06502d3a90f69d16672 Mon Sep 17 00:00:00 2001 From: Vijit Singh Date: Thu, 13 Aug 2026 07:36:14 -0500 Subject: [PATCH] fix(e2e): seed the checkout from the live release bundle, not the canonical checkout The canonical checkout's config.json/.env can drift far behind what's actually deployed (a release bumps config in the bundle dir, not in CANONICAL_DIR), so seeding the e2e checkout from canonical silently exercised and deployed a months-old config. Prefer the live bundle at the "current" symlink sibling of CANONICAL_DIR when it resolves, fall back to canonical when there's no live bundle, and warn loudly on either the fallback or a top-level-key mismatch between the two. Co-Authored-By: Claude Fable 5 --- tests/integration/e2e.sh | 37 +++++++++++++++++++++++++++++------ tests/integration/selftest.sh | 32 ++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/tests/integration/e2e.sh b/tests/integration/e2e.sh index d071e0da..5d931c2a 100755 --- a/tests/integration/e2e.sh +++ b/tests/integration/e2e.sh @@ -8,8 +8,9 @@ # What it does, end to end, then puts everything back the way it found it: # 1. Provisions a DEDICATED checkout on the test bench (/srv/code/pithead-e2e) — the canonical # /srv/code/pithead is the baseline and is never git-touched. -# 2. Fetches + checks out there, and seeds it with the canonical config.json/.env so -# it has the same wallet / secrets / onion keys / shared chains (just the branch's code). +# 2. Fetches + checks out there, and seeds it with the LIVE release bundle's config.json/.env +# (falling back to the canonical checkout's if there's no live bundle) so it has the same wallet / +# secrets / onion keys / shared chains (just the branch's code). # 3. Takes a `pithead backup` of the live stack (the rollback anchor). # 4. Borrows a miner (set MINER_HOST): backs up its xmrig config and repoints it at the test bench so # the live matrix has a real worker mining through this stack. @@ -332,10 +333,34 @@ provision() { head="$(on_bench "git -C '$E2E_DIR' rev-parse --short HEAD")" ok "e2e checkout on $BRANCH @ $head" - step "seeding the e2e checkout with the canonical config.json/.env (same wallet/secrets/chains)" - on_bench "cp -a '$CANONICAL_DIR/config.json' '$E2E_DIR/config.json' && cp -a '$CANONICAL_DIR/.env' '$E2E_DIR/.env'" || - die "Failed to seed config.json/.env into $E2E_DIR." - ok "config seeded (data dirs point at the shared chains)" + # Seed from the LIVE release bundle when one exists (#880): the canonical checkout's config can + # drift far behind what's actually deployed (a release bumps config.json/.env in the bundle dir, + # not in CANONICAL_DIR), so seeding from canonical silently exercises + deploys a stale config. + # The bundle lives at the "current" symlink sibling of CANONICAL_DIR (e.g. /srv/code/current). + local live_link live_cfg="" + live_link="$(dirname "$CANONICAL_DIR")/current" + on_bench "test -e '$live_link/config.json' -a -e '$live_link/.env'" && live_cfg="$live_link" + if [ -n "$live_cfg" ]; then + step "seeding the e2e checkout with the live bundle's config.json/.env ($live_cfg)" + on_bench "cp -a '$live_cfg/config.json' '$E2E_DIR/config.json' && cp -a '$live_cfg/.env' '$E2E_DIR/.env'" || + die "Failed to seed config.json/.env from $live_cfg into $E2E_DIR." + ok "config seeded from the live bundle (data dirs point at the shared chains)" + # Cheap drift check, not a full config differ: canonical is read-only and can lag the bundle + # for months, so a top-level-key diff is enough to catch a whole feature silently missing. + local live_keys canon_keys key_diff + live_keys="$(on_bench "jq -r 'keys[]' '$live_cfg/config.json' 2>/dev/null | sort")" + canon_keys="$(on_bench "jq -r 'keys[]' '$CANONICAL_DIR/config.json' 2>/dev/null | sort")" + key_diff="$(diff <(echo "$live_keys") <(echo "$canon_keys") 2>/dev/null)" + if [ -n "$key_diff" ]; then + warn "canonical config.json's top-level keys differ from the live bundle's ($live_cfg) — canonical is drifting:" + echo "$key_diff" | sed 's/^/ /' >&2 + fi + else + warn "no live bundle at $live_link — seeding from the canonical checkout ($CANONICAL_DIR) instead (may be stale)." + on_bench "cp -a '$CANONICAL_DIR/config.json' '$E2E_DIR/config.json' && cp -a '$CANONICAL_DIR/.env' '$E2E_DIR/.env'" || + die "Failed to seed config.json/.env into $E2E_DIR." + ok "config seeded from the canonical checkout (data dirs point at the shared chains)" + fi } # --- Phase 2: safety backup of the live stack ------------------------------- diff --git a/tests/integration/selftest.sh b/tests/integration/selftest.sh index 61e04e13..240a2af2 100755 --- a/tests/integration/selftest.sh +++ b/tests/integration/selftest.sh @@ -454,6 +454,38 @@ done if [ ! -e "$_gt/stray-cruft" ]; then it_pass "clean removes untracked cruft"; else it_fail "clean removes untracked cruft" "stray-cruft survived"; fi rm -rf "$_gt" +echo "== provision: seeds from the live bundle when one exists, else falls back to canonical (#880) ==" +# Mirrors e2e.sh provision()'s config-seeding selection + drift check, with plain dirs standing in +# for the on_bench SSH calls — the selection/diff logic itself is pure and needs no bench. +_sd="$(mktemp -d)" +_canon="$_sd/canonical" +_live="$_sd/current" +_e2e="$_sd/e2e" +mkdir -p "$_canon" "$_live" "$_e2e" +echo '{"monero":{},"dashboard":{}}' >"$_canon/config.json" +echo canon-env >"$_canon/.env" +echo '{"monero":{},"dashboard":{},"telegram":{}}' >"$_live/config.json" # live has a key canonical lacks +echo live-env >"$_live/.env" + +seed_from() { # -> copies into $_e2e, mirroring the cp -a pair in provision() + cp -a "$1/config.json" "$_e2e/config.json" && cp -a "$1/.env" "$_e2e/.env" +} + +# Live bundle present: seeds from it, and a top-level-key diff is non-empty (the drift signal). +seed_from "$_live" +assert_eq "seeds config.json from the live bundle" "$(cat "$_e2e/config.json")" "$(cat "$_live/config.json")" +assert_eq "seeds .env from the live bundle" "$(cat "$_e2e/.env")" "live-env" +_kd="$(diff <(jq -r 'keys[]' "$_live/config.json" | sort) <(jq -r 'keys[]' "$_canon/config.json" | sort))" +if [ -n "$_kd" ]; then it_pass "drift check flags canonical missing a live key"; else it_fail "drift check flags canonical missing a live key" "no diff reported"; fi + +# No live bundle (symlink missing/broken): falls back to canonical, and there's nothing to diff. +rm -rf "$_live" +[ -e "$_live/config.json" ] && [ -e "$_live/.env" ] && it_fail "no-live-bundle detection" "should be absent" || it_pass "no-live-bundle detection treats missing dir as absent" +seed_from "$_canon" +assert_eq "falls back to seeding config.json from canonical" "$(cat "$_e2e/config.json")" "$(cat "$_canon/config.json")" +assert_eq "falls back to seeding .env from canonical" "$(cat "$_e2e/.env")" "canon-env" +rm -rf "$_sd" + # --- Tally ------------------------------------------------------------------ echo "" echo "selftest: $IT_PASS passed, $IT_FAIL failed"