From 9cd51cac2e64aacfe812be7ee5be2cab94c55d20 Mon Sep 17 00:00:00 2001 From: Aleksei Sviridkin Date: Mon, 9 Nov 2026 18:38:56 +0300 Subject: [PATCH] ci(e2e): skip final cleanup on disposable PR runners Destroying runner-local state after a completed suite can push the job past its deadline even though the runner is discarded. Keep cleanup between preparation attempts and for reused hosts instead. Fixes: 186547d835cc ("test(e2e): run the merge-gating lanes on Talos containers") Assisted-by: LLM Signed-off-by: Aleksei Sviridkin --- .github/workflows/e2e-fork.yaml | 15 -------------- .github/workflows/pull-requests.yaml | 22 -------------------- hack/cozyreport.bats | 31 ++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 37 deletions(-) diff --git a/.github/workflows/e2e-fork.yaml b/.github/workflows/e2e-fork.yaml index df6ed1268..f988632e9 100644 --- a/.github/workflows/e2e-fork.yaml +++ b/.github/workflows/e2e-fork.yaml @@ -771,21 +771,6 @@ jobs: name: cozyreport path: _out/cozyreport.tgz if-no-files-found: warn - # Both halves, and in this order: the compose project owns the nodes and - # the zpools outlive it. - - name: Tear down sandbox - if: always() - run: | - # Annotated, not fatal: same reasoning as the in-tree lane. The runner - # is discarded after the job, so a dirty host has no next tenant, and - # failing here would post the required "E2E Tests" status as a failure - # indistinguishable from a real one. - cleanup_rc=0 - make -C packages/core/testing SANDBOX_NAME=$SANDBOX_NAME delete-cluster-container || cleanup_rc=$? - make -C packages/core/testing SANDBOX_NAME=$SANDBOX_NAME delete || true - if [ "$cleanup_rc" -ne 0 ]; then - echo "::error title=sandbox teardown::teardown exited $cleanup_rc; the host may hold a stale compose project or zpool" - fi # Flip the pending "E2E Tests" commit status posted by `resolve` to its # terminal state. Runs on failure too, so a failed publish or e2e turns the diff --git a/.github/workflows/pull-requests.yaml b/.github/workflows/pull-requests.yaml index b8b06fedf..7d3787ff9 100644 --- a/.github/workflows/pull-requests.yaml +++ b/.github/workflows/pull-requests.yaml @@ -1348,28 +1348,6 @@ jobs: Resume from inside: `breakpoint resume`. Otherwise the breakpoint exits 10 minutes after the last SSH session disconnects. - # ▸ Tear down environment (always runs) - # - # Both halves, and in this order: the compose project owns the nodes and - # the zpools outlive it. A leftover pool makes the next run on a reused - # host adopt storage that already carries a dead cluster's volumes. - - name: Tear down sandbox - if: always() - run: | - # Loud, but never the job's verdict. A failed teardown means a dirty - # host, and this runner is discarded after the job, so there is no next - # run to protect -- while failing the job here posts the required - # "E2E Tests" status as a failure that no reader can tell apart from a - # real one. The annotation is what a reused host (a developer machine) - # needs; `delete-cluster-container` returning non-zero is not evidence - # about the product. - cleanup_rc=0 - make -C packages/core/testing SANDBOX_NAME=$SANDBOX_NAME delete-cluster-container || cleanup_rc=$? - make -C packages/core/testing SANDBOX_NAME=$SANDBOX_NAME delete || true - if [ "$cleanup_rc" -ne 0 ]; then - echo "::error title=sandbox teardown::teardown exited $cleanup_rc; the host may hold a stale compose project or zpool" - fi - # Report the required "E2E Tests" gate as a commit status rather than relying # on a job named "E2E Tests". A required *job* that is skipped counts # as PASSED by branch protection — desired for docs-only PRs, but the exact diff --git a/hack/cozyreport.bats b/hack/cozyreport.bats index cc2668071..ee8911080 100644 --- a/hack/cozyreport.bats +++ b/hack/cozyreport.bats @@ -966,6 +966,37 @@ STUB } } +@test "PR E2E jobs clean up between preparation attempts but not after testing" { + tmp="$(mktemp -d)" + mkdir -p "$tmp/bin" + cat >"$tmp/bin/make" <<'STUB' +#!/bin/sh +printf '%s\n' "$*" >>"$CLEANUP_CALLS" +case "$*" in + *prepare-env-container*) + if [ ! -f "$CLEANUP_ATTEMPT" ]; then + touch "$CLEANUP_ATTEMPT" + exit 1 + fi + ;; +esac +STUB + chmod +x "$tmp/bin/make" + for wf in pull-requests e2e-fork; do + workflow="$HACK_DIR/../.github/workflows/$wf.yaml" + yq --unwrapScalar '.jobs.e2e.steps[] | select(.name == "Prepare environment") | .run' "$workflow" >"$tmp/prepare.sh" + CLEANUP_CALLS="$tmp/$wf.calls" CLEANUP_ATTEMPT="$tmp/$wf.attempt" SANDBOX_NAME=test PATH="$tmp/bin:$PATH" bash -eu "$tmp/prepare.sh" + printf '%s\n' 'SANDBOX_NAME=test prepare-env-container' '-C packages/core/testing SANDBOX_NAME=test delete-cluster-container' 'SANDBOX_NAME=test prepare-env-container' >"$tmp/expected" + diff "$tmp/expected" "$tmp/$wf.calls" + scripts="$(yq --unwrapScalar '.jobs.e2e.steps[] | select(.name != "Prepare environment") | .run // ""' "$workflow")" + if printf '%s\n' "$scripts" | grep -Eq 'delete-cluster-container|docker[[:space:]]+(compose.*down|rm)|zpool[[:space:]]+destroy|make.*[[:space:]]delete([[:space:]]|$)'; then + echo "FAIL: $wf destroys runner-local state outside preparation" + false + fi + done + rm -rf "$tmp" +} + @test "the step that runs this collector has a ceiling of its own everywhere" { # Every bound inside the script protects one read. None of them protects the # STEP: the tarball is written on the collector's last line, the upload is the