From 952091416c4eda2dc4106909d88f0aa49f238c6b Mon Sep 17 00:00:00 2001 From: Vigilans Date: Wed, 31 Dec 2025 01:08:35 +0800 Subject: [PATCH] feat: add documents for cross-release references and relative template functions Signed-off-by: Vigilans --- .../cross-release-reference/README.md | 85 +++++++++++++++++++ .../cross-release-reference/helmwave.yml | 30 +++++++ .../values/backend.yml | 29 +++++++ .../cross-release-reference/values/redis.yml | 3 + docs/examples/values-dependencies/README.md | 12 +++ docs/tpl.md | 43 +++++++++- mkdocs.yml | 1 + 7 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 docs/examples/cross-release-reference/README.md create mode 100644 docs/examples/cross-release-reference/helmwave.yml create mode 100644 docs/examples/cross-release-reference/values/backend.yml create mode 100644 docs/examples/cross-release-reference/values/redis.yml diff --git a/docs/examples/cross-release-reference/README.md b/docs/examples/cross-release-reference/README.md new file mode 100644 index 00000000..858ad323 --- /dev/null +++ b/docs/examples/cross-release-reference/README.md @@ -0,0 +1,85 @@ +# Cross-release reference + +> Introduced in [:material-tag: v0.43.0](https://github.com/helmwave/helmwave/releases/tag/v0.43.0) + +Since v0.43.0, releases are built in dependency order. This means a release can reference the already-built manifests and values of its dependencies declared in `depends_on`. + +This enables powerful cross-release data sharing: + +- Access the entire plan configuration using `getPlan`. Useful for accessing the field of other releases, like `tags` or `store`. +- Access a dependency's rendered values using `getValues`. +- Access a dependency's rendered manifests using `getManifests`. Useful for retrieving helm-generated secrets. + +## How it works + +```mermaid +graph LR + redis[redis release] --> backend[backend release] + redis -->|build values| redis_values[redis values] + redis -->|build manifests| redis_manifests[redis manifests] + redis_values -->|getValues| backend + redis_manifests -->|getManifests| backend +``` + +When helmwave builds the plan: + +1. Releases are sorted by their dependency graph +2. Each release's values are built immediately before its manifests +3. Dependent releases can access their dependencies' built artifacts via template functions + +## Example + +**Project Structure** + +```shell +⟨⟨ run_script("tree docs/examples/cross-release-reference") ⟩⟩ +``` + +```yaml title="helmwave.yml" +{% include "./helmwave.yml" %} +``` + +```yaml title="values/redis.yml" +{% include "./values/redis.yml" %} +``` + +```yaml title="values/backend.yml" +{% include "./values/backend.yml" %} +``` + +## Template functions + +### `getPlan` + +Access the entire plan configuration, including all releases' `store` fields: + +```yaml +{{ $plan := getPlan }} +{{ range $plan.releases }} +{{- if eq .name "redis" }} +redis_port: {{ .store.port }} +{{- end }} +{{ end }} +``` + +### `getValues` + +Fetch rendered values from a depending release: + +```yaml +{{ $redisValues := getValues "redis@my-namespace" "values/redis.yml" }} +redis_host: {{ $redisValues.connection.host }} +``` + +### `getManifests` + +Fetch rendered manifests from a depending release as an array of Kubernetes objects. This is useful for accessing helm-generated secrets like random passwords: + +```yaml +{{ $manifests := getManifests "redis@my-namespace" }} +{{- range $manifests }} +{{- if eq .kind "Secret" }} +redis_password: {{ index .data "redis-password" }} +{{- end }} +{{- end }} +``` diff --git a/docs/examples/cross-release-reference/helmwave.yml b/docs/examples/cross-release-reference/helmwave.yml new file mode 100644 index 00000000..e1b4aeaf --- /dev/null +++ b/docs/examples/cross-release-reference/helmwave.yml @@ -0,0 +1,30 @@ +project: "Example: cross-release reference" +version: ⟨⟨ ver ⟩⟩ + +repositories: + - name: bitnami + url: https://charts.bitnami.com/bitnami + +.options: &options + namespace: my-namespace + wait: true + +releases: + # redis is built first (no dependencies) + - name: redis + <<: *options + chart: bitnami/redis + store: + port: 6379 + values: + - values/redis.yml + + # backend depends on redis, so it's built after redis + # backend's values can reference redis's built manifests and values + - name: backend + <<: *options + chart: bitnami/nginx + depends_on: + - redis + values: + - values/backend.yml diff --git a/docs/examples/cross-release-reference/values/backend.yml b/docs/examples/cross-release-reference/values/backend.yml new file mode 100644 index 00000000..85e77689 --- /dev/null +++ b/docs/examples/cross-release-reference/values/backend.yml @@ -0,0 +1,29 @@ +# Example: Access redis's rendered values +{{ $redisValues := getValues "redis@my-namespace" "values/redis.yml" }} + +# Example: Access redis's rendered manifests to get helm-generated secrets +{{ $manifests := getManifests "redis@my-namespace" }} + +# Example: Access plan configuration +{{ $plan := getPlan }} + +# Use data from redis release values +redis: + host: {{ $redisValues.connection.host }} + port: {{ $redisValues.connection.port }} + +# Extract redis password from helm-generated secret +{{- range $manifests }} +{{- if eq .kind "Secret" }} +{{- if contains "redis" .metadata.name }} + password: {{ index .data "redis-password" }} +{{- end }} +{{- end }} +{{- end }} + +# Access store from plan +{{- range $plan.releases }} +{{- if eq .name "redis" }} + store_port: {{ .store.port }} +{{- end }} +{{- end }} diff --git a/docs/examples/cross-release-reference/values/redis.yml b/docs/examples/cross-release-reference/values/redis.yml new file mode 100644 index 00000000..d33e816d --- /dev/null +++ b/docs/examples/cross-release-reference/values/redis.yml @@ -0,0 +1,3 @@ +connection: + host: redis-master + port: {{ .Release.store.port }} diff --git a/docs/examples/values-dependencies/README.md b/docs/examples/values-dependencies/README.md index 6f3104ac..8d6eba6f 100644 --- a/docs/examples/values-dependencies/README.md +++ b/docs/examples/values-dependencies/README.md @@ -39,3 +39,15 @@ Rendered values files will look like that: {% include "./rendered/redis/redis.yml" %} ``` +## Cross-release values + +> Introduced in [:material-tag: v0.43.0](https://github.com/helmwave/helmwave/releases/tag/v0.43.0) + +Starting from v0.43.0, `getValues` also supports fetching rendered values from depending releases. +The depending release must be declared in `depends_on`. + +```yaml +{{ $redisValues := getValues "redis@my-namespace" "values/redis.yml" }} +``` + +See [Cross-release reference](../cross-release-reference/README.md) for a complete example. diff --git a/docs/tpl.md b/docs/tpl.md index 152dbb51..ef1e9a22 100644 --- a/docs/tpl.md +++ b/docs/tpl.md @@ -118,14 +118,55 @@ The `hasKey` function allows you to check if key exists in the value. Dot-separa ``` +### `getPlan` + +> Introduced in [:material-tag: v0.43.0](https://github.com/helmwave/helmwave/releases/tag/v0.43.0) + +The `getPlan` function returns the entire plan configuration as a map. This allows values to access any release's `store` field or other configuration. + +```shell +{{ $plan := getPlan }} +{{ $redis := index $plan.releases 0 }} +{{ $redis.store.someKey }} +``` + +[:material-duck: example](examples/cross-release-reference/README.md) + ### `getValues` > Introduced in [:material-tag: v0.36.0](https://github.com/helmwave/helmwave/releases/tag/v0.36.0) +> +> Enhanced in [:material-tag: v0.43.0](https://github.com/helmwave/helmwave/releases/tag/v0.43.0) + +The `getValues` function returns the contents of a values file parsed as YAML. On failure, the template rendering will fail with an error message. -The `getValues` function returns the contents of another values file of the current release parsed as YAML. On failure, the template rendering will fail with an error message. +**Single argument** - get values from another values file of the current release: ```shell {{ $common := getValues "common.yaml" }} ``` +**Two arguments** - get rendered values from a depending release (v0.43.0+). The release must be declared in `depends_on`. + +```shell +{{ $redisValues := getValues "redis@my-namespace" "values.yaml" }} +``` + [:material-duck: example](examples/values-dependencies/README.md) + +### `getManifests` + +> Introduced in [:material-tag: v0.43.0](https://github.com/helmwave/helmwave/releases/tag/v0.43.0) + +The `getManifests` function returns rendered manifests of a depending release as an array of objects. The release must be declared in `depends_on`. + +```shell +{{ $manifests := getManifests "redis@my-namespace" }} +{{- range $manifests }} +{{- if eq .kind "Secret" }} +redis_password: {{ index .data "redis-password" }} +{{- end }} +{{- end }} +``` + +[:material-duck: example](examples/cross-release-reference/README.md) diff --git a/mkdocs.yml b/mkdocs.yml index a7af5e8f..bf1a6b77 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -35,6 +35,7 @@ nav: - Templating: - examples/apps-per-ns/README.md - examples/single-app-multi-envs/README.md + - examples/cross-release-reference/README.md - examples/pass-git-commit/README.md - examples/pass-git-tag/README.md - examples/built-in-release/README.md