rules_helm icon indicating copy to clipboard operation
rules_helm copied to clipboard

Split `helm_import_repository` into different rules per source type

Open zachburg opened this issue 4 months ago • 8 comments

Right now, helm_import_repository supports three different use cases:

  • Downloading a chart from the specified HTTP URL
  • Finding a chart in a HTTP repository
    • Note that index.yaml may provide a oci:// URL here
  • Downloading a chart from an OCI registry

Two issues discovered here:

  1. No support for specifying by digest instead of version tag for OCI URLs:

    oci://registry-1.docker.io/bitnamicharts/grafana@sha256:015f66a231a809557ab368d903f6762ba31ba2f7b3d0f890445be6e8f213cff1

    This is not valid in helm though, helm requires specifying tag in the URL or setting the --version flag.

  2. Can't always determine version from URL:

    aws-cluster-autoscaler-1.2.3-rc.tgz is a possible chart package file name (Ref: https://helm.sh/docs/chart_best_practices/conventions/#chart-names), but there's no clear way to separate the version (1.2.3-rc) from the name of aws-cluster-autoscaler.

I propose splitting helm_import_repository into three different rules:

  • helm_import_url to import a chart from a HTTP URL
  • helm_import_repository to import a chart from a HTTP repository by finding it in index.yaml
  • helm_import_registry to import a chart from an OCI registry.

Splitting into separate rules will make it easier to manage the code and avoid the issues mentioned earlier.

Unfortunately, this would be a breaking change for current users. @abrisco, thoughts?

zachburg avatar Aug 21 '25 01:08 zachburg

Maybe some history will help reveal a path forward:

The original design of helm_import_repository was to support users specifying chart names, versions, and repositories, just as they would outside of Bazel, to fetch a dependency. Though, in the spirit of Bazel's determinism, the rule would recommend adding the sha256 checksum and url of the chart file so the dependency would be reproducible. I felt like this was low friction to new adopters familiar with helm and unfamiliar with Bazel and that Bazel would encourage modifying the repository rule instantiation to be reproducible. If oci registries don't support the same behavior, I would split oci logic into another rule and still aim to allow users to take the same info they might add to their chart.yaml files and add them to MODULE.bazel.

That being said though, I've not been a new user in a while so perhaps the UX I thought was cool was actually bad. Does that flavored history help in any way? 😅

abrisco avatar Aug 22 '25 02:08 abrisco

Working/thinking through this more, I think it makes sense to split into two rules:

  • helm_import_url to import from a HTTP or OCI URL, which would be similar to helm_import for importing a local chart package. With the sha256 sum, this would be deterministic and preferred.

  • helm_import_repository to look up a chart from a HTTP repository, given the repository, chart name, and chart version. Maybe this should never be deterministic and recommend adopting helm_import_url, which would be deterministic given URL and sha256 sum.

zachburg avatar Aug 22 '25 04:08 zachburg

Looking at the Bazel documentation for repository rules, they should only be returning the parameters that make the rule reproducible.

So I think for importing from a repository, the repository name, chart name, and version are enough to make it reproducible, but the rule still should accept a checksum. It shouldn't return the sum since we can't use that to locate the chart.

For importing from a OCI registry, you can specify a container digest, which is a sha256 sum, but it is from the entire container image and the chart layer (the .tgz file) has its sum that should be verified against.

zachburg avatar Aug 22 '25 05:08 zachburg

Also, one thing that might be leading to some confusion is the _repository suffix is a pattern I've been using for all repository rules (I forget where I adopted that from). Maybe it'd be better to call it helm_repository_import and helm_url_import?

abrisco avatar Aug 22 '25 15:08 abrisco

I think sticking with helm_import_url would be better since this alphabetically sorts with the other helm_import rules.

I can't find any reference recommending that repository rules end with _repository. I was thinking here that it was referring to importing from a Helm chart repository, and not that the rule itself was a Bazel repository rule.

If we really wanted to have parity with Helm though, we would use helm pull inside of the import rules. This is done in https://github.com/bazel-contrib/rules_jvm_external/tree/master which calls external programs to pull JARs.

zachburg avatar Aug 22 '25 21:08 zachburg

I've taken a look at other repository_rule use cases for fetching external user-specified dependencies (compared to downloading tools like maven or helm) in https://github.com/bazel-contrib/rules_oci/blob/1605dcde9b30cb64528a0d1cce7144c9f63cc82a/oci/private/pull.bzl and https://github.com/bazel-contrib/rules_python/blob/fe45faabeb3dceab8766fb1a67131ec0cc1135dc/python/private/pypi/pip_repository.bzl#L73 and they don't return anything from their rules, so I think the import rules here should be updated to resolve https://github.com/abrisco/rules_helm/issues/189.

zachburg avatar Aug 22 '25 23:08 zachburg

Another reason to use helm pull instead of the Bazel downloader for pulling charts is to let Helm handle authentication, like how real Helm is used to push charts in https://github.com/abrisco/rules_helm/blob/main/helm/private/registrar/registrar.go.

https://github.com/abrisco/rules_helm/pull/197/commits/4bca75577a30c74e55d071253751161b92e18228

zachburg avatar Sep 24 '25 22:09 zachburg

I just wanted to share that the first issue raised:

No support for specifying by digest instead of version tag for OCI URLs:

oci://registry-1.docker.io/bitnamicharts/grafana@sha256:015f66a231a809557ab368d903f6762ba31ba2f7b3d0f890445be6e8f213cff1

This is not valid in helm though, helm requires specifying tag in the URL or setting the --version flag.

is not an issue in the upcoming Helm v4 release. It is definitely still an issue when using older versions though!

Enhanced OCI Support

Install charts by digest for better supply chain security. For example, helm install myapp oci://registry.example.com/charts/app@sha256:abc123.... Charts with non-matching digests are not installed.

mjlshen avatar Oct 30 '25 03:10 mjlshen