Skip to content

feat: build host-only doc tools in host config via aspect_bazel_lib platform_transition_binary#635

Draft
umaucher wants to merge 1 commit into
eclipse-score:mainfrom
umaucher:um_host_platform_transition_aspect
Draft

feat: build host-only doc tools in host config via aspect_bazel_lib platform_transition_binary#635
umaucher wants to merge 1 commit into
eclipse-score:mainfrom
umaucher:um_host_platform_transition_aspect

Conversation

@umaucher

@umaucher umaucher commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Alternative implementation of #633. Same goal, using the public platform_transition_binary rule from aspect_bazel_lib instead of a hand-rolled transition rule. Opened for side-by-side comparison — only one should be merged.

Why

The runnable documentation targets created by docs()docs, docs_combo, docs_check, docs_link_check, live_preview, live_preview_combo_experimental, ide_support — are host tools that run Python/Sphinx on the build machine. When a consumer builds with a cross --platforms (e.g. --config=per-x86_64-qnx -- //...), these top-level targets get configured for the target platform and fail Python toolchain resolution (No matching toolchains ... tools/python), breaking the whole build in cross-compiling consumers (persistency, reference_integration).

What

Each host-only run target is wrapped with platform_transition_binary from aspect_bazel_lib, transitioning the wrapped binary to a fixed target_platform (@local_config_platform//:host) and forwarding its executable, runfiles and RunEnvironmentInfo, so bazel run //:docs keeps working unchanged.

  • aspect_bazel_lib is already in the module graph via aspect_rules_py; it is declared as a direct bazel_dep (2.16.0) so the rule can be loaded.
  • sphinx_build is only ever consumed as a tool (already built in the exec/host config), so it needs no transition; it is tagged manual so a wildcard bazel build //... under a cross platform skips it.

Comparison with #633

#633 (custom _host_binary) this PR (platform_transition_binary)
Code ~35 lines of custom rule + transition reuse a maintained ruleset rule
Target platform follows --host_platform dynamically fixed @local_config_platform//:host (autodetected host)
New dependency none direct bazel_dep on aspect_bazel_lib (already transitive)

The dynamic --host_platform behaviour of #633 is more precise when a consumer sets a specific --host_platform that differs from the autodetected host; this PR trades that for less code and a battle-tested rule.

Validation

  • Host: bazel build //:docs //:ide_support //:needs_json //:metrics_json — no regression; cquery confirms RunEnvironmentInfo is forwarded and the binary transitions to @local_config_platform//:host.
  • Cross: in a consumer with a local override, bazel build --config=per-x86_64-qnx -- //... no longer fails Python toolchain resolution (0 toolchain errors; only the unrelated valid_from skew fixed by Set valid_from attribute for all features score#3064).
  • buildifier clean.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

License Check Results

🚀 The license check job ran with the Bazel command:

bazel run --lockfile_mode=error //src:license-check

Status: ⚠️ Needs Review

Click to expand output
[License Check Output]
Extracting Bazel installation...
Starting local Bazel server (8.6.0) and connecting to it...
INFO: Invocation ID: 63c21073-abb2-41bf-bcea-5b3c35e3d73c
Computing main repo mapping: 
Loading: 
Loading: 0 packages loaded
Loading: 0 packages loaded
Loading: 0 packages loaded
    currently loading: src
WARNING: Target pattern parsing failed.
ERROR: Skipping '//src:license-check': no such target '//src:license-check': target 'license-check' not declared in package 'src' defined by /home/runner/work/docs-as-code/docs-as-code/src/BUILD
ERROR: no such target '//src:license-check': target 'license-check' not declared in package 'src' defined by /home/runner/work/docs-as-code/docs-as-code/src/BUILD
INFO: Elapsed time: 5.881s
INFO: 0 processes.
ERROR: Build did NOT complete successfully
ERROR: Build failed. Not running target

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

The created documentation from the pull request is available at: docu-html

@anmittag
anmittag requested a review from a-zw July 13, 2026 08:37
@anmittag

Copy link
Copy Markdown
Member

@a-zw could you have a look on it, please?

The runnable documentation targets (docs, docs_combo, docs_check,
docs_link_check, live_preview, live_preview_combo_experimental,
ide_support) are host tools that run Python/Sphinx locally. Under a cross
`--platforms` (e.g. QNX) they were configured for the target platform and
failed Python toolchain resolution, breaking `bazel build //...` in
cross-compiling consumers.

Wrap each with `platform_transition_binary` from aspect_bazel_lib, which
transitions the wrapped binary to a fixed `target_platform`
(`@local_config_platform//:host`) and forwards its executable, runfiles and
RunEnvironmentInfo, so `bazel run //:docs` keeps working.

`sphinx_build` is only consumed as a tool (already built in the exec/host
config) and is tagged `manual` so wildcard builds under a cross platform do
not try to configure it for the target platform.

aspect_bazel_lib is already in the module graph via aspect_rules_py; it is
declared as a direct dep so the rule can be loaded.
@umaucher
umaucher force-pushed the um_host_platform_transition_aspect branch from 5cbc574 to 8f6f97e Compare July 14, 2026 15:07

@a-zw a-zw left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nitpicks. The essential change looks good to me.

Comment thread docs.bzl
# `sphinx_build` is only consumed as a tool (see `needs_json`'s `sphinx` attr below), so Bazel
# already builds it in the exec (host) config -- no host transition needed. It is tagged
# `manual` so a cross-platform `bazel build //...` doesn't configure it for the target platform
# (which would fail Python toolchain resolution).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is overly specific. My understanding is that tagging as "manual" means bazel wildcards (e.g. //...) do not match it.

Documentation:

manual keyword will exclude the target from expansion of target pattern wildcards (..., :*, :all, etc.) and test_suite rules which do not list the test explicitly when computing the set of top-level targets to build/run for the build, test, and coverage commands. It does not affect target wildcard or test suite expansion in other contexts, including the query command. Note that manual does not imply that a target should not be built/run automatically by continuous build/test systems. For example, it may be desirable to exclude a target from bazel test ... because it requires specific Bazel flags, but still have it included in properly-configured presubmit or continuous test runs.

Comment thread docs.bzl
name = "docs",
binary = ":docs_impl",
target_platform = "@local_config_platform//:host",
tags = ["cli_help=Build documentation:\nbazel run //:docs"],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
tags = ["cli_help=Build documentation:\nbazel run //:docs"],

This tag never made sense, so this would be a good opportunity to remove them.

Comment thread MODULE.bazel
Comment on lines +51 to +52
# `platform_transition_binary` (used to build host-only doc tools in the host
# config under a cross `--platforms`). Already in the graph via aspect_rules_py.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# `platform_transition_binary` (used to build host-only doc tools in the host
# config under a cross `--platforms`). Already in the graph via aspect_rules_py.

No need for verbosity.

Comment thread docs.bzl
Comment on lines +49 to +58
# -- Host-platform transition for host-only documentation tooling --------------
#
# The runnable doc targets (docs, ide_support, live_preview, ...) are pure host tools that run
# Python/Sphinx locally. Under a cross `--platforms` (e.g. QNX) they would be configured for the
# target platform and fail Python toolchain resolution. To avoid that, each is wrapped with
# `platform_transition_binary` from aspect_bazel_lib, which transitions the wrapped binary to a fixed
# `target_platform` (the autodetected host, `@local_config_platform//:host`) while forwarding its
# executable, runfiles and RunEnvironmentInfo -- so `bazel build //...` under a cross platform and
# `bazel run //:docs` both keep working.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# -- Host-platform transition for host-only documentation tooling --------------
#
# The runnable doc targets (docs, ide_support, live_preview, ...) are pure host tools that run
# Python/Sphinx locally. Under a cross `--platforms` (e.g. QNX) they would be configured for the
# target platform and fail Python toolchain resolution. To avoid that, each is wrapped with
# `platform_transition_binary` from aspect_bazel_lib, which transitions the wrapped binary to a fixed
# `target_platform` (the autodetected host, `@local_config_platform//:host`) while forwarding its
# executable, runfiles and RunEnvironmentInfo -- so `bazel build //...` under a cross platform and
# `bazel run //:docs` both keep working.

This makes sense for the PR description but is too verbose for this bzl file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants