blob: d7891a99742313fd21a72a2fecaa823b025798e0 [file]
"""Defines the rbe_preconfig rule for Bazel CI
Note: this implementation is deliberately incrementally-incorrect. The
same manifest.json file is overwritten with new configurations, and we don't
validate it's checksum. A clean build / re-sync is required to pick up the changes.
"""
def _available_bazel_versions(manifests):
bazel_versions = []
for manifest in manifests:
bazel_versions.append("'{}'".format(manifest["bazel_version"]))
return ", ".join(bazel_versions)
def _available_toolchain_names(manifest):
names = []
for toolchain in manifest["toolchains"]:
names.append("'{}'".format(toolchain["name"]))
return ", ".join(names)
def _major(version):
return bazel_version.split(".")[0]
def _find_manifest(manifests, bazel_version):
# Exact match
for manifest in manifests:
if manifest["bazel_version"] == bazel_version:
return manifest
# Major version match
want_major = _major(bazel_version)
for manifest in manifests:
if _major(manifest["bazel_version"]) == want_major:
print("\nrbe_preconfig: Unsupported version '{}' (Values: {}), using major version match '{}'.\n".format(bazel_version, _available_bazel_versions(manifests), manifest["bazel_version"]))
return manifest
manifest = manifests[0]
print("\nrbe_preconfig: Unsupported version '{}' (Values: {}), using default '{}'.\n".format(bazel_version, _available_bazel_versions(manifests), manifest["bazel_version"]))
return manifest
def _find_toolchain(manifest, toolchain_name):
for toolchain in manifest["toolchains"]:
if toolchain["name"] == toolchain_name:
return toolchain
return None
def _auto_detect_bazel_version(manifests):
bazel_version = "UNKNOWN"
if "bazel_version" in dir(native) and native.bazel_version:
bazel_version = native.bazel_version
return _find_manifest(manifests, bazel_version)
def _rbe_preconfig_impl(repository_ctx):
"""Download pre-generated RBE toolchain configs based on current Bazel version.
The manifest is fetched everytime running this repo rule so we can get the
latest configs without upgrading this rule.
Args:
toolchain: The name of the pre-generated toolchain.
"""
toolchain_name = repository_ctx.attr.toolchain
manifest_json = "manifest.json"
# Omit sha256 since remote file can be changed
repository_ctx.download(
output = manifest_json,
url = ["https://storage.googleapis.com/bazel-ci/rbe-configs/manifest.json"],
)
manifests = json.decode(repository_ctx.read(manifest_json))
manifest = _auto_detect_bazel_version(manifests)
toolchain = _find_toolchain(manifest, toolchain_name)
if not toolchain:
fail("\nrbe_preconfig: Unsupported toolchain '{}' (Values: {}).\n".format(toolchain_name, _available_toolchain_names(manifest)))
repository_ctx.download_and_extract(
url = toolchain["urls"],
sha256 = toolchain["sha256"],
)
rbe_preconfig = repository_rule(
implementation = _rbe_preconfig_impl,
attrs = {
"toolchain": attr.string(
mandatory = True,
),
},
)