Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions setup/ubuntu/packages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@
"type": "download_deb",
"name": "bazelisk",
"version": "1.29.0",
"arches": ["amd64"],
"codenames": ["noble", "resolute"],
"arches": [
"amd64"
],
"codenames": [
"noble",
"resolute"
],
"sha256": "186d78a20e1a64f59ba08987791a989892d142c9d3a9f9cc0c5c35e201f53924",
"urls": [
"https://github.com/bazelbuild/bazelisk/releases/download/v1.29.0/bazelisk-amd64.deb"
Expand All @@ -14,8 +19,13 @@
"type": "download_deb",
"name": "bazelisk",
"version": "1.29.0",
"arches": ["arm64"],
"codenames": ["noble", "resolute"],
"arches": [
"arm64"
],
"codenames": [
"noble",
"resolute"
],
"sha256": "db8ada89c841afd2cb33db7d13aa98ea4fb14612579a8bae84722250caa84272",
"urls": [
"https://github.com/bazelbuild/bazelisk/releases/download/v1.29.0/bazelisk-arm64.deb"
Expand All @@ -25,12 +35,16 @@
"type": "download_deb",
"name": "kcov",
"version": "43+dfsg-1",
"arches": ["amd64"],
"codenames": ["noble"],
"arches": [
"amd64"
],
"codenames": [
"noble"
],
"sha256": "d192fd3cfd0d63e95f13a1b2120d0603a31b3a034b82c618d5e18205517d5cbb",
"urls": [
"https://drake-mirror.csail.mit.edu/ubuntu/pool/universe/k/kcov/kcov_43%2Bdfsg-1_amd64.deb"
],
"note": "Because Noble does not offer kcov natively, this file was mirrored from Ubuntu 25.04 Plucky at https://packages.ubuntu.com/plucky/kcov."
}
]
]
16 changes: 15 additions & 1 deletion tools/workspace/bazelisk_internal/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
load("//tools/lint:lint.bzl", "add_lint_tests")
load("//tools/skylark:drake_py.bzl", "drake_py_unittest")
load("//tools/skylark:drake_py.bzl", "drake_py_binary", "drake_py_unittest")

drake_py_binary(
name = "upgrade",
srcs = ["upgrade.py"],
data = [
"@bazelisk_internal//:LICENSE",
"@bazelisk_internal//:bazelisk.py",
],
env = {
"DRAKE_BAZELISK_LICENSE_PATH": "$(rlocationpath @bazelisk_internal//:LICENSE)",
"DRAKE_BAZELISK_PY_PATH": "$(rlocationpath @bazelisk_internal//:bazelisk.py)",
},
deps = ["@rules_python//python/runfiles"],
)

drake_py_unittest(
name = "lint_test",
Expand Down
26 changes: 9 additions & 17 deletions tools/workspace/bazelisk_internal/repository.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,17 @@ def bazelisk_internal_repository(
name = name,
repository = "bazelbuild/bazelisk",
upgrade_advice = """
When updating, the following additional steps (run in the Drake source
tree) must also be performed:

$ bazel build @bazelisk_internal//:*
$ cp -t third_party/com_github_bazelbuild_bazelisk/ \\
bazel-drake/external/+internal_repositories+bazelisk_internal/LICENSE \\
bazel-drake/external/+internal_repositories+bazelisk_internal/bazelisk.py

Additionally, you must manually update the version numbers in
setup/ubuntu/packages.json
and adjust the expected checksums accordingly.
To calculate a new checksum, download the deb file specifed in the json
and use:
shasum -a 256 'xxx.deb'

To fully test, a Linux uprovisioned job must be launched from the
pull request.
When upgrading, most Linux uprovisioned jobs should be launched from
the pull request. See the jenkins-jobs-experimental branch on
RobotLocomotion/drake for job lists.
""", # noqa
upgrade_type = "release",
post_upgrade_script = "upgrade.py",
# Our upgrade.py modifies things outside of the current directory.
extra_upgrade_paths = [
"setup/ubuntu",
"third_party/com_github_bazelbuild_bazelisk",
],
commit = "v1.29.0",
sha256 = "7e4c7b8ade016052e63c1553cb4fbe0c4fe921e1e66913d49eef074ed894e933", # noqa
build_file = ":package.BUILD.bazel",
Expand Down
106 changes: 106 additions & 0 deletions tools/workspace/bazelisk_internal/upgrade.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/usr/bin/env python3

"""
upgrade.py - Upgrades Drake's version of bazelisk.

This program is only tested / supported on Ubuntu.
"""

# noqa: shebang
# We suppress shebang lint checking because we have a magic trampoline atop our
# main function that allows us to re-execute ourselves using Bazel.

import hashlib
import json
import os
from pathlib import Path
import re
import shutil
import tempfile
from urllib.parse import urlparse
import urllib.request


def _get_url_sha256(url: str) -> str:
hasher = hashlib.sha256()
with tempfile.TemporaryDirectory("drake-bazelisk") as tmp:
tmp_file = Path(tmp) / os.path.basename(urlparse(url).path)
with (
tmp_file.open("wb") as f,
urllib.request.urlopen(url=url, timeout=30) as response,
):
while True:
data = response.read(4096)
if not data:
break
hasher.update(data)
f.write(data)
return hasher.hexdigest()


def main():
bazelisk_license_path = os.environ.get("DRAKE_BAZELISK_LICENSE_PATH")
if bazelisk_license_path is None:
# Operate relative to the root of the Drake source tree.
os.chdir(Path(__file__).resolve().parents[3])
os.execvp(
"bazel",
["bazel", "run", "//tools/workspace/bazelisk_internal:upgrade"],
)

# This import only works when run via Bazel, so must come after the re-exec.
from python import runfiles

manifest = runfiles.Create()

mydir = (
Path(os.environ["BUILD_WORKSPACE_DIRECTORY"])
/ "tools/workspace/bazelisk_internal"
)

# Find out which version we are pinned to (new_release has already upgraded
# our repository.bzl).
new_version = None
my_version_re = re.compile(r'commit\s*=\s*["\']([^"\']+)["\']')
repo_bzl_lines = (
(mydir / "repository.bzl").read_text(encoding="utf-8").splitlines()
)
for line in repo_bzl_lines:
m = my_version_re.search(line)
if m:
new_version = m.group(1)
break
assert new_version

# Upgrade setup/ubuntu/packages.json.
setup_dir = (
Path(os.environ["BUILD_WORKSPACE_DIRECTORY"]) / "setup" / "ubuntu"
)
packages = json.loads(
(setup_dir / "packages.json").read_text(encoding="utf-8")
)
for package in packages:
if package["name"] != "bazelisk":
continue
for i, url in enumerate(package["urls"]):
package["urls"][i] = re.sub(r"v\d+\.\d+\.\d+", new_version, url)
package["sha256"] = _get_url_sha256(package["urls"][0])
(setup_dir / "packages.json").write_text(json.dumps(packages, indent=4))

# Upgrade our third_party copy.
bazelisk_py_path = os.environ.get("DRAKE_BAZELISK_PY_PATH")
bazelisk_files = {
manifest.Rlocation(bazelisk_license_path),
manifest.Rlocation(bazelisk_py_path),
}
third_party_dir = (
Path(os.environ["BUILD_WORKSPACE_DIRECTORY"])
/ "third_party"
/ "com_github_bazelbuild_bazelisk"
)
for file in bazelisk_files:
shutil.copy2(file, third_party_dir)


if __name__ == "__main__":
main()
34 changes: 33 additions & 1 deletion tools/workspace/github.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ def github_archive(
local_repository_override = None,
mirrors = None,
upgrade_advice = "",
post_upgrade_script = "",
extra_upgrade_paths = None,
**kwargs):
"""A macro to be called in the MODULE.bazel that adds an external from
GitHub using a workspace rule.
Expand Down Expand Up @@ -82,6 +84,13 @@ def github_archive(
upgrade_advice: optional string that describes extra steps that should
be taken when upgrading to a new version.
Used by //tools/workspace:new_release.
post_upgrade_script: optional string describing a path to an upgrade
script to be run after the automated upgrade, relative to the
package.
Used by //tools/workspace:new_release.
extra_upgrade_paths: optional list of directories that are expected
to (at least potentially) be changed when upgrading.
Used by //tools/workspace:new_release.
"""
if repository == None:
fail("Missing repository=")
Expand Down Expand Up @@ -131,6 +140,8 @@ def github_archive(
extra_strip_prefix = extra_strip_prefix,
mirrors = mirrors,
upgrade_advice = upgrade_advice,
post_upgrade_script = post_upgrade_script,
extra_upgrade_paths = extra_upgrade_paths,
**kwargs
)

Expand Down Expand Up @@ -204,6 +215,12 @@ _github_archive_real = repository_rule(
"upgrade_advice": attr.string(
default = "",
),
"post_upgrade_script": attr.string(
default = "",
),
"extra_upgrade_paths": attr.string_list(
default = [],
),
},
)
"""This is a rule() formulation of the github_archive() macro. It is identical
Expand Down Expand Up @@ -236,6 +253,8 @@ def setup_github_repository(repository_ctx):
sha256 = repository_ctx.attr.sha256,
extra_strip_prefix = repository_ctx.attr.extra_strip_prefix,
upgrade_advice = getattr(repository_ctx.attr, "upgrade_advice", ""),
post_upgrade_script = getattr(repository_ctx.attr, "post_upgrade_script", ""),
extra_upgrade_paths = getattr(repository_ctx.attr, "extra_upgrade_paths", None),
)

# Optionally apply source patches, using Bazel's utility helper. Here we
Expand Down Expand Up @@ -267,6 +286,8 @@ def github_download_and_extract(
sha256 = "0" * 64,
extra_strip_prefix = "",
upgrade_advice = "",
post_upgrade_script = "",
extra_upgrade_paths = None,
upgrade_cooldown_days = None,
commit_pin = None):
"""Download an archive of the provided GitHub repository and commit to the
Expand Down Expand Up @@ -304,6 +325,13 @@ def github_download_and_extract(
upgrade_advice: optional string that describes extra steps that should
be taken when upgrading to a new version.
Used by //tools/workspace:new_release.
post_upgrade_script: optional string describing a path to an upgrade
script to be run after the automated upgrade, relative to the
package.
Used by //tools/workspace:new_release.
extra_upgrade_paths: optional list of directories that are expected
to (at least potentially) be changed when upgrading.
Used by //tools/workspace:new_release.
"""
urls = _urls(
repository = repository,
Expand Down Expand Up @@ -338,10 +366,12 @@ def github_download_and_extract(
if upgrade_type not in ["release", "tag"] and exclude_tags_pattern:
fail("exclude_tags_pattern can only be used for releases or tags")

repository_rule_type = "github_script" if post_upgrade_script != "" else "github"

# Create a summary file for Drake maintainers.
generate_repository_metadata(
repository_ctx,
repository_rule_type = "github",
repository_rule_type = repository_rule_type,
repository = repository,
upgrade_type = upgrade_type,
upgrade_cooldown_days = upgrade_cooldown_days,
Expand All @@ -353,6 +383,8 @@ def github_download_and_extract(
urls = urls,
strip_prefix = strip_prefix,
upgrade_advice = upgrade_advice,
post_upgrade_script = post_upgrade_script,
extra_upgrade_paths = extra_upgrade_paths,
)

def _sha256(sha256):
Expand Down
Loading