Fix cli-proxy TCP tunnel localhost binding on IPv6-enabled runners#4626
Conversation
✅ Coverage Check PassedOverall Coverage
📁 Per-file Coverage Changes (1 files)
Coverage comparison generated by |
There was a problem hiding this comment.
Pull request overview
This PR fixes cli-proxy’s TCP tunnel loopback binding behavior on IPv6-enabled runners by ensuring the tunnel listens on both IPv4 and IPv6 loopback addresses, preventing failures when localhost resolves to ::1 first.
Changes:
- Update
containers/cli-proxy/tcp-tunnel.jsto bind the listener on both127.0.0.1and::1, while tolerating missing IPv6 loopback. - Add a Jest regression test to validate the tunnel accepts connections via both IPv4 and IPv6 loopback when IPv6 is available.
Show a summary per file
| File | Description |
|---|---|
| containers/cli-proxy/tcp-tunnel.js | Bind TCP tunnel on both IPv4 and IPv6 loopback with explicit per-bind error handling. |
| scripts/ci/tcp-tunnel.test.ts | Add regression test covering IPv4/IPv6 loopback connectivity to the tunnel. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 2/2 changed files
- Comments generated: 3
| const bindHosts = ['127.0.0.1', '::1']; | ||
| let startedServers = 0; | ||
| let readyLogged = false; | ||
| const servers = []; | ||
|
|
| } finally { | ||
| tunnel.kill('SIGTERM'); | ||
| await new Promise((resolve) => upstream.server.close(() => resolve(undefined))); | ||
| } | ||
|
|
||
| expect(tunnel.exitCode).not.toBe(1); | ||
| }, 10000); |
| async function connectWithRetry(host: string, port: number, attempts = 20): Promise<void> { | ||
| let lastError: unknown; | ||
| for (let i = 0; i < attempts; i += 1) { | ||
| try { | ||
| await connect(host, port); |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
@copilot address review feedback |
This comment has been minimized.
This comment has been minimized.
Done in a68ec25. Changes made:
|
| @@ -0,0 +1,144 @@ | |||
| import { describe, expect, it } from '@jest/globals'; | |||
Smoke Test Results: Copilot BYOK (Direct) Mode✅ GitHub MCP connectivity — Last 2 merged PRs fetched Status: PASS — Running in direct BYOK mode via api-proxy → api.githubcopilot.com
|
🔬 Smoke Test Results
Overall: FAIL PR: Fix cli-proxy TCP tunnel localhost binding on IPv6-enabled runners
|
|
Smoke test results:
|
Chroot Version Comparison Results
Overall: ❌ Not all tests passed — Python and Node.js versions differ between host and chroot environments.
|
|
Smoke test results:
Running in direct BYOK mode (AWF_AUTH_TYPE=github-oidc + AWF_AUTH_AZURE_* + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw) authenticated via Microsoft Entra Overall status: FAIL Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "api.openai.com"See Network Configuration for more information.
|
🏗️ Build Test Suite Results
Overall: 8/8 ecosystems passed — ✅ PASS
|
Smoke Test: GitHub Actions Services Connectivity
Overall: FAIL
|
|
GitHub API: ✅ PASS Total: PASS
|
cli-proxy’s TCP tunnel only listened on127.0.0.1, whileghmay resolvelocalhostto::1first. On IPv6-enabled runners this caused liveness probe failures (connect: connection refused) during sidecar startup.Tunnel binding behavior
containers/cli-proxy/tcp-tunnel.jsto start listeners on both loopback addresses:127.0.0.1::1Regression coverage
scripts/ci/tcp-tunnel.test.tsto verify the tunnel accepts connections on both IPv4 and IPv6 loopback when IPv6 loopback is available.