Skip to content

Commit ddf89b5

Browse files
authored
fix: select when exec is windows (#886)
Fixes: #420
1 parent a46337a commit ddf89b5

File tree

9 files changed

+81
-16
lines changed

9 files changed

+81
-16
lines changed

.github/workflows/ci.yaml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ jobs:
4040
- id: linux
4141
run: echo "os=ubuntu-latest" >> $GITHUB_OUTPUT
4242
- id: macos
43-
run: echo "os=macos-13" >> $GITHUB_OUTPUT
43+
run: echo "os=macos-15" >> $GITHUB_OUTPUT
4444
# Don't run MacOS if there is no TestContainers API token which is the case on forks. We need it for container tests.
4545
if: ${{ env.TC_CLOUD_TOKEN != '' }}
4646
outputs:
47-
# Will look like ["ubuntu-latest", "macos-13"]
47+
# Will look like ["ubuntu-latest", "macos-15"]
4848
os: ${{ toJSON(steps.*.outputs.os) }}
4949

5050
test:
@@ -69,11 +69,13 @@ jobs:
6969
bzlmodEnabled: [true, false]
7070
exclude:
7171
# macos is expensive (billed at 10X) so don't test these
72-
- os: macos-13
72+
- os: macos-15
7373
folder: e2e/wasm
74-
- os: macos-13
74+
- os: macos-15
7575
folder: e2e/assertion
76-
- os: macos-13
76+
- os: macos-15
77+
folder: e2e/smoke
78+
- os: macos-15
7779
bazelversion: 7.6.2
7880
- folder: .
7981
bazelversion: 7.6.2
@@ -135,7 +137,7 @@ jobs:
135137
run: echo "${{ matrix.bazelversion }}" > .bazelversion
136138

137139
- name: Configure TestContainers cloud
138-
if: ${{ matrix.os == 'macos-13' }}
140+
if: ${{ matrix.os == 'macos-15' }}
139141
uses: atomicjar/testcontainers-cloud-setup-action@main
140142
with:
141143
wait: true
@@ -144,7 +146,7 @@ jobs:
144146
- run: man xargs
145147

146148
- name: Configure Remote Docker Host
147-
if: ${{ matrix.os == 'macos-13' }}
149+
if: ${{ matrix.os == 'macos-15' }}
148150
run: |
149151
echo "DOCKER_HOST=$(grep 'tc.host' ~/.testcontainers.properties | cut -d '=' -f2 | xargs)" >> $GITHUB_ENV
150152
curl -fsSL https://download.docker.com/mac/static/stable/x86_64/docker-23.0.0.tgz | tar -xOvf - docker/docker > /usr/local/bin/docker

examples/dockerfile/.bazelversion

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
8.4.2
2+
3+
# The first line of this file is used by Bazelisk and Bazel to be sure
4+
# the right version of Bazel is used to build and test this repo.
5+
# This also defines which version is used on CI.
6+
#
7+
# Note that you should also run integration_tests against other Bazel
8+
# versions you support.

examples/dockerfile/MODULE.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module(name = "dockerfile")
44

55
bazel_dep(name = "bazel_skylib", version = "1.8.2")
66
bazel_dep(name = "aspect_bazel_lib", version = "2.7.2")
7+
bazel_dep(name = "platforms", version = "1.0.0")
78
bazel_dep(name = "rules_oci", version = "2.2.5")
89
bazel_dep(name = "rules_go", version = "0.53.0")
910

oci/private/BUILD.bazel

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
2+
load(":windows_utils.bzl", "is_exec_platform_windows")
3+
4+
is_exec_platform_windows(
5+
name = "is_exec_platform_windows",
6+
visibility = ["//visibility:public"],
7+
)
28

39
exports_files(
410
glob(["*.bzl"]),
@@ -103,7 +109,14 @@ bzl_library(
103109
srcs = ["util.bzl"],
104110
visibility = ["//oci:__subpackages__"],
105111
deps = [
112+
":windows_utils",
106113
"@bazel_skylib//lib:paths",
107114
"@bazel_skylib//lib:versions",
108115
],
109116
)
117+
118+
bzl_library(
119+
name = "windows_utils",
120+
srcs = ["windows_utils.bzl"],
121+
visibility = ["//oci:__subpackages__"],
122+
)

oci/private/image.bzl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,7 @@ If `group/gid` is not specified, the default group and supplementary groups of t
9696
"annotations": attr.label(doc = "A file containing a dictionary of annotations. Each line should be in the form `name=value`.", allow_single_file = True),
9797
"_image_sh": attr.label(default = "image.sh", allow_single_file = True),
9898
"_descriptor_sh": attr.label(default = "descriptor.sh", executable = True, cfg = "exec", allow_single_file = True),
99-
"_windows_constraint": attr.label(default = "@platforms//os:windows"),
100-
}
99+
} | util.IS_EXEC_PLATFORM_WINDOWS_ATTRS
101100

102101
def _platform_str(os, arch, variant = None):
103102
parts = dict(os = os, architecture = arch)
@@ -241,7 +240,7 @@ def _oci_image_impl(ctx):
241240
action_env = {}
242241

243242
# Windows: Don't convert arguments like --entrypoint=/some/bin to --entrypoint=C:/msys64/some/bin
244-
if ctx.target_platform_has_constraint(ctx.attr._windows_constraint[platform_common.ConstraintValueInfo]):
243+
if util.is_windows_exec(ctx):
245244
# See https://www.msys2.org/wiki/Porting/:
246245
# > Setting MSYS2_ARG_CONV_EXCL=* prevents any path transformation.
247246
action_env["MSYS2_ARG_CONV_EXCL"] = "*"

oci/private/load.bzl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,7 @@ attrs = {
130130
),
131131
"_tarball_sh": attr.label(allow_single_file = True, default = "//oci/private:tarball.sh.tpl"),
132132
"_runfiles": attr.label(default = "@bazel_tools//tools/bash/runfiles"),
133-
"_windows_constraint": attr.label(default = "@platforms//os:windows"),
134-
}
133+
} | util.IS_EXEC_PLATFORM_WINDOWS_ATTRS
135134

136135
def _get_workspace_name(ctx, file):
137136
label = getattr(file, "owner", None)

oci/private/push.bzl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,12 +176,11 @@ _attrs = {
176176
allow_single_file = True,
177177
),
178178
"_runfiles": attr.label(default = "@bazel_tools//tools/bash/runfiles"),
179-
"_windows_constraint": attr.label(default = "@platforms//os:windows"),
180179
"_jq": attr.label(
181180
default = "@jq_toolchains//:resolved_toolchain",
182181
cfg = "exec",
183182
),
184-
}
183+
} | util.IS_EXEC_PLATFORM_WINDOWS_ATTRS
185184

186185
def _quote_args(args):
187186
return ["\"{}\"".format(arg) for arg in args]

oci/private/util.bzl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
load("@bazel_skylib//lib:paths.bzl", "paths")
44
load("@bazel_skylib//lib:versions.bzl", "versions")
5+
load(":windows_utils.bzl", "IS_EXEC_PLATFORM_WINDOWS_ATTRS", "is_windows_exec")
56

67
_IMAGE_PLATFORM_VARIANT_DEFAULTS = {
78
"linux/arm64": "v8",
@@ -197,11 +198,11 @@ def _maybe_wrap_launcher_for_windows(ctx, bash_launcher):
197198
but without requiring that the script has a .runfiles folder.
198199
199200
To use:
200-
- add the _windows_constraint appears in the rule attrs
201+
- add IS_EXEC_PLATFORM_WINDOWS_ATTRS to the rule attrs
201202
- make sure the bash_launcher is in the inputs to the action
202203
- @bazel_tools//tools/sh:toolchain_type should appear in the rules toolchains
203204
"""
204-
if not ctx.target_platform_has_constraint(ctx.attr._windows_constraint[platform_common.ConstraintValueInfo]):
205+
if not is_windows_exec(ctx):
205206
return bash_launcher
206207

207208
win_launcher = ctx.actions.declare_file("wrap_%s.bat" % ctx.label.name)
@@ -295,4 +296,6 @@ util = struct(
295296
build_manifest_json = _build_manifest_json,
296297
assert_crane_version_at_least = _assert_crane_version_at_least,
297298
platform_triplet = _platform_triplet,
299+
is_windows_exec = is_windows_exec,
300+
IS_EXEC_PLATFORM_WINDOWS_ATTRS = IS_EXEC_PLATFORM_WINDOWS_ATTRS,
298301
)

oci/private/windows_utils.bzl

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""Utilities for detecting Windows execution platform."""
2+
3+
def _is_exec_platform_windows(ctx):
4+
is_windows = ctx.target_platform_has_constraint(ctx.attr._windows_constraint[platform_common.ConstraintValueInfo])
5+
executable = ctx.actions.declare_file("windows_exec.bats")
6+
ctx.actions.write(
7+
executable,
8+
content = "@noop",
9+
)
10+
11+
return [
12+
DefaultInfo(executable = executable),
13+
OutputGroupInfo(windows = depset()) if is_windows else OutputGroupInfo(),
14+
]
15+
16+
is_exec_platform_windows = rule(
17+
implementation = _is_exec_platform_windows,
18+
attrs = {
19+
"_windows_constraint": attr.label(default = Label("@platforms//os:windows")),
20+
},
21+
)
22+
23+
IS_EXEC_PLATFORM_WINDOWS_ATTRS = {
24+
"_is_platform_windows_exec": attr.label(
25+
default = Label("//oci/private:is_exec_platform_windows"),
26+
executable = True,
27+
cfg = "exec",
28+
),
29+
}
30+
31+
def is_windows_exec(ctx):
32+
"""Utility function for checking if the action run on windows.
33+
34+
TODO: explain
35+
36+
Args:
37+
ctx: rule context
38+
"""
39+
40+
outputgroupinfo = ctx.attr._is_platform_windows_exec[OutputGroupInfo]
41+
return hasattr(outputgroupinfo, "windows")

0 commit comments

Comments
 (0)