diff --git a/MODULE.bazel b/MODULE.bazel index 553f81e..d40e1c6 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -6,6 +6,7 @@ module( bazel_dep(name = "aspect_bazel_lib", version = "2.15.3") bazel_dep(name = "bazel_skylib", version = "1.7.1") bazel_dep(name = "gazelle", version = "0.43.0") +bazel_dep(name = "package_metadata", version = "0.0.7") bazel_dep(name = "rules_go", version = "0.54.0") bazel_dep(name = "rules_pkg", version = "1.1.0") bazel_dep(name = "stardoc", version = "0.8.0") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index f36faf8..350b72b 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -62,6 +62,8 @@ "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", "https://bcr.bazel.build/modules/jsoncpp/1.9.5/source.json": "4108ee5085dd2885a341c7fab149429db457b3169b86eb081fa245eadf69169d", "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", + "https://bcr.bazel.build/modules/package_metadata/0.0.7/MODULE.bazel": "7adb03933fc8401f495800cf4eafcff0edc6da0ff55c7db223ef69d19f689486", + "https://bcr.bazel.build/modules/package_metadata/0.0.7/source.json": "50639625e937b56115012674c797cca7a05a96b4878c87d803c13dc2b31de8a0", "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", "https://bcr.bazel.build/modules/platforms/0.0.10/source.json": "f22828ff4cf021a6b577f1bf6341cb9dcd7965092a439f64fc1bb3b7a5ae4bd5", "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", diff --git a/WORKSPACE b/WORKSPACE index 205e32c..5146e47 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1 +1,10 @@ workspace(name = "com_github_datadog_rules_oci") + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +http_archive( + name = "package_metadata", + sha256 = "8f27dc7393e3f3bdc793bdc4ba36d67a63c22cc9d38cc65d3204654974ea4563", + strip_prefix = "supply-chain-0.0.7/metadata", + url = "https://github.com/bazel-contrib/supply-chain/releases/download/v0.0.7/supply-chain-v0.0.7.tar.gz", +) diff --git a/oci/pull.bzl b/oci/pull.bzl index 61fe08c..b50cf55 100755 --- a/oci/pull.bzl +++ b/oci/pull.bzl @@ -1,5 +1,7 @@ """ pull """ +load("@package_metadata//:defs.bzl", "package_metadata") + # A directory to store cached OCI artifacts # TODO(griffin) currently not used, but going to start depending on this for # integration into the bzl wrapper. @@ -51,6 +53,36 @@ def generate_build_files(rctx, layout_root, digest = ""): if res.return_code > 0: failout("failed to pull manifest", res) +def _generate_package_metadata(rctx, registry, repository, digest): + """Generate a package_metadata BUILD file for the pulled image. + + Args: + rctx: repository context + registry: OCI registry (e.g., "ghcr.io") + repository: OCI repository path (e.g., "datadog/rules_oci/ubuntu") + digest: Image digest (e.g., "sha256:...") + """ + # Construct PURL for OCI image + # Format: pkg:oci/[name]@[digest]?repository_url=[registry_url] + purl = "pkg:oci/{repository}@{digest}?repository_url=https://{registry}".format( + repository = repository.replace("/", "%2F"), + digest = digest, + registry = registry, + ) + + # Create metadata directory + metadata_dir = rctx.path("metadata") + rctx.file(metadata_dir.get_child("BUILD.bazel"), content = """# Generated package metadata for pulled OCI image + +load("@package_metadata//:defs.bzl", "package_metadata") + +package_metadata( + name = "metadata", + purl = "{purl}", + visibility = ["//visibility:public"], +) +""".format(purl = purl)) + def _oci_pull_impl(rctx): pull( rctx, @@ -67,6 +99,20 @@ def _oci_pull_impl(rctx): digest = rctx.attr.digest, ) + # Generate package metadata for supply chain tracking + _generate_package_metadata( + rctx, + registry = rctx.attr.registry, + repository = rctx.attr.repository, + digest = rctx.attr.digest, + ) + + # Create REPO.bazel to set default package metadata for the entire repository + rctx.file("REPO.bazel", content = """# Repository-level configuration for pulled OCI image + +repo(default_package_metadata = ["//metadata:metadata"]) +""") + oci_pull = repository_rule( implementation = _oci_pull_impl, doc = """