Skip to content

CI: hermetic spawns in the e2e_maven suite (#823) - #1519

Merged
Mikola Lysenko (mikolalysenko) merged 3 commits into
mainfrom
agent/fix-ci-hermetic-maven
Oct 14, 2026
Merged

Mikola Lysenko (mikolalysenko) merged 3 commits into
mainfrom
agent/fix-ci-hermetic-maven

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

LLM Description written by Claude Code:claude-opus-5-5

Refs #823 (slice 18: the e2e_maven suite). This uses Refs, so #823 stays open for the remaining PENDING_RAW_SPAWNS files.

Summary

e2e_maven.rs now starts socket-patch through tests/common/hermetic.rs (hermetic::binary_command()), scrubs any activated venv (Extra::Venv) and isolates the JVM env with jvm_env::isolate_cli, the same way e2e_cargo.rs does. After that call it pins its own fixture-local homes: MAVEN_REPO_LOCAL, HOME/USERPROFILE, XDG_CACHE_HOME, LOCALAPPDATA, and now GRADLE_USER_HOME. It also removes M2_HOME. The file comes off PENDING_RAW_SPAWNS (9 → 8 on main). Once #1515 and #1518 also land, 3 files remain: e2e_hosted_production, e2e_redirect_cargo_shapes and e2e_vendored_production. The change touches tests only: no product code and no workflows.

This PR removes the e2e_maven.rs entry, which is the only remaining entry whose neighbours #1515 and #1518 don't remove. The three PRs merge cleanly in any order.

Root cause

run() spawned the CLI with a bare Command::new and removed only 6 SOCKET_* names by hand. Every other ambient SOCKET_* reached the child:

  • On main, a shell that exports SOCKET_DRY_RUN=true SOCKET_ECOSYSTEMS=cargo SOCKET_ORG_SLUG=hostile SOCKET_NO_CONFIG=0 SOCKET_JSON=false SOCKET_SILENT=true SOCKET_NO_UPDATE_CHECK=0 fails 2 of the 22 tests: scan_discovers_maven_artifacts and scan_discovers_gradle_project_artifacts.
  • SOCKET_NO_CONFIG=0 let a developer's real socket login reach the child. The update check and telemetry were never forced off.
  • GRADLE_USER_HOME, GRADLE_OPTS, GRADLE_RO_DEP_CACHE and VIRTUAL_ENV were inherited by the unscoped scans.

Test evidence

  • Red with only the PENDING_RAW_SPAWNS removal: spawn_env_hygiene fails no_new_bare_binary_spawns (15 passed, 1 failed).
  • Red on main under the hostile shell above (plus VIRTUAL_ENV=/nonexistent): e2e_maven passes 20 and fails 2.
  • Green at be57c3d under the same hostile shell (plus GRADLE_USER_HOME=/nonexistent M2_HOME=/nonexistent): e2e_maven 22/22 and spawn_env_hygiene 16/16. With a clean env, e2e_maven is 22/22. The suite has no #[ignore]d tests.
  • cargo fmt --all -- --check and cargo clippy --locked --workspace --all-features -- -D warnings are clean, and clippy --test e2e_maven -- -D warnings is clean too.
  • CI at be57c3d: all 86 check runs completed. 35 passed (including ci-ok and clippy), 50 were skipped (the full tier), 1 was neutral (Bugbot) and none failed. Bugbot found no issues.

/code-review high

No correctness findings in this diff. Fixed in be57c3d:

  • The shared stand-in GRADLE_USER_HOME (from isolate_cli) outlives test runs. run() now pins it next to the fixture's HOME, so a stray cache can't change the Gradle scan's count.
  • Added a comment saying the home pins must stay after isolate_cli, because the last write for a name wins.
  • run() now calls hermetic::binary_command() instead of hermetic::command(&binary()).

Not fixed here. These change the shared common harness, so they belong in a follow-up slice under #823:

  • jvm_env::AMBIENT doesn't scrub M2_HOME / MAVEN_REPO_LOCAL, and isolate_cli doesn't pin XDG_CACHE_HOME / LOCALAPPDATA. Other suites that only use isolate_cli (for example e2e_cargo and common::run) can still see a developer's real ~/.m2 or Coursier cache. e2e_maven pins all of these itself.
  • The proxied async run() helper is now repeated almost verbatim across e2e_maven, e2e_cargo, e2e_composer and others. A shared common::run_proxied would remove the copies.

CI cost

No workflow changes. A lean PR run costs the same before and after: about 28 Linux jobs and about 8 minutes.

🤖 Generated with Claude Code

https://claude.ai/code/session_015ra9QiqqVWRsp6FEqw8BXb

Assisted-by: Claude Code:claude-opus-5-5
e2e_maven started the CLI with a bare Command::new and a private
sweep of a handful of SOCKET_* names. Any other ambient value reached
the child: on main, a shell exporting SOCKET_ECOSYSTEMS=cargo fails
two of its scans, and SOCKET_NO_CONFIG=0 lets a developer's real
socket login authenticate the test child.

Its run() helper now builds the child with hermetic::command, scrubs
an activated venv and isolates the JVM env the way e2e_cargo does,
and keeps its own fixture HOME and cache pins. The file leaves
PENDING_RAW_SPAWNS so the spawn_env_hygiene ratchet keeps it there.

Refs #823

Assisted-by: Claude Code:claude-opus-5-5
The shared stand-in GRADLE_USER_HOME outlives test runs, so a cache
left there would change the Gradle scan's package count on that
machine only. Pin it next to the fixture's own HOME, note why the home
pins must follow isolate_cli, and use hermetic::binary_command.

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 14, 2026 04:04
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit be57c3d. Configure here.

Merged via the queue into main with commit c28402a Oct 14, 2026
86 checks passed
@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the agent/fix-ci-hermetic-maven branch October 14, 2026 04:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants