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
3 changes: 3 additions & 0 deletions python3/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ load("//private/util:tar.bzl", "tar")
load(":config.bzl", "PYTHON_ARCHITECTURES", "PYTHON_DISTROS", "PYTHON_PACKAGES")
load(":ldconfig.bzl", "python3_ldconfig")
load(":python.bzl", "python3_image", "python3_image_index")
load(":version_test.bzl", "clean_python_version_test")

package(default_visibility = ["//visibility:public"])

Expand Down Expand Up @@ -42,3 +43,5 @@ python3_ldconfig(
architectures = PYTHON_ARCHITECTURES["debian13"],
distro = "debian13",
)

clean_python_version_test(name = "clean_python_version_test")
13 changes: 12 additions & 1 deletion python3/python.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ load("@rules_oci//oci:defs.bzl", "oci_image", "oci_image_index")
load("//common:variables.bzl", "DEBUG_MODE", "OS_RELEASE", "USERS")
load("//private/util:deb.bzl", "deb")
load("//private/util:tar.bzl", "tar")
load(":version.bzl", "clean_python_version")

DISTRO_VERSION = {
"debian13": "3.13",
Expand Down Expand Up @@ -50,6 +51,13 @@ def python3_image(distro, arch, packages):
"""
python_alias(distro)

_python_version = clean_python_version(deb.version(
arch,
distro,
"python" + DISTRO_VERSION[distro] + "-minimal",
"python",
))

for mode in DEBUG_MODE:
for user in USERS:
oci_image(
Expand All @@ -65,7 +73,10 @@ def python3_image(distro, arch, packages):
deb.package(arch, distro, pkg, "python")
for pkg in packages
] + [":python_aliases_%s" % distro] + ([":ldconfig_cache_" + arch] if distro == "debian13" else []),
annotations = {"org.opencontainers.image.source": OS_RELEASE["HOME_URL"]},
annotations = {
"org.opencontainers.image.source": OS_RELEASE["HOME_URL"],
"com.google.distroless.python.version": _python_version,
},
)

for user in USERS:
Expand Down
23 changes: 23 additions & 0 deletions python3/version.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"Python version helper functions"

def clean_python_version(version_string):
"""Clean Debian package version to get upstream Python version.

Handles epochs (prefix before first ':') and Debian revisions (suffix after last '-').
"""

# Handle epoch (split at first ':')
epoch_parts = version_string.partition(":")
if epoch_parts[1]: # separator found
version_string = epoch_parts[2]
else:
version_string = epoch_parts[0]

# Handle revision (split at last '-')
rev_parts = version_string.rpartition("-")
if rev_parts[1]: # separator found
version_string = rev_parts[0]
else:
version_string = rev_parts[2]

return version_string
33 changes: 33 additions & 0 deletions python3/version_test.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest")
load(":version.bzl", "clean_python_version")

def _clean_python_version_test_impl(ctx):
env = unittest.begin(ctx)

# Standard Debian version: upstream-revision
asserts.equals(env, "3.13.5", clean_python_version("3.13.5-2"))

# With epoch: epoch:upstream-revision
asserts.equals(env, "3.13.5", clean_python_version("1:3.13.5-2"))

# With epoch and complex revision (e.g. backport)
asserts.equals(env, "3.13.5", clean_python_version("1:3.13.5-2+deb13u3"))

# Raw upstream only (no revision, no epoch)
asserts.equals(env, "3.13.5", clean_python_version("3.13.5"))

# Upstream containing hyphens (should preserve hyphens in upstream, split at last hyphen)
asserts.equals(env, "3.13.5-rc1", clean_python_version("3.13.5-rc1-1"))

# Upstream containing hyphens and epoch
asserts.equals(env, "3.13.5-rc1", clean_python_version("1:3.13.5-rc1-1"))

# Upstream containing colons (unlikely but test robustness)
# partition(":")[:] should handle it if we only split at first colon
asserts.equals(env, "3.13:5", clean_python_version("1:3.13:5-1"))

return unittest.end(env)

clean_python_version_test = unittest.make(
impl = _clean_python_version_test_impl,
)
Loading