Bazel rules and toolchain support for Helm charts. Build chart dependencies from Chart.lock, render manifests with helm template, or produce an executable for helm upgrade --install.
- Working:
helm_chart,helm_deps,helm_template,helm_deploy - Toolchain: downloads Helm from official release archives
- Example:
examples/basic
# MODULE.bazel
bazel_dep(name = "rules_helm", version = "0.1.0")
helm_ext = use_extension("@rules_helm//helm:extensions.bzl", "helm")
helm_ext.toolchain(
version = "v4.1.0",
# sha256 = "...",
# url = "...",
)
helm_ext.deps(
name = "my_chart_deps",
helm_lock = "//:helm-lock.yaml",
)
use_repo(helm_ext, "helm_toolchain", "my_chart_deps")
register_toolchains("@helm_toolchain//:toolchain")# BUILD.bazel
load(
"@rules_helm//helm:defs.bzl",
"helm_chart",
"helm_deps",
"helm_deploy",
"helm_template",
)
helm_chart(
name = "my_chart",
srcs = glob(["chart/**"]),
strip_prefix = "chart",
)
helm_deps(
name = "my_chart_with_deps",
chart = ":my_chart",
deps = "@my_chart_deps//:deps",
)
helm_template(
name = "my_manifests",
chart = ":my_chart_with_deps",
release_name = "myapp",
namespace = "default",
values = ["values.yaml"],
)
helm_deploy(
name = "deploy_myapp",
chart = ":my_chart_with_deps",
release_name = "myapp",
namespace = "default",
values = ["values.yaml"],
extra_args = ["--atomic"],
)Run:
bazel build //:my_manifests
bazel run //:deploy_myappload("@rules_helm//helm:defs.bzl", "helm_deps_repository", "helm_register_toolchains")
helm_register_toolchains(
version = "v4.1.0",
# sha256 = "...",
# url = "...",
)
helm_deps_repository(
name = "my_chart_deps",
helm_lock = "//:helm-lock.yaml",
)Stages chart sources into a single directory so Helm can consume them.
Attributes
srcs: list of chart filesstrip_prefix: optional path prefix to strip (useful when chart files live under a subdir)
helm_chart(
name = "my_chart",
srcs = glob(["chart/**"]),
strip_prefix = "chart",
)Stages dependencies from a pre-fetched deps repository (no network at build time).
Attributes
chart:helm_chartoutputdeps: filegroup fromhelm_deps_repository(required)helm_lock: optionalhelm-lock.yamlto use instead of a chart-local lock
By default, helm_deps expects Chart.lock and helm-lock.yaml alongside Chart.yaml in the chart sources.
Use helm_lock to point at a shared or centralized lock file.
helm_deps(
name = "my_chart_with_deps",
chart = ":my_chart",
deps = "@my_chart_deps//:deps",
# helm_lock = "//:helm-lock.yaml",
)Renders manifests using helm template.
Attributes
chart:helm_chartorhelm_depsoutputrelease_name: default"release"namespace: optionalvalues: ordered list of values files
helm_template(
name = "my_manifests",
chart = ":my_chart_with_deps",
release_name = "myapp",
namespace = "default",
values = ["values.yaml", "values.prod.yaml"],
)Creates an executable that runs helm upgrade --install.
Attributes
chart:helm_chartorhelm_depsoutputrelease_name: default"release"namespace: optionalcreate_namespace: defaultTruevalues: ordered list of values fileskubeconfig: optional fileextra_args: list of extra Helm flags
The generated script also forwards CLI args, so you can append flags at runtime:
bazel run //:deploy_myapp -- --debug --dry-runPrefetches dependency archives listed in helm-lock.yaml into an external repo with a deps filegroup.
See:
examples/basicfor a working chart with a local subchart and a buildable manifest check.examples/remotefor a chart with a remote non‑OCI dependency locked viahelm-lock.yaml.examples/multifor multiple charts sharing a singlehelm-lock.yamlfile.
cd examples/basic
bazel build //:hello_manifests_checkhelm_register_toolchains()downloads Helm fromhttps://get.helm.sh/for the host platform.helm_deps_repositoryuses the same Helm version/sha/url attrs to pull dependency archives at repo sync time.- For reproducibility, provide
sha256and/or a pinnedurl. - Known SHA256s for
v4.1.0(officialget.helm.sharchives):darwin-amd64:a326073ae392bed8b73c415d1d9d6880b0f5accb18aa9456975562b44a87c650darwin-arm64:f12e2723c5e8eaff3e4b3670536867289fb6ab7f797fa2efedd1c53cfaca62fblinux-amd64:8e7ae5cb890c56f53713bffec38e41cd8e7e4619ebe56f8b31cd383bfb3dbb83linux-arm64:81315e404b6d09b65bee577a679ab269d6d44652ef2e1f66a8f922b51ca93f6bwindows-amd64:3c214081d51356a8e07ee610a1c3add30688e80adcd3bdfcfa4204f793b30f30
helm_depsexpects validChart.lockandhelm-lock.yamlfiles next toChart.yaml.- Dependency archives are fetched during repo sync via
helm_deps_repository; builds are offline after that. Chart.lockselects dependency versions;helm-lock.yamlpins artifact content (OCI digests or.tgzsha256s).helm_deployis a wrapper aroundhelm upgrade --installand does not enforce cluster safety.- The toolchain is host‑only today; no cross‑platform selection yet.
helm-lock.yaml unifies dependency selection, repository config, and artifact pinning in a single file.
OCI deps must be digest‑pinned using an oci:// reference that includes @sha256: (or a version string
that includes @sha256:).
The generator accepts a standard Helm repositories.yaml file (normally located under
~/.config/helm/repositories.yaml). In a Bazel monorepo, it’s common to check in a minimal
repo‑local file (for example helm-repositories.yaml at the repo root) and use it when generating
helm-lock.yaml so repositories can be referenced by name.
Example:
apiVersion: rules_helm/v1
kind: HelmLock
generated: "2026-01-27T00:00:00Z"
chart:
path: .
name: mychart
version: 1.2.3
chartYamlSha256: deadbeef...
repositories:
- name: example
url: https://charts.example.com
dependencies:
- name: dep
version: 4.5.6
repository: example
artifact:
type: tgz
sha256: feedface...Multi-chart lock (single file for multiple charts):
apiVersion: rules_helm/v1
kind: HelmLock
generated: "2026-01-27T00:00:00Z"
repositories:
- name: example
url: https://charts.example.com
charts:
- chart:
path: charts/app1
name: app1
version: 0.1.0
chartYamlSha256: deadbeef...
dependencies:
- name: dep1
version: 1.2.3
repository: example
artifact:
type: tgz
sha256: feedface...
- chart:
path: charts/app2
name: app2
version: 0.2.0
chartYamlSha256: cafebabe...
dependencies: []When using a multi-chart lock, point each helm_deps at the shared file with helm_lock = "helm-lock.yaml" and
reuse a single deps repo (e.g. deps = "@multi_deps//:deps").
Generate/update the file with:
bazel run //tools:helm_lock -- --chart path/to/chart --update
# optionally: --repository-config helm-repositories.yamlValidate in CI with:
bazel run //tools:helm_lock -- --chart path/to/chart --checkPrefetch dependency archives (Bzlmod):
bazel fetch @my_chart_deps//:deps @helm_toolchain//:toolchainPrefetch dependency archives (WORKSPACE):
bazel fetch @my_chart_deps//:depsIssues and PRs are welcome. If you add new rules or attributes, please update this README and the example.