@zuke/helm
`@zuke/helm` — typed `HelmTasks` wrappers for the [Helm](https://helm.sh) CLI,
@zuke/helm on JSR ↗ 19 symbols
Symbols
function helmCanary(configure: Configure<HelmCanarySettings>): HelmCanary Two Helm releases of one chart as a canary platform, for @zuke/canary:
c.platform(helmCanary((h) =>
h.chart("./charts/api").stableRelease("api").namespace("prod")
.image(this.tag.value).replicas(10).values("values-prod.yaml")
.helm((s) => s.kubeContext("prod"))
))
The lambda runs on every call, so it may read resolved parameters; the image, replica count, charts, versions, values files and keys are fixed by stage. Every upgrade passes --reset-then-reuse-values, and every command on the stable release --history-max 0.
- stage — reads the stable release's revision, status and first-deployed time, checks no canary release exists, then upgrade <stable>-canary <chart> --set replicaCount=0 --set-string image.tag=<image> --install --wait. - expose — upgrade --set replicaCount=<n> on the canary release (waiting), then on the stable release with the remainder. - promote — upgrade <stable> --set replicaCount=<total> --set-string image.tag=<image> --wait, then uninstall <canary> --ignore-not-found. - abort — rollback <stable> <recorded revision> --wait, then the same uninstall; run by hand, the revision set with .stableRevision(...). A rollback with nothing recorded runs nothing: nothing was staged.
Every call after stage that has its record first reads the stable release's first-deployed time again and refuses, changing nothing, unless it is the one stage recorded — so a release reinstalled under the same name, or another cluster's reached through a changed kube context, is never upgraded or rolled back.
class HelmCanary Two Helm releases of one chart as a canary platform. Create one with helmCanary; hand it to @zuke/canary's c.platform(...).
Exposure is the canary release's share of the replicas, so it is quantised.
| Member | Signature | Doc |
|---|---|---|
describe | describe(): string | "Helm release api in prod", for the build summary. |
stage | stage(ctx: HelmCanaryContext): Promise<void> | Check the stable release is deployed and record its revision and first-deployed time, check no canary release is left over, then install the candidate as the canary release with no replicas: upgrade <canary> <chart> --set <replicasKey>=0 --set-string <imageKey>=<image> --install --wait. The image, replica count, charts, versions, values files and keys are recorded, and every later call uses those, not a configuration that may have changed since. A stage resumed after an earlier attempt recorded the stable release refuses, before writing anything, unless the release it reads now was first deployed at the recorded time. |
expose | expose(percent: number, ctx: HelmCanaryContext): Promise<number> | Give the canary release percent of the staged replica count — rounded, and at least one for any share above 0 — scaling it up (waiting) before the stable release down (not waiting). Returns the share achieved. Refuses, changing nothing, unless the stable release was first deployed at the time stage recorded. |
promote | promote(ctx: HelmCanaryContext): Promise<void> | Upgrade the stable release to the staged chart and image at the staged replica count, waiting for it, then uninstall the canary release. Idempotent. Refuses, changing nothing, unless the stable release was first deployed at the time stage recorded. |
abort | abort(ctx: HelmCanaryContext): Promise<void> | Return the stable release to where it was and remove the canary release. Idempotent. What it does depends on what this rollout recorded: - Staged (a rollback mid-rollout, or after a promotion that failed): helm rollback <stable> <revision> --wait to the revision stage recorded, then helm uninstall <canary> --ignore-not-found. - The canary install was under way: the stable release was never touched, so only the canary release is uninstalled. - Stage failed before the canary install: nothing changed; nothing runs. - Nothing recorded, on a rollback (ctx.reason is "rollback"): nothing was staged, so nothing runs — neither a rollback nor an uninstall, and the stable revision is not even read. - Nothing recorded, run by hand (rollout.abort on its own, a fresh run, or an engine that names no reason): the rollback goes to HelmCanarySettings.stableRevision. Without one this refuses, since claiming a rollback it cannot do would be worse. - A record it does not recognise: refuses. Staged, or with the install under way, it first reads when the stable release was first deployed and refuses, changing nothing, unless that is the time stage recorded — a release reinstalled under the same name, or another cluster's through a changed kube context, is not this rollout's to roll back. A hand-run abort has no recorded time to compare with. |
exposure | exposure: replicas | Exposure is a share of replicas, quantised to whole pods. |
interface HelmCanaryContext The part of the canary engine's context the Helm platform uses: the rollout's durable state, where the stable release's revision and the staged candidate are recorded, and the build summary. The engine hands a richer context; this is the narrow view.
| Member | Signature | Doc |
|---|---|---|
reportSummary | reportSummary(pairs: SummaryPairs): void | Add key/value pairs to the calling target's row in the build summary. |
state | state: TargetStateHandle | The rollout's durable platform state, shared by every call. |
reason? | reason?: rollback | hand-run | Why abort runs: "rollback" when the engine undoes a rollout, "hand-run" for rollout.abort run on its own. An engine older than this field leaves it out, which is treated as a hand run — the behaviour from before the field existed. |
class HelmCanarySettings How helmCanary reaches the releases, configured through its lambda.
| Member | Signature | Doc |
|---|---|---|
chart | chart(ref: string): this | The chart the candidate is rendered from — a path, repo/name or an oci:// reference. The canary release and the promotion use it; the stable release's replica moves use it too unless stableChart names the chart the stable release runs. Pin a repository chart with version: a chart that is not a local path (one starting with . or /, or a Windows drive path) is refused without one. A local chart is recorded by its path, not its content, so leave it unchanged until the rollout finishes. |
version | version(value: string): this | The candidate chart's version (--version). |
stableChart | stableChart(ref: string): this | The chart the stable release runs today, for the replica moves on it while the canary runs. Without it they render chart, so a candidate that changes the chart changes every stable pod's templates at the first step. A chart that is not a local path (one starting with . or /, or a Windows drive path) must be pinned with stableVersion, or each move would render whatever the repository serves as latest. |
stableVersion | stableVersion(value: string): this | The stable chart's version (--version on the stable release's replica moves). Defaults to version when stableChart is not set, and is required when it names a repository or oci:// chart. |
stableRelease | stableRelease(name: string): this | The release serving today. It must already exist; the canary amends it. |
canaryRelease | canaryRelease(name: string): this | The release the candidate runs as (default <stable>-canary). |
namespace | namespace(name: string): this | The namespace both releases live in (--namespace). |
image | image(value: string): this | The candidate's image, as the chart reads it at imageKey. With the default key, image.tag, that is the tag alone (1.4.2, or 1.4.2@sha256:…), as the chart helm create scaffolds expects; point imageKey at a key that takes a full reference to pass one. Set with --set-string, so a tag like 1.10 is not turned into a number. |
imageKey | imageKey(path: string): this | The values path the image is set on (default image.tag). |
replicasKey | replicasKey(path: string): this | The values path the replica count is set on (default replicaCount, as helm create scaffolds). The chart must honour it — an enabled autoscaler that ignores it makes the exposure meaningless. |
replicas | replicas(total: number): this | The total replica count, split between the two releases while the canary runs and given to the stable release by the promotion. |
values | values(...files: PathLike[]): this | Values files (--values) the canary release is installed with, and that the promotion merges into the stable release's values. The canary release inherits nothing from the stable one, so these must carry its whole configuration. |
timeout | timeout(duration: string): this | How long each command that waits may take, e.g. 10m (--timeout). |
stableRevision | stableRevision(revision: number): this | The stable release's revision to roll back to when rollout.abort is run by hand — the one helm history <stable> lists from before the rollout. Such a run is fresh, with no record of a rollout, so it has nothing else to go on. A rollback the engine runs does not use it: mid-rollout it returns to the revision stage recorded, and with nothing recorded it runs nothing, since nothing was staged. |
helm | helm(configure: Configure<HelmSettings>): this | Global flags for every helm command the platform runs — (s) => s.kubeContext("prod").kubeconfig("~/.kube/prod"), or a .toolPath(...) to a specific helm. The kube context and kubeconfig must not change mid-rollout: the rollout records its release names and namespace and refuses a change to those, but cannot record these. A context that now points at another cluster is refused all the same, since that cluster's stable release was not first deployed at the time stage recorded — a strong check, not a proof. |
runner | runner(run: HelmSettingsRunner): this | Replace how each prepared command is run. The default runs it; this is for a test, or for a build that executes helm through something else. |
chart_? | chart_?: string | The chart the candidate is rendered from (set by chart). |
version_? | version_?: string | The candidate chart's version (set by version). |
stableChart_? | stableChart_?: string | The chart the stable release runs (set by stableChart). |
stableVersion_? | stableVersion_?: string | The stable chart's version (set by stableVersion). |
stableRelease_? | stableRelease_?: string | The release serving today (set by stableRelease). |
canaryRelease_? | canaryRelease_?: string | The release the candidate runs as (set by canaryRelease). |
namespace_? | namespace_?: string | The namespace both releases live in (set by namespace). |
image_? | image_?: string | The candidate's image value (set by image). |
imageKey_ | imageKey_: string | The values path the image is set on (set by imageKey). |
replicasKey_ | replicasKey_: string | The values path the replica count is set on (set by replicasKey). |
replicas_? | replicas_?: number | The total replica count across both releases (set by replicas). |
values_ | values_: string[] | Values files for the canary release and the promotion (set by values). |
timeout_? | timeout_?: string | How long each waiting command may take (set by timeout). |
stableRevision_? | stableRevision_?: number | The revision a hand-run rollback returns to (set by stableRevision). |
helm_? | helm_?: Configure<HelmSettings> | Global helm flags for every command (set by helm). |
runner_ | runner_: HelmSettingsRunner | How each command is run (set by runner). |
class HelmDependencyUpdateSettings extends HelmSettings Settings for helm dependency update.
| Member | Signature | Doc |
|---|---|---|
chart | chart(path: PathLike): this | The chart path whose dependencies to update (required). |
class HelmGetAllSettings extends HelmSettings Settings for helm get all (everything recorded about a release).
| Member | Signature | Doc |
|---|---|---|
release | release(name: string): this | The release to read (required). |
revision | revision(number: number): this | Read a specific revision instead of the latest (--revision). A whole number from 1 up. |
template | template(value: string): this | Format the output with a Go template over .Release (--template) — e.g. {{.Release.Version}} prints just the current revision. |
class HelmInstallSettings extends HelmValuesSettings Settings for helm install.
| Member | Signature | Doc |
|---|---|---|
release | release(name: string): this | The release name (required). |
chart | chart(ref: string): this | The chart reference or path (required). |
createNamespace | createNamespace(): this | Create the release namespace if absent (--create-namespace). |
wait | wait(): this | Wait until resources are ready (--wait). |
atomic | atomic(): this | Roll back on failure (--atomic). |
timeout | timeout(duration: string): this | Operation timeout, e.g. 5m (--timeout). |
dryRun | dryRun(): this | Simulate the install (--dry-run). |
class HelmLintSettings extends HelmSettings Settings for helm lint.
| Member | Signature | Doc |
|---|---|---|
chart | chart(path: PathLike): this | The chart path to lint (required). |
values | values(path: PathLike): this | Add a values file (--values); repeatable. |
strict | strict(): this | Treat warnings as errors (--strict). |
class HelmPackageSettings extends HelmSettings Settings for helm package.
| Member | Signature | Doc |
|---|---|---|
chart | chart(path: PathLike): this | The chart path to package (required). |
destination | destination(path: PathLike): this | Output directory for the packaged chart (--destination). |
version | version(value: string): this | Set the chart version (--version). |
appVersion | appVersion(value: string): this | Set the chart appVersion (--app-version). |
class HelmRepoAddSettings extends HelmSettings Settings for helm repo add.
| Member | Signature | Doc |
|---|---|---|
name | name(value: string): this | The repository name (required). |
url | url(value: string): this | The repository URL (required). |
class HelmRollbackSettings extends HelmSettings Settings for helm rollback.
| Member | Signature | Doc |
|---|---|---|
release | release(name: string): this | The release to roll back (required). |
revision | revision(number: number): this | The revision to roll back to. Without one, helm rolls back to the previous revision. A whole number from 1 up. |
wait | wait(): this | Wait until resources are ready (--wait). |
timeout | timeout(duration: string): this | Operation timeout, e.g. 5m (--timeout). |
historyMax | historyMax(count: number): this | Keep at most count revisions of the release; 0 keeps them all (--history-max). A whole number from 0 up. |
class HelmSettings extends ToolSettings Base for all helm subcommand settings: the binary is helm, and the cluster-targeting flags (--namespace, --kube-context, --kubeconfig) are shared by every subcommand.
| Member | Signature | Doc |
|---|---|---|
namespace | namespace(name: string): this | Target a namespace (--namespace). |
kubeContext | kubeContext(name: string): this | Use a named kube context (--kube-context). |
kubeconfig | kubeconfig(path: PathLike): this | Use an explicit kubeconfig file (--kubeconfig). |
type HelmSettingsRunner = unknown Runs one prepared helm command and returns its output. The default runs it; a test or a build that executes helm some other way injects its own with HelmCanarySettings.runner.
const HelmTasks: HelmTasksApi Typed task functions for the helm CLI.
interface HelmTasksApi The shape of HelmTasks.
| Member | Signature | Doc |
|---|---|---|
install | install(configure?: Configure<HelmInstallSettings>): Promise<CommandOutput> | Install a chart: helm install. |
upgrade | upgrade(configure?: Configure<HelmUpgradeSettings>): Promise<CommandOutput> | Upgrade (or install) a release: helm upgrade. |
uninstall | uninstall(configure?: Configure<HelmUninstallSettings>): Promise<CommandOutput> | Uninstall a release: helm uninstall. |
rollback | rollback(configure?: Configure<HelmRollbackSettings>): Promise<CommandOutput> | Roll a release back to an earlier revision: helm rollback. |
getAll | getAll(configure?: Configure<HelmGetAllSettings>): Promise<CommandOutput> | Read everything recorded about a release: helm get all. |
template | template(configure?: Configure<HelmTemplateSettings>): Promise<CommandOutput> | Render manifests locally: helm template. |
lint | lint(configure?: Configure<HelmLintSettings>): Promise<CommandOutput> | Lint a chart: helm lint. |
dependencyUpdate | dependencyUpdate(configure?: Configure<HelmDependencyUpdateSettings>): Promise<CommandOutput> | Update chart dependencies: helm dependency update. |
repoAdd | repoAdd(configure?: Configure<HelmRepoAddSettings>): Promise<CommandOutput> | Add a chart repository: helm repo add. |
package | package(configure?: Configure<HelmPackageSettings>): Promise<CommandOutput> | Package a chart: helm package. |
class HelmTemplateSettings extends HelmValuesSettings Settings for helm template (render manifests locally).
| Member | Signature | Doc |
|---|---|---|
release | release(name: string): this | The release name (required). |
chart | chart(ref: string): this | The chart reference or path (required). |
outputDir | outputDir(path: PathLike): this | Write rendered manifests to a directory (--output-dir). |
class HelmUninstallSettings extends HelmSettings Settings for helm uninstall.
| Member | Signature | Doc |
|---|---|---|
release | release(name: string): this | The release name to uninstall (required). |
keepHistory | keepHistory(): this | Retain release history (--keep-history). |
ignoreNotFound | ignoreNotFound(): this | Treat "release not found" as a successful uninstall (--ignore-not-found, Helm 3.13 and later). |
wait | wait(): this | Wait until removal completes (--wait). |
class HelmUpgradeSettings extends HelmValuesSettings Settings for helm upgrade.
| Member | Signature | Doc |
|---|---|---|
release | release(name: string): this | The release name (required). |
chart | chart(ref: string): this | The chart reference or path (required). |
install | install(): this | Install the release if it does not exist (--install). |
reuseValues | reuseValues(): this | Reuse the last release's values and merge the command line's --set and --values over them (--reuse-values). |
resetThenReuseValues | resetThenReuseValues(): this | Reset to the new chart's default values, apply the last release's values over them, then the command line's (--reset-then-reuse-values, Helm 3.14 and later). Unlike reuseValues, a default the new chart changed is picked up. |
historyMax | historyMax(count: number): this | Keep at most count revisions of the release; 0 keeps them all (--history-max). A whole number from 0 up. |
createNamespace | createNamespace(): this | Create the release namespace if absent (--create-namespace). |
wait | wait(): this | Wait until resources are ready (--wait). |
atomic | atomic(): this | Roll back on failure (--atomic). |
timeout | timeout(duration: string): this | Operation timeout, e.g. 5m (--timeout). |
class HelmValuesSettings extends HelmSettings Base for value-bearing commands (install/upgrade/template).
| Member | Signature | Doc |
|---|---|---|
values | values(path: PathLike): this | Add a values file (--values/-f); repeatable. |
set | set(name: string, value: string): this | Override a single value (--set name=value); repeatable. |
setString | setString(name: string, value: string): this | Override a single value as a string (--set-string name=value); repeatable. Unlike --set, helm does not infer a type, so a tag such as 1.10 or 2024 stays a string. |
version | version(value: string): this | Pin the chart version (--version). |