Skip to content

Commit

Permalink
Use a transition to resolve the correct versions of crane and yq
Browse files Browse the repository at this point in the history
Bazel doesn't provide a very elegant way to specify that a toolchain
should be resolved in such a way that it can be executed on a *target*
platform:

bazelbuild/bazel#19645

To work around this, we can pass in the toolchains through ordinary
labels and apply an outgoing edge transition to set
--extra_execution_platforms equal to --platforms. This causes the
toolchains to be resolved the way we want.

Though I think using transitions for this is pretty slick, it's a shame
that this has to be done by patching up command line options.
  • Loading branch information
EdSchouten committed May 28, 2024
1 parent 49fbc76 commit d8eed58
Showing 1 changed file with 31 additions and 7 deletions.
38 changes: 31 additions & 7 deletions oci/private/push.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,23 @@ oci_push(
```
"""

# Helper rule for ensuring that the crane and yq toolchains are actually
# resolved for the architecture we are targeting.
def _transition_to_target_impl(settings, attr):
return {
# String conversion is needed to prevent a crash with Bazel 6.x.
"//command_line_option:extra_execution_platforms": [
str(platform)
for platform in settings["//command_line_option:platforms"]
],
}

_transition_to_target = transition(
implementation = _transition_to_target_impl,
inputs = ["//command_line_option:platforms"],
outputs = ["//command_line_option:extra_execution_platforms"],
)

_attrs = {
"image": attr.label(
allow_single_file = True,
Expand All @@ -124,19 +141,30 @@ _attrs = {
""",
allow_single_file = [".txt"],
),
"_allowlist_function_transition": attr.label(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
"_crane": attr.label(
cfg = _transition_to_target,
default = "@oci_crane_toolchains//:current_toolchain",
),
"_push_sh_tpl": attr.label(
default = "push.sh.tpl",
allow_single_file = True,
),
"_windows_constraint": attr.label(default = "@platforms//os:windows"),
"_yq": attr.label(
cfg = _transition_to_target,
default = "@yq_toolchains//:resolved_toolchain",
),
}

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

def _impl(ctx):
crane = ctx.toolchains["@rules_oci//oci:crane_toolchain_type"]
yq = ctx.toolchains["@aspect_bazel_lib//lib:yq_toolchain_type"]
crane = ctx.attr._crane[0][platform_common.ToolchainInfo]
yq = ctx.attr._yq[0][platform_common.ToolchainInfo]

if ctx.attr.repository and ctx.attr.repository_file:
fail("must specify exactly one of 'repository_file' or 'repository'")
Expand Down Expand Up @@ -184,11 +212,7 @@ def _impl(ctx):
oci_push_lib = struct(
implementation = _impl,
attrs = _attrs,
toolchains = [
"@rules_oci//oci:crane_toolchain_type",
"@aspect_bazel_lib//lib:yq_toolchain_type",
"@bazel_tools//tools/sh:toolchain_type",
],
toolchains = ["@bazel_tools//tools/sh:toolchain_type"],
)

oci_push = rule(
Expand Down

0 comments on commit d8eed58

Please sign in to comment.