ci: pin TLS-verified patch hosts on macOS compat legs (fix hosted DNS flake) - #295
Mikola Lysenko (mikolalysenko) wants to merge 1 commit into
Conversation
The Bun, vlt and Poetry compatibility workflows drive real package managers
against the production patch service. On GitHub's hosted macOS runners the
system resolver intermittently answers patch.socket.dev with EAI_NONAME
("[Errno 8] nodename nor servname provided"; bun: FailedToOpenSocket; Bun
1.3.x workspace installs never exit) for minutes at a time, at job start or
mid-job, while the service is up: ubuntu and windows legs of the same run
pass, and the same macOS cells pass before and after the window. Over the
last 60 Bun runs (69 attempts) 29 macOS native jobs failed this way and no
other OS did; the CLI's own API calls in those cells succeeded.
A pre-flight wait cannot cover a mid-job window, and the failing processes
are bun / vlt / poetry / python rather than the CLI, so a product retry
cannot help. The runner's resolver is not under test, so take it out of the
path: .github/actions/pin-socket-hosts runs scripts/pin-socket-hosts.py on
macOS, which resolves patch.socket.dev and patches-api.socket.dev (system
resolver, then DNS-over-HTTPS by IP literal, with bounded backoff), keeps
only addresses whose TLS handshake verifies the hostname, and pins them in
/etc/hosts. Every cell still hits production over TLS verified for the
hostname, so the captures depscan imports stay production captures.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
#279 landed on release/v5-prerelease as f6bdad5; please merge origin/release/v5-prerelease again, resolve conflicts, get green, and keep it ready. Generated by Claude Code |
|
#282 landed on release/v5-prerelease as 14a9cb0; please merge origin/release/v5-prerelease again, resolve conflicts, get green, and keep it ready. Generated by Claude Code |
|
#291 landed on release/v5-prerelease as f9cb7e1; please merge origin/release/v5-prerelease again, resolve conflicts, get green, and keep it ready. Generated by Claude Code |
|
#292 landed on release/v5-prerelease as a7b0d00; please merge origin/release/v5-prerelease again, resolve conflicts, get green, and keep it ready. Generated by Claude Code |
|
#296 landed on release/v5-prerelease as 1e3ace6; please merge origin/release/v5-prerelease again, resolve conflicts, get green, and keep it ready. Generated by Claude Code |
|
#293 landed on release/v5-prerelease as b9e106d; please merge origin/release/v5-prerelease again, resolve conflicts, get green, and keep it ready. Generated by Claude Code |
|
#294 landed on release/v5-prerelease as 180f10f; please merge origin/release/v5-prerelease again, resolve conflicts, get green, and keep it ready. Generated by Claude Code |
Problem
The macOS
nativelegs of Bun patch compatibility (and, more rarely, vlt and Poetry) fail intermittently, and a re-run of the same code passes.Root cause (from the logs)
GitHub's hosted macOS runner intermittently cannot resolve
patch.socket.dev, sometimes for minutes, at job start or partway through a job. Meanwhile the service is up.patches-api.socket.devsucceed: it finds the patch and rewrites the lock. What fails is the package manager downloading the tarball frompatch.socket.dev:error: FailedToOpenSocket downloading tarball minimist@https://patch.socket.dev/...<urlopen error [Errno 8] nodename nor servname provided, or not known>curl: (6) Could not resolve host: patch.socket.devFailed to resolve 'patch.socket.dev' ([Errno 8] ...)1.3.10in 36415924573 passed its first 6 hosted cells, lost DNS from about 11:37 to 11:43, then passed the rest.1.3.0in 36420943072 lost DNS from 12:24 to about 12:31. The vlt macOS failure (36420943301, 12:22 to 12:24) falls in the same window as four Bun macOS failures in 36420943072.patch.socket.dev. The only vendored failures are the two conversion shapes (hosted-then-vendored,vendored-then-hosted), which run hosted mode.Frequency (Bun
native, last 60 runs / 69 attempts, all attempts counted)Four runs failed on every leg of every OS (code regressions in those PRs); they are excluded here.
patch.socket.devDNS failure, as abovepatches-api.socket.devreturnedConnection reset by peer/504to the CLI's own requests (see below)vlt
nativeover the last 62 runs: 1 macOS failure (same DNS cause), 1 Windows failure (not this issue), 0 on ubuntu. The vlt workflow's red status on recent PRs comes frominstall-proofon older vlt eras. That fails on every run, on all three OSes. It's deterministic and unrelated to this PR.Fix
A new composite action,
.github/actions/pin-socket-hosts, runs on macOS only, before the backtest, in the Bun, vlt and Poetrynativejobs. It callsscripts/pin-socket-hosts.py, which:patch.socket.devandpatches-api.socket.dev, first with the system resolver, then with DNS-over-HTTPS to IP-literal endpoints (1.1.1.1,8.8.8.8), which need no DNS. It keeps retrying with backoff for up to 5 minutes./etc/hostsand flushes the resolver cache. If a host can't be pinned, the job fails at this step and names the host, instead of failing a hundred cells later.Every cell still talks to the production service over TLS verified for the hostname. Only the runner's DNS resolver, which isn't what we're testing, is out of the path.
Why not the other options
ci.yml'se2ematrix, including macOS.backtest-vlt.pysays it runs "with no service doubles". Both harnesses' rows are imported by depscan as production captures, and the existing loopbackIdentityMirroris documented as "never an import source". Moving these legs to a mock would duplicateci.ymland lose the only production signal.Separate issue, not fixed here: ubuntu (and Poetry
ubuntu-latest, 1.1.15on #293/#294)The ubuntu failures are not DNS. The CLI's own requests to
patches-api.socket.devgotclient error (Connect): Connection reset by peer (os error 104)orAPI request failed with status 504, for example Bun jobs 108648998493 and 108733768066. On Poetry 1.1.15 the reset hitvex's/patch/viewcall.ApiClient::send_json_requestdeliberately never retries transport errors ("Transport errors are never retried"), and only retries 429/503. Retrying idempotent GETs on connect or reset errors, and treating 502/504 like 503, would be a real product improvement. It changes a documented policy, though, so I've left it for a separate PR.Validation
scripts/tests/test_pin_socket_hosts.py(6 hermetic tests): system resolver path, fallback to DoH, unverified addresses rejected, IPv6-only as a last resort, retry until the resolver recovers, and fail-closed with no output.python3 -m unittest discover -s scripts/tests: 111 tests pass.Hostname mismatch.actionlint: no new findings. The existing SC2086/SC2206 notes are in steps this PR doesn't touch.shellcheckis clean on the action script.cargo clippy --locked --workspace --all-targets -- -D warnings: clean (no Rust changes).🤖 Generated with Claude Code
Note
Low Risk
CI-only change affecting macOS job
/etc/hostsvia sudo; no application or auth logic changes, with TLS verification before pinning.Overview
Adds a macOS-only CI workaround for GitHub hosted runners intermittently failing to resolve
patch.socket.dev/patches-api.socket.dev(EAI_NONAME) while production is healthy, which was flaking Bun, vlt, and Poetry production backtest jobs.A new composite action
.github/actions/pin-socket-hostsrunsscripts/pin-socket-hosts.pybefore native backtests inbun-compatibility,poetry-compatibility, andvlt-compatibility. The script resolves each host via the system resolver, then DNS-over-HTTPS to IP literals (1.1.1.1 / 8.8.8.8), keeps only TLS-verified addresses, appends them to/etc/hosts, and flushes the macOS resolver cache. Jobs still hit the real production endpoints with normal hostname TLS; only runner DNS is bypassed.Path filters on those workflows now include the action and script.
docs/testing/bun-compatibility.mdanddocs/testing/vlt-compatibility.mddocument the step.scripts/tests/test_pin_socket_hosts.pyadds hermetic tests for resolver fallback, verification gating, IPv6 last-resort, retries, and fail-closed behavior.Reviewed by Cursor Bugbot for commit 6f46cb2. Configure here.