Uh oh!
There was an error while loading. Please reload this page.
ci(e2e): give E2E auth-proxy (squid) its own always-reporting workflow (backend#2350) - #867
Conversation
…w (backend#2350) The auth-proxy E2E shipped RED to staging on client#789 and blocked nothing because it lived in installer-tests.yaml — an expensive, path-filtered workflow whose jobs can never be required status checks (a required check behind a paths filter never reports on a PR outside its paths, so GitHub holds the PR at "waiting for status to be reported" forever; a guard that cannot block is advice, not a gate — backend#1729). Root cause of the red itself was diagnosed and already fixed on develop: the squid probe's curl --retry was inert against curl's negative-DNS cache (#811), and the probe/squid/nginx images are pinned (#813). This change does the remaining enablement so the check can actually gate. Extract the e2e-proxy job into e2e-auth-proxy.yaml, mirroring the move Source-of-truth drift made out of installer-tests' old static job: - pull_request has NO paths filter, so the context always reports and can be required on staging/main without deadlocking a promotion PR that touches no scripts/ file (backmerge, hotfix lane, version-bump promotion). - push keeps a paths filter (pushes aren't gated) and adds staging; the Monday cron is preserved so extracting the job doesn't drop its weekly canary. - job name 'E2E auth-proxy (squid)' is unchanged, so the required-context name and the release train's by-name check reading are preserved. Arming it as a required check on staging + main is a follow-up branch-protection setting, to be flipped after a green-watch window (arm while green). See backend#2350. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
saadqbal
left a comment
There was a problem hiding this comment.
The diagnosis is the best part and it's worth restating for anyone skimming: --retry-all-errors retried nine times and asked the resolver once. curl's process-lifetime negative-DNS cache served every subsequent attempt from the first failure — * Negative DNS entry in the log is the tell — so a retry loop that looked like resilience was replaying a single answer taken ~1s after pod start. A retry that cannot observe the thing it's retrying against isn't a retry, and #811 fixing it with a fresh process per attempt is the only shape that works.
Separating node-level from in-cluster egress is what makes the verdict trustworthy: TCP_TUNNEL/200 CONNECT auth.docker.io:443 tbuser proves squid tunnelled fine, so the failure was never the proxy. And the history is a real control rather than a vibe — 28/2 over 30 runs, continuously green since ebb84b13, and the 19:57 develop run carried more Collector code than the promotion did and was green. A regression would be a wall of red; two isolated failures with green either side is a flake. Gathering that from the runs rather than the issue thread is the difference between a verdict and a repetition.
"An intermittent false red in a non-required job — the shape that never gets diagnosed because each instance is individually dismissible" is the sentence I'd put in a retro. That's why this sat since 22 Aug.
The enablement design is the load-bearing bit and it's right. No paths: on pull_request, because a required check behind a paths filter simply never reports on a PR that touches nothing under it — the check sits "Expected" and the PR can never merge. Keeping paths: on push is the correct asymmetry, since pushes aren't gated by required checks and there's no reason to spend the minutes. Both stated at the top of the file rather than left for someone to rediscover.
And the job name is preserved, so the check context stays E2E auth-proxy (squid). That's the third time this week a PR has had to think about required-context stability — backend#2655 left a job name alone for the same reason, and .github#337 was about a cosmetic name: silently renaming a reusable-workflow context. It keeps nearly costing someone a repo-wide block.
Documenting the branch-protection flip in the PR description because the issue closes on merge is the right instinct — that step has no other home once #2350 is shut, and "deferred to a green-watch window" is a decision, not a TODO.
Green, no threads. 👍
Uh oh!
There was an error while loading. Please reload this page.
What & why
E2E auth-proxy (squid)went red when client#789 promoted develop→staging on 2026-08-22, and it blocked nothing. This PR does the remaining enablement so the check can actually gate — the "step 4" the ticket calls the last outstanding work.Closes tracebloc/backend#2350
(The one operational step this PR cannot do — arming the branch-protection flip on
staging+main— is a settings action deferred to after a green-watch window; it is documented in full at the end of this description so it is not lost when the issue closes.)Verdict on "flake vs. Collector regression" — it is a flake, independently confirmed
Two outcomes were on the table: (a) flake / long-standing red, or (b) a real regression from the telemetry Collector payload (#779/#784/#790/#792). It is (a). Evidence I gathered directly from the runs, not from the issue thread:
32589039697, job97069826651) the node-level image pulls tunnelled fine through squid —TCP_TUNNEL/200 CONNECT auth.docker.io:443 tbuserappears repeatedly. The failure is only the in-cluster app-pod probe, and its own log prints the mechanism:* Negative DNS entry— curl served all retries from its process-lifetime negative-DNS cache, so--retry-all-errorsnever re-queried the resolver. One real lookup, ~1s after pod start, decided the whole check.develop, theE2E auth-proxy (squid)job is 28 green / 2 red over the 30installer-testsruns around the event (6.7%), and it has been continuously green sinceebb84b13— the merge of the fix (fix(e2e): the squid probe's DNS retry was inert — retry in a fresh process (backend#2350) #811) on 2026-08-24 — through today. A regression would be a wall of red, not two isolated failures with green on either side. The 19:57 develop run on 2026-08-22 carried more Collector code than the promotion did and was green.So: not the payload, and not a permanently-red job either — an intermittent false red in a non-required job, the shape that never gets diagnosed because each instance is individually dismissible.
What was already fixed (no code change needed here)
e2e-proxy.sh. The "pin external deps before gating" prerequisite is satisfied.What this PR does — the remaining enablement (step 4)
The check could not block because it was a job inside
installer-tests.yaml, which is path-filtered on bothpushandpull_request. A required check behind a paths filter never reports on a PR that touches nothing under the filter — GitHub then holds the PR at "Expected — waiting for status to be reported" forever. That is the same hazarddrift-checks.yamldocuments (it once stuck client#651/#657/#660), and the same reasonSource-of-truth driftwas moved out of installer-tests' oldstaticjob.This PR extracts
e2e-proxyinto its owne2e-auth-proxy.yaml, following that precedent:pull_requesthas nopaths:filter → the context always reports on every PR tomain/staging/develop/openshift, so it can be required on staging/main without deadlocking a promotion PR whose batch happens to touch noscripts/file (backmerge, hotfix lane, a version-bump promotion).pushkeeps its paths filter (pushes aren't gated) and gainsstaging; the Monday cron is preserved so extraction doesn't drop the job's weekly canary.E2E auth-proxy (squid)is unchanged → the required-context name and the release train's by-name check reading both keep working. No duplicate context: the job is removed frominstaller-tests.yaml(a tombstone comment records where it went and why).This choice dominates both options weighed in the ticket: no skip-shim (so none of backend#2447's fail-open shape), and no "drop paths → run the full distro matrix on every PR" cost — only a single ubuntu-latest job moves.
The "should it be required?" decision (step 5) — yes, on staging + main; not flipped here
It should gate, on
staging+main(the hop this protects), notdevelop(where a blip would tax every PR). But it is a branch-protection setting, not a file, and flipping it now would be wrong on two counts: the context can't be selected until this workflow has run at least once on those branches, and per arm-while-green it should wait out a green-watch window (#811 landed only 2026-08-24). I have not changed any protection setting. Once this merges, has run, and the watch is clean, arm it with:(Merge the new context into the existing
checkslist rather than replacing it — read the current set first withgh api repos/tracebloc/client/branches/staging/protection/required_status_checks --jq '.checks'.)Test evidence
yaml.safe_load); the onlyuses:is SHA-pinned (quality / action-pins); no.shchanged (quality / shellcheckout of scope);permissions: contents: readpreserved.installer-tests.yamljobs after the edit:unit-bash, unit-pester, distro-prereqs, e2e-cluster, path-persist, e2e-journey—e2e-proxycleanly removed, noneeds:referenced it.develop, which is in the new workflow'spull_requestbranches with no paths — soE2E auth-proxy (squid)runs on this PR itself: live proof the extracted workflow is green (the probe script is byte-identical to what is already green on develop).Reviewer note
The class here — "an expensive E2E stuck in installer-tests that can therefore never gate" — has other members (
E2E cluster,E2E last-mile journey). This PR deliberately scopes to the auth-proxy check the ticket is about; whether those two also deserve extraction/gating is a separate call.Ref: tracebloc/backend#2350
Note
Low Risk
CI workflow layout only—no installer or test script changes in the diff; branch protection arming is documented as a separate manual step.
Overview
Moves the
E2E auth-proxy (squid)job out of path-filteredinstaller-tests.yamlinto a newe2e-auth-proxy.yaml, matching the earlier Source-of-truth drift extraction so the check can become a required status gate onstaging/main.The new workflow keeps the same job name and still runs
scripts/tests/e2e-proxy.shon a singleubuntu-latestrunner.pull_requesthas nopaths:filter, so every PR tomain,staging,develop, andopenshiftgets a status report (avoiding “waiting for status” on promotions that don’t touchscripts/).pushstays path-scoped underscripts/**and the workflow file, addsstagingon push, and retains the Monday 03:00 UTC schedule plusworkflow_dispatch.installer-tests.yamldrops thee2e-proxyjob and documents the move in a tombstone comment; no other jobs depended on it.Reviewed by Cursor Bugbot for commit 0872fb3. Bugbot is set up for automated code reviews on this repo. Configure here.