refactor(toolchains): register runtimes using manifest#3812
Conversation
Currently, all supported Python runtime versions and their platform-specific metadata (URLs, SHA256s, strip_prefix) must be hardcoded in `python/versions.bzl`. This makes it slow and difficult to adopt new Python versions or custom builds without updating `rules_python` itself. This PR introduces the ability to dynamically fetch and register Python runtimes from a remote python-build-standalone (PBS) manifest file (e.g., `SHA256SUMS`). This is supported via two new attributes in `python.override`: - `add_runtime_manifest_urls`: A list of URLs pointing to manifest files to parse and register. - `runtime_manifest_sha`: The SHA256 hash of the manifest file.
…ce mode Workspace builds running under older Bazel versions do not support Bzlmod module extensions. This commit introduces Starlark helper macros to conditionally gate and register Bzlmod-specific unit tests, resolving test suite loading crashes in workspace CI jobs.
Removes the external test_helpers.bzl under tests/python/ and inlines the register_python_tests macro directly inside python_tests.bzl. This simplifies the test suite layout while keeping legacy workspace gating completely intact.
Enables local PBS manifest file resolution in Bzlmod mode. Implemented attr.label_list attribute on python.override and updated _populate_from_pbs_manifest to read local files via module_ctx.read.
Separates free-threading and archive type from the build flavor string in parse_filename. Also includes canonical documentation citation in the docstring and updates manifest parsing assertions.
Documents local manifest file loading alongside remote manifest URLs. Includes unified Starlark example using @// label prefix.
Flattens parsed manifest entries into a single list and sorts by archive flavor (install_only > install_only_stripped > full) so smaller standalone archives take precedence.
Restores explicit whitelist validation on entry.archive_flavor to prevent unsupported standalone release asset formats from polluting available toolchain mappings.
# Conflicts: # tests/support/mocks/python_ext.bzl
Centralizes standalone Python runtime asset registration into python/runtimes_manifest.txt and parses it dynamically via _populate_from_pbs_manifest, replacing the static TOOL_VERSIONS table.
There was a problem hiding this comment.
Code Review
This pull request introduces support for dynamically fetching and registering Python runtimes from a python-build-standalone manifest file, replacing the hardcoded TOOL_VERSIONS map with a dynamic parser. Feedback on the implementation highlights several critical Starlark compatibility issues, such as the unsupported use of lambda expressions and string methods like removeprefix and removesuffix on older Bazel versions. Additionally, suggestions are provided to improve robustness by handling empty base download URLs, parsing tabs in manifests, and fixing a potential type error in the test suite.
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.
|
I really like this listing of it. It makes it really obvious and apparent how many runtimes are being registered (600+ !). It also just seems much easier to add/remove entries. The paths in the manifest are a bit funny: It looks like CI is failing on the workspace tests. I'm not keen to port all this functionality to workspace. I'm thinking, for workspace, we just replace some internals so it reads from the manifest file, but don't expose a Q: Should we have one manifest file, or split it along some axis? e.g. python version, platform, build date, etc. Q: Should we publish a runtime manifest as part of releases? The thought is it lets one easily "upgrade" the runtimes (treating rules_python as a trusted source) without having to upgrade rules_python itself. The counter argument is: one can always add a custom manifest. |
Instead of generating complex nested Starlark dictionaries during repository setup, internal_config_repo now generates a straightforward list of parsed manifest structs (MANIFEST_ENTRIES) using render.struct() and render.list(). The versions.bzl module dynamically converts these entries into the legacy TOOL_VERSIONS dictionary format when loaded during macro evaluation.
…times-manifest # Conflicts: # tests/python/python_tests.bzl
Update internal_config_repo_bzl and python_register_toolchains_bzl in python/private/BUILD.bazel to include their respective loaded modules so that Stardoc extracts API documentation successfully.
…flags Mitigate transient 504 Gateway Timeout network errors during downloads by adding secondary mirror fallback rewrites for Stardoc to downloader_config.cfg and scaling HTTP timeouts and retries in .bazelrc files.
Combat transient 504 Gateway Timeout network dropouts on external artifact downloads by escalating HTTP timeout scaling to 10.0 and downloader retries to 10 across bazelrc files, and adding a mirror rewrite rule for rules_java.
Ensure primary GitHub release URLs are attempted prior to secondary mirror fallbacks by adding primary pass-through rewrite rules for rules_java and stardoc across downloader_config.cfg files.
Sets `python_version = "3.14"` directly on `sphinx_build_binary` to ensure the documentation builder executes with a modern Python runtime capable of parsing PEP 695 type aliases in recent Sphinx releases.
Replaced fragile substring search over PLATFORMS.keys() with direct synthesis of the PLATFORMS dictionary key from structured struct fields (arch, vendor, os, libc, freethreaded). Eliminated defensive getattr() access. Factored entry sorting into _manifest_entry_sort_key preferring install_only and the lowest microarchitecture level.
…ntimes-manifest # Conflicts: # python/private/pbs_manifest.bzl # python/private/python.bzl
Renamed flavor to build_flavor in parse_filename and parse_sha_manifest to clearly distinguish runtime build configurations (e.g., debug, pgo+lto) from distribution release bundling schemes (archive_flavor).
…on releases Adds all prior release distribution entries (including historical Python 3.8-3.13 and freethreaded variant builds) to runtimes_manifest.txt to ensure dynamic runtime registration provides equivalent toolchain coverage to the previous static table.
Adds .agents/skills/monitor-ci-results containing continuous background polling and log analysis support scripts. Allows developers and automated agents to autonomously watch GitHub checks and Buildkite workflow executions for a PR, downloading full logs and reporting actionable resolution plans upon any failure.
…itories Removes the deprecated workspace_mode parameter from the internal_config_repo repository rule call inside python/private/py_repositories.bzl. Fully restores compatibility for legacy WORKSPACE macros across example and downstream projects.
Updates monitor_remote_ci.py to inspect job exit_status in addition to job state, correctly catching failures where Buildkite marks job state as 'finished'.
Enhances monitor_remote_ci.py to compute and display real-time summary counters (passed, failed, running, other) and log all discovered Buildkite job IDs across each polling cycle.
Removes individual job ID print statements from monitor_remote_ci.py to keep polling logs clean and streamlined. Retains the one-line Buildkite swarm summary breakdown (passed, failed, running, other).
Extracts and displays the underlying Buildkite Build ID / number alongside the Passed/Failed/Running swarm counters to clearly anchor active polling progress in the logs.
Streamlines the Buildkite summary line prefix to exactly 'Buildkite #{build_id}:' per user code review comment, improving log scan readability.
…lure skill Creates the analyze-ci-failure skill and migrates analyze_ci_failure.py out of monitor-ci-results. Updates monitor_remote_ci.py to only dispatch lightweight failure alerts rather than performing heavy log downloading and analysis itself. Also configures the monitor to ignore upstream rolling Bazel CI job incompatibilities.
Replaces the hardcoded 'rolling' job filter with an architectural inspection of the 'soft_failed' attribute in Buildkite metadata. Ensures that jobs allowed to fail are correctly categorized as passed/ignored rather than triggering failure alerts. Also removes cached runtime log artifacts from repository tracking.
Regenerates tests/integration/bzlmod_lockfile/MODULE.bazel.lock to reflect underlying Starlark implementation changes in rules_python extensions. Resolves integration test verification failures under lockfile_mode=error.
…starting a subagent Refines the alert text dispatched by monitor_remote_ci to explicitly prompt the recipient to invoke a subagent for failure analysis, supporting fully agentic background delegation.
…legation prompts
Adopts an exact imperative phrasing ("Start subagent: run analyze-ci-failure skill on this failure") in the failure alerts dispatched by monitor_remote_ci per direct code review instructions.
|
woo, success! I need to do some cleanup (later, its 1am), but this is finally passing. For the workspace problem: I just embedded a duplicate of runtimes_manifest.txt as a bzl file so it's easy to load. I don't want to put a lot of effort into workspace mode. Maybe a future change could add the ability to use custom manifests that get parsed at repo phase. |
…scripts Adds an absolute rule to AGENTS.md prohibiting the addition of Bazel copyright headers to new or existing files per user directives. Also purges existing Bazel copyright headers from our newly created analyze_ci_failure.py and monitor_remote_ci.py scripts.
…e reviews Refactors the runtimes manifest landscape by moving the catalog into python/private/ and establishing canonical automated synchronization tools (sort_manifest.py, sync_runtimes_manifest_workspace.py). Renames legacy manifest parsers to parse_runtime_manifest, privatizes internal tool logic, scrubs generic test mocks of hardcoded manifests, and reinforces the core diff and transition suites.
Updates runtime_manifests_tests.bzl to use python_ext.mctx instead of mocks.mctx to ensure the default runtimes manifest is available during test analysis.
…tests Adds macos execution platform constraints to py_exec_tools_toolchain test rules and splits flag transition tests into driver and consumer rules to ensure Bazel 10 toolchain resolution propagates correctly.
…lies in tests" This reverts commit bfaaccf.
…ark rule Removes print_toolchains_checksums from python/private/BUILD.bazel and purges print_toolchain_checksums.bzl as it is legacy functionality replaced by the public TOOL_VERSIONS map.
…guration Renames base_url attribute to base_urls on module extension override tags and defaults to provide multi-mirror download fallback. Outfits get_release_info with DEFAULT_RELEASE_BASE_URLS (GitHub astral-sh, releases.astral.sh, indygreg) to guarantee duplicate-free fallback resolution across all registered runtimes.
Enforces LF line endings on runtimes manifest files in .gitattributes and ensures sync_runtimes_manifest_workspace writes output files with LF to prevent checkout mismatches during Windows CI diff testing.
…mat links Adds entry to CHANGELOG.md explaining bzlmod runtimes manifest registration and adds seealso links to manifest file format docs in python.override add_runtime_manifest attributes.
|
FYI: This also adds several skills. I had pretty good results with them (it successfully fetched, diagnosed, reproduced, and fixed several CI failures on the first try and without going off the rails) |
This changes the list of runtimes that are registered to come from a file instead of
being logic within Starlark code.
Along the way...
settings as CI
which is faster and works better than the custom python program.
network failures.
#comments in the manifest