Skip to content

Give imported charts a package_metadata with an OCI purl - #311

Open
darkrift wants to merge 3 commits into
periareon:mainfrom
darkrift:helm-import-package-metadata
Open

darkrift wants to merge 3 commits into
periareon:mainfrom
darkrift:helm-import-package-metadata

Conversation

@darkrift

@darkrift darkrift commented Nov 3, 2026 •

Copy link
Copy Markdown

helm_import_repository now generates a package_metadata target next to each imported chart and sets it as the package_metadata of the helm_import target, so SBOM and license tooling built on bazel-contrib/supply-chain can identify charts that come from outside the workspace.

A chart is identified by an oci purl whose repository_url and tag qualifiers carry where the chart was fetched from and its version:

Import purl
url = "https://charts.bitnami.com/bitnami/postgresql-14.0.5.tgz" pkg:oci/postgresql?repository_url=https:%2F%2Fcharts.bitnami.com%2Fbitnami&tag=14.0.5
repository = "https://charts.jetstack.io", chart_name = "trust-manager", version = "v0.24.0" pkg:oci/trust-manager?repository_url=https:%2F%2Fcharts.jetstack.io&tag=v0.24.0
url = "oci://public.ecr.aws/karpenter/karpenter:1.9.0" pkg:oci/karpenter?repository_url=oci:%2F%2Fpublic.ecr.aws%2Fkarpenter&tag=1.9.0

With url, repository_url is the chart's parent path; with repository, it is the repository itself.

Bazel 8.0.0 renamed the applicable_licenses common attribute to package_metadata, so on Bazel 7 the generated helm_import sets applicable_licenses instead; the package_metadata target itself is the same.

The purl is built by a new helm_import_package_metadata macro, exported from @rules_helm//helm:defs.bzl, which the generated BUILD.bazel loads instead of loading @package_metadata directly. A repo created with use_repo_rule resolves labels through the calling module's repo mapping, so a direct load fails in every workspace that does not itself depend on package_metadata. Going through rules_helm keeps that dependency on the rules_helm side, as the new bazel_dep(name = "package_metadata", version = "0.0.13").

The module itself declares its metadata too: //:package_metadata carries pkg:bazel/rules_helm@0.34.0 from purl.bazel(module_name(), module_version()), and REPO.bazel makes it the default_package_metadata of every target in the module.

Testing

From a scratch module that depends on rules_helm (through local_path_override) but not on package_metadata, bazel build of charts imported with url and with repository succeeds on Bazel 9.3.1 and 7.7.2, and bazel query --output=build shows the package_metadata target and the helm_import target referencing it (through applicable_licenses on 7.7.2). In this repository, bazel build //helm/... //docs:helm_import and bazel run //:buildifier.check pass, and the helm_test extension's postgresql and trust-manager repos carry the purls above. The OCI registries reject anonymous token requests from my network, so the OCI imports in //tests/with_external_deps are left to CI.

repo(default_package_metadata = ...) in REPO.bazel and module_name()/module_version() in a BUILD file work on Bazel 7.7.2, 8.0.0 and 9.3.1 (checked in a scratch module, where the default reaches the targets on 7.7.2 as applicable_licenses); here, bazel query 'deps(//helm:current_toolchain, 1)' lists //:package_metadata.

🤖 Generated with Claude Code

darkrift and others added 3 commits November 3, 2026 12:54
`helm_import_repository` now generates a `package_metadata` target next
to each imported chart and sets it as the `package_metadata` of the
`helm_import` target, so supply-chain tooling can identify charts that
come from outside the workspace. The chart is identified by an `oci`
purl whose `repository_url` and `tag` qualifiers carry where the chart
was fetched from and its version.

The purl is built by a new `helm_import_package_metadata` macro exported
from `//helm:defs.bzl`, which the generated BUILD file loads instead of
loading `@package_metadata` directly: a repo created with
`use_repo_rule` resolves labels through the calling module's repo
mapping, so a direct load fails in every workspace that does not itself
depend on `package_metadata`.

Bazel 8.0.0 renamed the `applicable_licenses` common attribute to
`package_metadata`, so on Bazel 7 the generated `helm_import` sets
`applicable_licenses` instead.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`//:package_metadata` identifies rules_helm by the purl
`pkg:bazel/rules_helm@<version>`, and `REPO.bazel` makes it the
`default_package_metadata` of every target in the module.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

@abrisco abrisco left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay here, I'll take a look this weekend!

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants