cloudflare / cloudflare/workerd
Windows: --nowindows_enable_symlinks workaround for TypeScript builds causes test targets to fail to build
- Dominant language
- C++
- Stars
- 8.7k
- Forks
- 739
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 174
Description
## Summary
The TypeScript pre-build workaround (`--nowindows_enable_symlinks`) used in CI for Windows creates a configuration mismatch that prevents test targets from reusing the cached TS artifacts. When the remote cache is cold or when building locally, ~870 test targets fail to build because they transitively depend on pyodide TypeScript code that only compiles under the `--nowindows_enable_symlinks` configuration.
Applying `--nowindows_enable_symlinks` globally is not an option -- it causes "redefinition" errors in C++ compilation (kj/common.h headers get duplicated via `_virtual_includes` instead of symlinked).
## Background
CI has this workaround in `_bazel.yml`:
```yaml
- name: Bazel build (Windows workaround)
if: runner.os == 'Windows'
# HACK: Work around Bazel Windows bug
run: |
bazel --nowindows_enable_symlinks build ... //src/pyodide:pyodide_static@tsproject
```
The subsequent `bazel build //...` and `bazel test //...` run **without** `--nowindows_enable_symlinks`. This works when the remote cache has TS artifacts from a prior Linux CI run (TS output is platform-independent), but fails when:
1. The remote cache is cold for these targets
2. A developer builds locally on Windows (no remote cache)
## Reproduction
On any Windows machine with the workerd build environment:
```sh
# TS build fails with symlinks enabled:
bazel build --config=windows //src/pyodide:pyodide_static@tsproject
# C++ build fails with symlinks disabled:
bazel --nowindows_enable_symlinks build --config=windows //src/workerd/server:workerd
# -> "redefinition of default argument" in kj/common.h
# Two-step workaround works, but test targets can't reuse the TS artifacts
# because the configuration hashes differ:
bazel --nowindows_enable_symlinks build --config=windows //src/pyodide:pyodide_static@tsproject
bazel test --config=windows //...
# -> ~870 test targets fail to build
```
## Evidence
- Local Windows Server 2025 VM: 109/111 tests pass, but 872 targets fail to build due to the pyodide TS dependency chain
- The same 872 targets build fine on Linux
## Impact
- Windows developers cannot run the full test suite locally
- CI Windows tests are fragile -- they depend on remote cache hits from Linux CI for TS artifacts
- The `--nowindows_enable_symlinks` flag creates two incompatible Bazel configurations that can't share artifacts
## Questions
- What is the root cause of the pyodide TypeScript compilation failure when symlinks are enabled on Windows? Is this a `rules_ts` / `rules_js` bug, or a Bazel bug?
- Is there a way to make the TS build work with symlinks enabled on Windows, eliminating the need for the workaround entirely?
Contributor guide
Assessment
This issue has not been assessed yet.