fix(bazel): symlink structure_test binary to .exe on Windows#559
fix(bazel): symlink structure_test binary to .exe on Windows#559peakschris wants to merge 1 commit into
Conversation
On Windows, the downloaded structure_test binary has no file extension. When a batch script tries to invoke it, Windows does not recognise it as an executable and shows an "Open With" application picker dialog instead of running the binary. The test then appears to pass (exit 0) without actually executing any structure tests. Fix by symlinking the binary to <name>.exe in the Bazel action graph when building on Windows. The binary is a valid Windows PE regardless of its name, so the symlink is safe. The generated launcher scripts already use rlocation to resolve the path at runtime, so they will automatically pick up the .exe copy.
There was a problem hiding this comment.
Code Review
This pull request introduces a change to bazel/container_structure_test.bzl to handle Windows environments by symlinking the container structure test binary to a '.exe' extension if it is missing. The reviewer identified a critical issue where reassigning the binary variable to the symlink would omit the original binary from the runfiles, causing a dangling symlink and test failures in sandboxed or remote execution environments. The reviewer provided a code suggestion to include both the original binary and the symlink in the runfiles, and to clean up a duplicate 'is_windows' check.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| is_windows = ctx.target_platform_has_constraint(ctx.attr._windows_constraint[platform_common.ConstraintValueInfo]) | ||
| if is_windows and not test_bin.basename.endswith(".exe"): | ||
| test_bin_exe = ctx.actions.declare_file(test_bin.basename + ".exe") | ||
| ctx.actions.symlink(output = test_bin_exe, target_file = test_bin) | ||
| test_bin = test_bin_exe |
There was a problem hiding this comment.
On Windows, reassigning test_bin = test_bin_exe means that only the symlink (test_bin_exe) is added to the test's runfiles (on line 119), while the original binary (test_bin) is omitted.
In sandboxed or remote execution environments, this will result in a dangling symlink at runtime because the target of the symlink is not present in the sandbox, causing the test to fail.
To fix this, both the symlink and the original binary must be included in the runfiles. Additionally, is_windows is calculated twice (here and on line 114); we should define it once and reuse it.
Please also update the runfiles definition around line 119 to include original_test_bin as well:
runfiles = ctx.runfiles(
files = image_files + ctx.files.configs + [
bash_launcher,
test_bin,
original_test_bin,
jq_bin,
],
).merge(ctx.attr._runfiles.default_runfiles)And you can remove the duplicate is_windows definition on line 114.
| is_windows = ctx.target_platform_has_constraint(ctx.attr._windows_constraint[platform_common.ConstraintValueInfo]) | |
| if is_windows and not test_bin.basename.endswith(".exe"): | |
| test_bin_exe = ctx.actions.declare_file(test_bin.basename + ".exe") | |
| ctx.actions.symlink(output = test_bin_exe, target_file = test_bin) | |
| test_bin = test_bin_exe | |
| is_windows = ctx.target_platform_has_constraint(ctx.attr._windows_constraint[platform_common.ConstraintValueInfo]) | |
| original_test_bin = test_bin | |
| if is_windows and not test_bin.basename.endswith(".exe"): | |
| test_bin_exe = ctx.actions.declare_file(test_bin.basename + ".exe") | |
| ctx.actions.symlink(output = test_bin_exe, target_file = test_bin) | |
| test_bin = test_bin_exe |
Fixes #557
Problem
On Windows, the downloaded
structure_testbinary has no file extension.When the generated
.batlauncher tries to invoke it, Windows does notrecognise it as an executable and shows an "Open With" dialog instead of
running it. The test then exits 0 and Bazel marks it PASSED without any
structure tests having actually executed.
Fix
After resolving the toolchain binary, symlink it to
<name>.exewhenbuilding on Windows. The binary is a valid PE regardless of its name, so
the symlink is safe. The generated launcher scripts use
rlocationtoresolve the path at runtime and automatically pick up the
.execopy.The change is 11 lines in
bazel/container_structure_test.bzland doesnot affect Linux or macOS builds.