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 a86249d commit 11cf945
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 8 deletions.
3 changes: 2 additions & 1 deletion MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ register_toolchains("@oci_crane_toolchains//:all", "@oci_crane_registry_toolchai
# Dev dependencies
bazel_lib = use_extension("@aspect_bazel_lib//lib:extensions.bzl", "toolchains", dev_dependency = True)
bazel_lib.jq()
use_repo(bazel_lib, "jq_toolchains")
bazel_lib.yq()
use_repo(bazel_lib, "jq_toolchains", "yq_toolchains")

bazel_dep(name = "rules_go", version = "0.46.0", dev_dependency = True, repo_name = "io_bazel_rules_go")
bazel_dep(name = "rules_pkg", version = "0.7.0", dev_dependency = True)
Expand Down
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 11cf945

Please sign in to comment.