Skip to content

fix: run Bazel Maven scans on Windows - #1658

Merged
Martin Torp (mtorp) merged 9 commits into
v1.xfrom
martin/windows-bazel-support
Oct 27, 2026
Merged

Martin Torp (mtorp) merged 9 commits into
v1.xfrom
martin/windows-bazel-support

Conversation

@mtorp

@mtorp Martin Torp (mtorp) commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

LLM Description written by Codex:GPT-6

Bazel manifest generation assumes Unix executables and Python symlinks, splits quoted flags at spaces, and shuts down without the workspace and environment used for extraction. This adds a Maven baseline for native Windows x64 with Bazel 7.4.1 and rules_jvm_external 6.6.

Queries, probes, cqueries, extension discovery, and shutdown share executable handling for native binaries, batch wrappers, and Node entry points. Native lookup uses the existing which version in the lockfile. Only script launchers go through the registry's Node entry-point resolver. Prerequisites use the scan environment. Windows requires a working Python 3 python.exe, and elsewhere a python that isn't Python 3 falls back to python3. Quotes that open a value or follow = keep spaces and backslashes, while apostrophes inside a value stay literal. A relative --bazel resolves against the current directory, and one from socket.json against the scanned directory.

SOCKET_BAZEL_OUTPUT_ROOT selects a short parent for isolated output directories. Cleanup uses each workspace's startup options and environment. It asks Bazel for the effective install base and output base and only shuts down a server when one of them is inside the scan's own output root. That covers a server the scan started in an explicit output base, while a server whose install and output base both come from the caller's rc is left alone. Cleanup runs under its own time limit, so it still works after Ctrl-C. It reads the pid of each server the scan owns, waits for it to exit after shutdown and kills it if it is still running. The scan's root is removed once its servers have exited, even when Bazel cannot report its bases. If its pid files can't be read, cleanup warns and keeps the root without failing the scan. Timeouts and cancellation stop every process a launcher started, through a process group on Unix and taskkill on Windows, and the call settles even if an escaped process holds the output pipes. A cancelled run fails with an AbortError on every platform. Removal handles read-only extracted directories without following links, and reports directories it cannot remove. Workspace discovery skips every socket-bazel- output directory, including ones left by other scans. Quoted PATH entries are unquoted before executable lookup. Windows PyPI extraction gives a specific unsupported error until platform selection is implemented. The external PyPI fixture now requires SOCKET_BAZEL_PYPI_FIXTURE instead of an implicit sibling checkout and a Unix sandbox heuristic. The Windows workflow only runs when Bazel sources, Bazel fixtures, dependencies, or the workflow change.

Validation on commit 0d97adc, which merges the latest v1.x and addresses the remaining review feedback. All checks pass on it, including the native Windows Maven job, Linux unit tests on Node 22 and 24, Linux end-to-end tests, lint, and type checks. Earlier validation runs:

  • Native Windows CI passed: 70 unit and process tests, packaged CLI installation, and six real Maven fixture checks across Bzlmod and WORKSPACE. The fixtures check direct and transitive packages, the dependency edge, paths with spaces, the auto-manifest layout, workspace files, and cleanup.
  • Linux CI passed on Node 22 and 24, including lint and type checks. Linux end-to-end tests passed on both Node versions.
  • All 275 Bazel unit and process tests pass locally. Native macOS fixtures have also passed.
  • The Windows configuration is Server 2022 x64, PowerShell 7.6.8, Node 24.14.1, Bazelisk 1.26.0, Bazel 7.4.1, Python 3.12.10, and Temurin JDK 21.0.6+7.

Two release gates remain open as follow-ups: a dedicated test-organization upload with expected findings, and real Bazel server coverage for concurrent scans. Windows PyPI platform selection is outside this first Maven slice. Other Windows versions and architectures have not been validated.

Companion documentation: https://github.com/SocketDev/docs/pull/155
Related compatibility work: https://linear.app/socketdev/issue/REA-981


Note

Medium Risk
Touches subprocess spawning, process-tree teardown, and Bazel server shutdown logic across platforms; mistakes could leave orphan servers or affect non-Windows scans, but scope is mostly the manifest Bazel path with heavy test coverage.

Overview
Enables Bazel Maven manifest extraction on native Windows by centralizing process launch, prerequisites, flag parsing, and teardown instead of assuming Unix shells and symlinks.

A new spawnBazel / bazel-process layer resolves Bazel via the scan PATH (quoted entries, PATHEXT), runs native .exe, .cmd/.bat, and Node entry points while preserving arguments, kills full process trees on timeout or cancel (taskkill on Windows), and surfaces BazelTimeoutError. --bazel-flags now parses quoted values (spaces, backslashes, apostrophes in unquoted values). Relative --bazel paths resolve from the CLI cwd; defaults from socket.json resolve from the scanned tree.

Prerequisites and cleanup run against the extraction environment: Java/JAVA_HOME and Python 3 checks (Windows requires python.exe, no batch shims; Unix may shim python3 → python). SOCKET_BAZEL_OUTPUT_ROOT picks a short parent for isolated output dirs; bazel-cleanup shuts down only servers owned by the scan, retries locked dirs, and is wired through Maven extraction (replacing ad-hoc shutdown/rm). Workspace walks ignore socket-bazel-* output.

PyPI on Windows fails fast with an explicit unsupported message; the external PyPI fixture now needs SOCKET_BAZEL_PYPI_FIXTURE. Adds which, native Maven fixtures, integration e2e tests, and a Windows CI workflow (unit/process tests, packaged CLI, real Bazel 7.4.1 Maven runs).

Reviewed by Cursor Bugbot for commit 33305d7. Configure here.

Generate Maven manifests with native Windows tools. Preserve paths
and arguments, use the scan environment for prerequisite checks,
and clean up servers started by the connector.

Add pinned Windows fixtures and packaged CLI checks.

Assisted-by: Codex:GPT-6
Use executable lookup before unwrapping Node launchers so native
Bazel and Python executables remain runnable. Keep custom batch
wrappers intact and invoke their selected paths.

Pin the existing which version without changing resolutions.

Assisted-by: Codex:GPT-6
Compare executable identity so case-insensitive Windows paths do
not fail when PATHEXT uses an uppercase extension.

Assisted-by: Codex:GPT-6

@mtorp Martin Torp (mtorp) left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

[agent] Reviewed 0c7235d and found three P2 issues in executable lookup, workspace discovery, and cleanup. Build, type checks, lint on changed files, 275 Bazel tests, and all six native Maven fixture tests passed locally on macOS. Windows CI also passed. The inline comments describe the reproductions and suggested fixes.

Comment thread src/commands/manifest/bazel/bazel-cleanup.mts Outdated
Comment thread src/commands/manifest/bazel/extract_bazel_to_maven.mts Outdated
Comment thread src/commands/manifest/bazel/bazel-process.mts Outdated
Ask Bazel for the effective output base before shutdown, so an rc
file that selects a caller-owned output base keeps its server alive.
Skip every socket-bazel- output directory during workspace discovery,
and strip quotes from PATH entries before resolving them.

Simplify the Windows process helpers. Use one environment key lookup,
one batch escaper and one Python shim result shape, require explicit
env and cwd, shut down servers in parallel, and cancel superseded
Windows CI runs.

Assisted-by: Claude Code:claude-opus-5-5
Comment thread src/commands/manifest/bazel/bazel-cleanup.mts Outdated
Comment thread src/commands/manifest/bazel/bazel-cleanup.mts
Comment thread src/commands/manifest/bazel/bazel-python-shim.mts Outdated
Comment thread src/commands/manifest/bazel/bazel-query-runner.mts Outdated
Comment thread src/commands/manifest/bazel/bazel-process.mts
Comment thread src/commands/manifest/bazel/bazel-bin-detect.mts
Comment thread src/commands/manifest/bazel/bazel-cleanup.mts Outdated
Comment thread .github/workflows/bazel-windows.yml
Shut down any Bazel server whose install or output base is in the
scan's own root, including one started in an explicit output base,
and always remove the root afterwards, even when Bazel cannot report
its bases. A python on PATH that is not Python 3 falls back to
python3. Quotes in Bazel flags only open at the start of a value or
after =, so apostrophes stay literal. A relative --bazel resolves
against the current directory again. The Windows Bazel workflow runs
only for Bazel changes.

Assisted-by: Claude Code:claude-opus-5-5

@mtorp Martin Torp (mtorp) left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

[agent] Reviewed aa20faf8d. The source build, both TypeScript projects, lint over the changed files, 279 Bazel unit and process tests, and all six native Maven fixture checks on macOS passed. The two inline comments describe lifecycle failures reproduced with real Bazel 7.4.1.

Comment thread src/commands/manifest/bazel/bazel-process.mts Outdated
Comment thread src/commands/manifest/bazel/bazel-cleanup.mts Outdated
A Bazel timeout or cancellation now kills every process a launcher
started, through a process group on Unix and taskkill on Windows. If
something still holds the output pipes, the call settles after a short
grace period. Timeouts surface as BazelTimeoutError.

Cleanup runs under its own time limit, so it still works after Ctrl-C
aborts the scan. It reads the pid of each server the scan owns before
shutdown, waits for that server to exit, and kills it if shutdown left
it running. The output root is kept only while an owned server is
still alive. Real Bazel tests cover timeout and cancellation behind a
JavaScript launcher, and behind a batch launcher on Windows.

Assisted-by: Claude Code:claude-opus-5-5

@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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is ON, but none of the reported issues met your autofix severity threshold.

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

Reviewed by Cursor Bugbot for commit 33305d7. Configure here.

Comment thread src/commands/manifest/bazel/bazel-cleanup.mts
Bazel cleanup runs after a scan has produced its manifests. An
unreadable server pid file made cleanup throw and failed the scan.
Cleanup now warns, still shuts down the servers it knows about, and
keeps the output root because it can't confirm the servers stopped.

Assisted-by: Claude Code:claude-opus-5-5
On Windows, stopping a cancelled Bazel run kills the launcher before
the abort reaches the spawn, so the run failed with the launcher's exit
code. It now fails with an AbortError like on other platforms. The
escaped-process test also waits for its child to exit, because Windows
keeps the temporary directory locked until then.

Assisted-by: Claude Code:claude-opus-5-5
@mtorp
Martin Torp (mtorp) merged commit 421bd9f into v1.x Oct 27, 2026
11 checks passed
@mtorp
Martin Torp (mtorp) deleted the martin/windows-bazel-support branch October 27, 2026 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants