Conversation
The hostname is pypi-proxy.cloud.databricks.com (hyphen), not pypi.proxy.cloud.databricks.com — the dotted form doesn't resolve.
Confirms whether the runner can reach files.pythonhosted.org, pypi-proxy.cloud.databricks.com, and pypi.org. Earlier runs suggested the runner can reach pythonhosted directly (wheel downloads succeed) but can't reach the proxy or pypi.org for /simple/ lookups. Run this to get hard evidence before talking to the runner-group owners. Errors are tolerated so we see all three results before pytest runs.
The databricks-protected-runner-group's egress firewall blocks TLS to pypi.org and pypi-proxy.cloud.databricks.com (only files.pythonhosted.org is reachable for TLS handshakes), which prevents uv from resolving build-isolation deps like setuptools to compile thrift's sdist. Other Databricks Python repos (e.g. databricks-ai-bridge) run their pytest CI on plain ubuntu-latest with no proxy and it works fine. Switch both jobs to match. The test job has no need for protected egress, and e2e only uses secrets passed via env, which work the same on either runner. Also removes the now-unused UV_INDEX_URL env var and the temporary network diagnostic step.
CI runners (e.g. GitHub Actions ubuntu-latest) set FORCE_COLOR=1, which makes rich/typer render --help with SGR escapes that split styled tokens across ANSI codes. ``"--agents" in result.output`` then fails because the rendered output is actually ``--\x1b[0m\x1b[1magents``. The test passed locally because non-TTY runs don't get colored. Strip ANSI before checking so the assertion holds either way.
- ruff format: auto-formatted src/ucode/databricks.py (collapsed lines ruff now considers fitting under the 100-char limit). - ty: typed the run() wrapper with @overload so text=True narrows to CompletedProcess[str] (every caller that reads the return value uses text=True). Also guard _scrub_json's dict-key match against non-str keys so re.Pattern[str].search gets a str. Test suite stays at 535 passing.
The prior commit ran `git add -A` and swept up local-only scratch files (.antigravitycli/, .claude/, .vscode/, OPENCODE_PLAN.md, mlflow.db, scripts/) that should never have been tracked. Removing them from the index — they remain on disk locally.
The Databricks CLI's `auth login --no-browser` fallback path reads stdin for the user to paste an OAuth code. In CI the runner's stdin sometimes keeps the subprocess alive past Python's timeout, hanging the whole job for the full ~6h workflow limit. Redirecting stdin to /dev/null makes that fallback EOF immediately, so if M2M env vars don't yield a token we fail fast with a clear error instead of hanging.
Last CI run failed with `Databricks CLI returned no access token` after get_databricks_token's pytest fixture couldn't authenticate via M2M env vars. The CLI's stderr is captured (and discarded) by ucode so we never see *why* M2M failed. This diagnostic step prints the CLI version, which auth env vars are set, whether ~/.databrickscfg exists, and the raw output of `databricks auth token` + `current-user me` so the next run will tell us exactly what's wrong.
`databricks auth token` only returns cached user-OAuth tokens (from `databricks auth login`) — it has no M2M path. Hosted-runner CI has no ~/.databrickscfg and no cached login, so the CLI command always errors with "OAuth is not configured for this host", and ucode's token helper hangs on the `auth login --no-browser` fallback waiting for stdin. Teach has_valid_databricks_auth and get_databricks_token to short-circuit to a pre-fetched DATABRICKS_BEARER env var (the same env var build_auth_shell_command already honors). The e2e workflow pulls it from a repo secret; user fetches a fresh bearer (e.g. M2M client_credentials against /oidc/v1/token) and pastes it into Settings → Secrets when the token expires (~1h). Removes DATABRICKS_CLIENT_ID/_SECRET from the workflow — they're no longer load-bearing now that we don't call the CLI for auth.
- tests/test_e2e.py: TestConfigureSubset patches `run_databricks_login` at the wrong module path. cli.py does `from ucode.databricks import run_databricks_login`, so patching `ucode.databricks.run_databricks_login` doesn't affect the local name cli uses, and the real function runs (which opens a browser). Patch `ucode.cli.run_databricks_login` instead. - mcp_web_search.py: bump urllib timeout from 60s to 180s. Codex Responses API with native web_search does a real web fetch + LLM completion, which legitimately can exceed 60s under load.
The six TestXxxLaunch tests all call `_require_binary("...")` and skip
when the agent isn't on PATH. The runner has only Node.js, not the
agents themselves, so every launch test skipped. Install all six
via `npm install -g` so they exercise real binaries against the e2e
workspace.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Make CI work end-to-end
The CI workflow on
mainwas never green — both the unit-test job and the e2e job failed for unrelated reasons. This PR fixes everything needed to get both to pass.Summary of fixes
1. Switched runners (
b7c3a4f)databricks-protected-runner-groupdoes TLS-level SNI filtering that blocksegress to anything other than
files.pythonhosted.org.uvcan resolve fromthe lockfile (direct file URLs) but anything that hits a
/simple/index —including build-isolation deps for
thrift's sdist — fails with TLS timeouts.Both jobs now run on
ubuntu-latest, matching whatdatabricks/databricks-ai-bridgeuses for its
uv run pytestCI.2.
DATABRICKS_BEARERas the CI auth path (0ae6d88)databricks auth tokenonly returns cached user-OAuth tokens — it doesn'tsupport M2M client_credentials. On hosted CI there's no
~/.databrickscfgand no cached login, so the CLI always errored with "OAuth is not configured
for this host," and ucode's token helper hung on the
auth login --no-browserfallback waiting on stdin. Two changes:
has_valid_databricks_auth+get_databricks_tokennow short-circuit toa
DATABRICKS_BEARERenv var when set (the same env varbuild_auth_shell_commandalready honors for the agents'apiKeyHelper).DATABRICKS_BEARERfrom a repo secret. Theworkspace admin generates a PAT with
all-apisscope and pastes it in;CI uses the same bearer for the SDK helper, the agent runtime helpers,
and all gateway API calls.
3. Install agent CLIs in CI (
40c8c6f)_require_binary("codex")etc. skipped everyTestXxxLaunchtest when theagent wasn't on PATH, and
_register_web_search_mcpraisedFileNotFoundErrorwhen it tried to
claude mcp remove. Adding a singlenpm install -gstepfor all six packages makes the launch tests actually run and lets MCP cleanup
shell out as designed.
4. Misc test bugs
tests/test_cli.py:--helpoutput substring assertion ("--agents" in result.output) failed on CI becauseFORCE_COLOR=1makes typer/rich splitstyled tokens across ANSI escapes (
--\x1b[0m\x1b[1magents). Strip ANSIbefore checking (
4065f14).tests/test_e2e.py:TestConfigureSubsetmonkeypatcheducode.databricks.run_databricks_login, butcli.pydoesfrom ucode.databricks import run_databricks_loginso the local namewas never stubbed and the real function opened a browser. Patch
ucode.cli.run_databricks_logininstead (835adef).mcp_web_search.py: Bumped urllib timeout 60s → 180s. Codex Responses APIwith native
web_searchdoes a real web fetch + completion, easilyexceeds 60s under load (
835adef).5. Pre-existing lint failures (
6cbc26c)test_ruff_formatandtest_tywere already failing onmainbefore thisbranch — fixed both:
ruff format src/.run()wrapper with@overloadsotext=Truenarrows toCompletedProcess[str]. Guard_scrub_json's dict-key match againstnon-
strkeys.Required repo configuration
After merging, the following need to be set in repo Settings:
E2E_ENABLEDtrue(gates the e2e job)UCODE_TEST_WORKSPACEDATABRICKS_BEARERall-apisscopeDATABRICKS_BEARERis short-lived; rotate when CI starts failing with 401s.A future improvement could exchange
DATABRICKS_CLIENT_ID/SECRETat jobstart to keep the bearer always fresh.
Test plan
testjob: 535 unit tests pass onubuntu-lateste2ejob: all 25 e2e tests pass (including the six agent launch testsexercising real binaries against the workspace's AI Gateway endpoints)