@intentius/chant-lexicon-helm 0.0.22 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/integrity.json +7 -5
  2. package/dist/manifest.json +1 -1
  3. package/dist/rules/values-no-helm-tpl.ts +92 -0
  4. package/dist/rules/whm005-no-empty-wrapper.ts +54 -0
  5. package/dist/skills/{chant-helm-chart-patterns.md → chant-helm-patterns.md} +52 -0
  6. package/dist/skills/chant-helm.md +496 -0
  7. package/package.json +6 -3
  8. package/src/codegen/docs.ts +3 -2
  9. package/src/composites/composites.test.ts +116 -110
  10. package/src/composites/helm-batch-job.ts +33 -19
  11. package/src/composites/helm-crd-lifecycle.ts +37 -24
  12. package/src/composites/helm-cron-job.ts +25 -13
  13. package/src/composites/helm-daemon-set.ts +26 -14
  14. package/src/composites/helm-external-secret.ts +21 -12
  15. package/src/composites/helm-library.ts +21 -7
  16. package/src/composites/helm-microservice.ts +46 -29
  17. package/src/composites/helm-monitored-service.ts +75 -51
  18. package/src/composites/helm-namespace-env.ts +80 -52
  19. package/src/composites/helm-secure-ingress.ts +66 -50
  20. package/src/composites/helm-stateful-service.ts +29 -16
  21. package/src/composites/helm-web-app.ts +37 -22
  22. package/src/composites/helm-worker.ts +34 -20
  23. package/src/index.ts +4 -1
  24. package/src/intrinsics.ts +53 -0
  25. package/src/lint/post-synth/post-synth.test.ts +43 -0
  26. package/src/lint/post-synth/whm005-no-empty-wrapper.ts +54 -0
  27. package/src/lint/rules/lint-rules.test.ts +35 -0
  28. package/src/lint/rules/values-no-helm-tpl.ts +92 -0
  29. package/src/plugin.test.ts +7 -5
  30. package/src/plugin.ts +8 -42
  31. package/src/resources.ts +49 -0
  32. package/src/serializer.test.ts +113 -2
  33. package/src/serializer.ts +149 -13
  34. package/src/skills/{chart-patterns.md → chant-helm-patterns.md} +52 -0
  35. package/src/skills/chant-helm.md +496 -0
  36. package/dist/skills/chant-helm-create-chart.md +0 -211
  37. package/src/skills/create-chart.md +0 -211
  38. /package/dist/skills/{chant-helm-chart-security-patterns.md → chant-helm-security.md} +0 -0
  39. /package/src/skills/{chart-security-patterns.md → chant-helm-security.md} +0 -0
@@ -0,0 +1,496 @@
1
+ ---
2
+ skill: chant-helm
3
+ description: Build, validate, and deploy Helm charts from a chant project
4
+ user-invocable: true
5
+ ---
6
+
7
+ # Helm Chart Operational Playbook
8
+
9
+ ## How chant and Helm relate
10
+
11
+ chant is a **synthesis compiler** — it compiles TypeScript source files into a complete Helm chart directory (Chart.yaml, values.yaml, templates/, etc.). `chant build` does not call the Helm CLI; synthesis is pure and deterministic. Your job as an agent is to bridge synthesis and deployment:
12
+
13
+ - Use **chant** for: build, lint, diff (local chart comparison)
14
+ - Use **helm** for: install, upgrade, rollback, test, dependency update
15
+
16
+ The source of truth is the TypeScript in `src/`. The generated chart directory is an intermediate artifact — never edit it by hand.
17
+
18
+ ## Scaffolding a new project
19
+
20
+ ### Initialize with a template
21
+
22
+ ```bash
23
+ chant init --lexicon helm # default: Deployment + Service chart
24
+ ```
25
+
26
+ ### Project structure after init
27
+
28
+ ```
29
+ my-chart/
30
+ src/
31
+ chart.ts ← Chart metadata, Values, K8s resources with Helm intrinsics
32
+ chant.json ← project configuration
33
+ package.json
34
+ ```
35
+
36
+ ## Key concepts
37
+
38
+ ### Values proxy
39
+
40
+ The `values` proxy creates `{{ .Values.x }}` template directives:
41
+
42
+ ```typescript
43
+ import { values } from "@intentius/chant-lexicon-helm";
44
+
45
+ // values.replicaCount → {{ .Values.replicaCount }}
46
+ // values.image.repository → {{ .Values.image.repository }}
47
+ ```
48
+
49
+ ### Template functions
50
+
51
+ ```typescript
52
+ import { include, printf, toYaml, quote, required, helmDefault } from "@intentius/chant-lexicon-helm";
53
+
54
+ include("my-app.fullname") // {{ include "my-app.fullname" . }}
55
+ printf("%s:%s", values.image.repo, values.image.tag) // {{ printf "%s:%s" ... }}
56
+ toYaml(values.resources, 12) // {{ toYaml .Values.resources | nindent 12 }}
57
+ ```
58
+
59
+ ### Conditional resources
60
+
61
+ ```typescript
62
+ import { If, values } from "@intentius/chant-lexicon-helm";
63
+
64
+ // Wrap an entire resource in {{- if .Values.ingress.enabled }}
65
+ export const ingress = If(values.ingress.enabled, new Ingress({ ... }));
66
+ ```
67
+
68
+ ### Runtime values and value overrides
69
+
70
+ Use `runtimeSlot()` for deploy-time values that cannot be known at build time (database IPs, bucket names, etc.):
71
+
72
+ ```typescript
73
+ import { Values, runtimeSlot } from "@intentius/chant-lexicon-helm";
74
+
75
+ export const vals = new Values({
76
+ global: {
77
+ psql: {
78
+ host: runtimeSlot("Cloud SQL private IP"), // → '' in values.yaml
79
+ },
80
+ redis: {
81
+ host: runtimeSlot("Memorystore persistent host"),
82
+ },
83
+ },
84
+ });
85
+ ```
86
+
87
+ `runtimeSlot()` generates two outputs:
88
+ - `values.yaml` — the field emits `''` (empty placeholder, safe for `helm template`)
89
+ - `values-runtime-slots.yaml` — lists only the slots with descriptions as YAML comments, for use as a deploy-time checklist
90
+
91
+ **WHM004** fires when `v.xxx` (the values proxy) is used inside `new Values({...})` — values.yaml is not a Go template, so `{{ .Values.x }}` would silently become `''`. Use `runtimeSlot()` instead.
92
+
93
+ Use `ValuesOverride` for static configuration shared across all deployments, like disabling bundled services:
94
+
95
+ ```typescript
96
+ import { ValuesOverride } from "@intentius/chant-lexicon-helm";
97
+
98
+ export const baseOverride = new ValuesOverride({
99
+ filename: "values-base", // → generates chart-dir/values-base.yaml
100
+ values: {
101
+ postgresql: { install: false },
102
+ redis: { install: false },
103
+ certmanager: { install: false },
104
+ },
105
+ });
106
+ ```
107
+
108
+ Pass the generated file at deploy time:
109
+ ```bash
110
+ helm upgrade --install my-release chart/
111
+ -f chart/values-base.yaml # generated by ValuesOverride
112
+ -f values-prod.yaml # runtime overrides (from values-runtime-slots.yaml)
113
+ ```
114
+
115
+ ### Built-in objects
116
+
117
+ ```typescript
118
+ import { Release, ChartRef } from "@intentius/chant-lexicon-helm";
119
+
120
+ Release.Name // {{ .Release.Name }}
121
+ Release.Namespace // {{ .Release.Namespace }}
122
+ ChartRef.Version // {{ .Chart.Version }}
123
+ ```
124
+
125
+ ## Build and validate workflow
126
+
127
+ ### Build the chart
128
+
129
+ ```bash
130
+ chant build # synthesize TypeScript → dist/
131
+ chant build --watch # rebuild on source changes
132
+ chant build --output my-chart/ # write to a custom directory
133
+ ```
134
+
135
+ `chant build` produces a complete Helm chart directory:
136
+ - `dist/Chart.yaml` — chart metadata (name, version, apiVersion v2)
137
+ - `dist/values.yaml` — default values extracted from `values` proxy usage
138
+ - `dist/templates/*.yaml` — rendered K8s manifests with Go template directives
139
+ - `dist/templates/_helpers.tpl` — named templates (fullname, labels, etc.)
140
+ - `dist/templates/NOTES.txt` — post-install instructions
141
+
142
+ ### Lint and validate
143
+
144
+ ```bash
145
+ # Lint the TypeScript (pre-synth rules)
146
+ chant lint
147
+
148
+ # Validate the generated chart (post-synth checks)
149
+ chant check
150
+
151
+ # Validate with helm CLI
152
+ helm lint dist/
153
+ helm template test dist/
154
+ ```
155
+
156
+ ### What each step catches
157
+
158
+ | Step | Catches | When to run |
159
+ |------|---------|-------------|
160
+ | `chant lint` | Pre-synth: missing chart metadata, bare secrets in values, hardcoded images | Every edit |
161
+ | `chant check` | Post-synth: unbalanced template braces, missing _helpers.tpl, deprecated APIs, security issues | After build |
162
+ | `helm lint dist/` | Chart structure validation, values schema, template rendering errors | Before publish |
163
+ | `helm template test dist/` | Full template rendering with default values — catches nil pointer panics in Go templates | Before publish |
164
+ | `helm template test dist/ -f values-prod.yaml` | Template rendering with environment-specific overrides | Before deploy |
165
+
166
+ ## Common patterns
167
+
168
+ ### Deployment with parameterized image
169
+
170
+ ```typescript
171
+ export const deployment = new Deployment({
172
+ metadata: {
173
+ name: include("my-app.fullname"),
174
+ labels: include("my-app.labels"),
175
+ },
176
+ spec: {
177
+ replicas: values.replicaCount,
178
+ template: {
179
+ spec: {
180
+ containers: [{
181
+ name: "my-app",
182
+ image: printf("%s:%s", values.image.repository, values.image.tag),
183
+ resources: toYaml(values.resources),
184
+ }],
185
+ },
186
+ },
187
+ },
188
+ });
189
+ ```
190
+
191
+ ### Composites for common patterns
192
+
193
+ ```typescript
194
+ import { HelmWebApp, HelmMicroservice, HelmDaemonSet, HelmWorker } from "@intentius/chant-lexicon-helm";
195
+
196
+ // Quick scaffold: Deployment + Service + Ingress + HPA + ServiceAccount
197
+ const result = HelmWebApp({ name: "my-app", port: 3000, replicas: 3 });
198
+
199
+ // Full microservice: + PDB + ConfigMap + health probes + resource limits
200
+ const msvc = HelmMicroservice({ name: "api", port: 8080 });
201
+
202
+ // DaemonSet for node-level agents (logging, monitoring)
203
+ const agent = HelmDaemonSet({ name: "log-agent", imageRepository: "fluent/fluent-bit" });
204
+
205
+ // Worker for background processors (no Service, exec probes, queue config)
206
+ const worker = HelmWorker({ name: "job-processor", replicas: 4 });
207
+ ```
208
+
209
+ ### Composites reference
210
+
211
+ | Need | Composite | Resources |
212
+ |------|-----------|-----------|
213
+ | Stateless web app | **HelmWebApp** | Deployment + Service + optional Ingress + HPA + ServiceAccount |
214
+ | Production microservice | **HelmMicroservice** | Deployment + Service + HPA + PDB + ConfigMap + probes + limits |
215
+ | Stateful database/cache | **HelmStatefulService** | StatefulSet + headless Service + PVC + optional PDB |
216
+ | Background workers | **HelmWorker** | Deployment + optional HPA (no Service, exec probes) |
217
+ | Node-level agent | **HelmDaemonSet** | DaemonSet + ServiceAccount + RBAC |
218
+ | Scheduled jobs | **HelmCronJob** | CronJob + ServiceAccount + RBAC |
219
+ | One-shot batch jobs | **HelmBatchJob** | Job + ServiceAccount + optional RBAC |
220
+ | App with Prometheus monitoring | **HelmMonitoredService** | Deployment + Service + ServiceMonitor + optional PrometheusRule |
221
+ | TLS Ingress (cert-manager) | **HelmSecureIngress** | Ingress + optional Certificate |
222
+ | External secrets (Vault, AWS SM) | **HelmExternalSecret** | ExternalSecret + SecretStore ref |
223
+ | CRD lifecycle hooks | **HelmCRDLifecycle** | pre-install/upgrade Job for CRD apply |
224
+ | Library chart (no templates) | **HelmLibrary** | Chart.yaml with `type: library` + _helpers.tpl |
225
+ | Namespace with quotas | **HelmNamespaceEnv** | Namespace + ResourceQuota + LimitRange + NetworkPolicy |
226
+
227
+ ### Secret management with ExternalSecret
228
+
229
+ ```typescript
230
+ import { HelmExternalSecret } from "@intentius/chant-lexicon-helm";
231
+
232
+ const secrets = HelmExternalSecret({
233
+ name: "app-secrets",
234
+ secretStoreName: "vault",
235
+ data: {
236
+ DB_PASSWORD: "secret/data/db-password",
237
+ API_KEY: "secret/data/api-key",
238
+ },
239
+ });
240
+ ```
241
+
242
+ ### Resource ordering
243
+
244
+ ```typescript
245
+ import { withOrder, argoWave } from "@intentius/chant-lexicon-helm";
246
+
247
+ // Helm hook ordering (lower weight = runs first)
248
+ metadata: { annotations: { ...withOrder(-5) } }
249
+
250
+ // Argo CD sync waves
251
+ metadata: { annotations: { ...argoWave(2) } }
252
+ ```
253
+
254
+ ### CRD lifecycle management
255
+
256
+ ```typescript
257
+ import { HelmCRDLifecycle } from "@intentius/chant-lexicon-helm";
258
+
259
+ // Managed CRD lifecycle via Helm hooks (solves Helm's CRD limitation)
260
+ const lifecycle = HelmCRDLifecycle({
261
+ name: "my-operator",
262
+ crdContent: crdYaml,
263
+ });
264
+ ```
265
+
266
+ ## Lint rules
267
+
268
+ | Rule | Phase | Description |
269
+ |------|-------|-------------|
270
+ | WHM001 | pre-synth | Chart must have name, version, apiVersion |
271
+ | WHM002 | pre-synth | Values should not contain bare secrets |
272
+ | WHM003 | pre-synth | Container images should use values references |
273
+ | WHM004 | pre-synth | HelmTpl (`v.xxx`) has no effect in Values — use `runtimeSlot()` |
274
+ | WHM005 | post-synth | Chart with dependencies but no templates — deploy upstream chart directly |
275
+ | WHM101 | post-synth | Chart.yaml has valid apiVersion (v2) |
276
+ | WHM102 | post-synth | values.schema.json present when Values used |
277
+ | WHM103 | post-synth | Go template syntax valid (balanced braces) |
278
+ | WHM104 | post-synth | NOTES.txt exists for application charts |
279
+ | WHM105 | post-synth | _helpers.tpl exists |
280
+ | WHM201 | post-synth | Resources have standard Helm labels |
281
+ | WHM301 | post-synth | At least one test for application charts |
282
+ | WHM302 | post-synth | Resource limits set |
283
+ | WHM401 | post-synth | Image uses :latest tag or no tag |
284
+ | WHM402 | post-synth | runAsNonRoot not set |
285
+ | WHM403 | post-synth | readOnlyRootFilesystem not set |
286
+ | WHM404 | post-synth | privileged: true detected |
287
+ | WHM405 | post-synth | Resource spec missing cpu/memory |
288
+ | WHM406 | post-synth | CRD lifecycle limitation |
289
+ | WHM407 | post-synth | Secret with inline data |
290
+ | WHM501 | post-synth | Unused values keys |
291
+ | WHM502 | post-synth | Deprecated K8s API versions |
292
+
293
+ ## OCI registry workflow
294
+
295
+ Helm 3.8+ supports OCI registries as first-class chart repositories.
296
+
297
+ ```bash
298
+ # Login to an OCI registry
299
+ helm registry login ghcr.io -u <user>
300
+ helm registry login <account>.dkr.ecr.<region>.amazonaws.com --username AWS --password $(aws ecr get-login-password)
301
+
302
+ # Package the chart
303
+ helm package dist/
304
+
305
+ # Push to OCI registry
306
+ helm push my-app-1.0.0.tgz oci://ghcr.io/my-org/charts
307
+ helm push my-app-1.0.0.tgz oci://<account>.dkr.ecr.<region>.amazonaws.com/charts
308
+
309
+ # Pull from OCI registry
310
+ helm pull oci://ghcr.io/my-org/charts/my-app --version 1.0.0
311
+
312
+ # Install directly from OCI
313
+ helm install my-app oci://ghcr.io/my-org/charts/my-app --version 1.0.0
314
+ ```
315
+
316
+ ## Chart testing
317
+
318
+ ### helm test
319
+
320
+ Helm tests are pods defined in `templates/tests/` with the `helm.sh/hook: test` annotation. They run after install/upgrade.
321
+
322
+ ```bash
323
+ helm install my-app dist/
324
+ helm test my-app # run test pods
325
+ helm test my-app --logs # show test pod logs
326
+ ```
327
+
328
+ ### chart-testing (ct)
329
+
330
+ The `ct` tool validates charts against a set of rules and optionally installs them in a Kind cluster.
331
+
332
+ ```bash
333
+ # Lint all changed charts
334
+ ct lint --charts dist/
335
+
336
+ # Lint + install (requires a running cluster)
337
+ ct install --charts dist/
338
+
339
+ # CI-oriented: lint and install only changed charts
340
+ ct lint-and-install --chart-dirs dist/
341
+ ```
342
+
343
+ ## Deploy lifecycle
344
+
345
+ ### Install a release
346
+
347
+ ```bash
348
+ # Build the chart first
349
+ chant build
350
+
351
+ # Install with default values
352
+ helm install my-app dist/
353
+
354
+ # Install with overrides
355
+ helm install my-app dist/ -f values-prod.yaml
356
+ helm install my-app dist/ --set replicaCount=3 --set image.tag=v2.0.0
357
+
358
+ # Install in a specific namespace (create if missing)
359
+ helm install my-app dist/ -n production --create-namespace
360
+
361
+ # Dry run (renders templates, validates against cluster)
362
+ helm install my-app dist/ --dry-run
363
+ ```
364
+
365
+ ### Upgrade a release
366
+
367
+ ```bash
368
+ # Upgrade with new chart
369
+ chant build
370
+ helm upgrade my-app dist/
371
+
372
+ # Upgrade with value overrides
373
+ helm upgrade my-app dist/ -f values-prod.yaml --set image.tag=v2.1.0
374
+
375
+ # Atomic upgrade (auto-rollback on failure)
376
+ helm upgrade my-app dist/ --atomic --timeout 5m
377
+
378
+ # Install or upgrade (idempotent)
379
+ helm upgrade --install my-app dist/ -f values-prod.yaml
380
+ ```
381
+
382
+ ### Rollback a release
383
+
384
+ ```bash
385
+ # View release history
386
+ helm history my-app
387
+
388
+ # Rollback to previous revision
389
+ helm rollback my-app
390
+
391
+ # Rollback to a specific revision
392
+ helm rollback my-app 3
393
+
394
+ # Rollback with timeout
395
+ helm rollback my-app 3 --timeout 5m
396
+ ```
397
+
398
+ ### Uninstall
399
+
400
+ ```bash
401
+ helm uninstall my-app
402
+ helm uninstall my-app --keep-history # preserve history for rollback
403
+ ```
404
+
405
+ ## Troubleshooting
406
+
407
+ ### Common errors
408
+
409
+ #### "apiVersion must be v2"
410
+ Helm 3 requires `apiVersion: v2` in Chart.yaml. Update your Chart metadata.
411
+
412
+ #### "unbalanced template braces"
413
+ A Go template expression has mismatched `{{` / `}}`. Check your intrinsic usage.
414
+
415
+ #### "hardcoded image tag"
416
+ Use `printf("%s:%s", values.image.repository, values.image.tag)` instead of literal strings for container images.
417
+
418
+ #### "UPGRADE FAILED: another operation is in progress"
419
+ A previous install/upgrade was interrupted. Fix with:
420
+ ```bash
421
+ helm history my-app
422
+ helm rollback my-app <last-good-revision>
423
+ ```
424
+ If stuck in `pending-install`, uninstall and reinstall:
425
+ ```bash
426
+ helm uninstall my-app
427
+ helm install my-app dist/
428
+ ```
429
+
430
+ #### "rendered manifests contain a resource that already exists"
431
+ Another release or kubectl owns the resource. Add `--force` or use `kubectl annotate` to transfer ownership:
432
+ ```bash
433
+ kubectl annotate <resource> meta.helm.sh/release-name=my-app --overwrite
434
+ kubectl annotate <resource> meta.helm.sh/release-namespace=default --overwrite
435
+ kubectl label <resource> app.kubernetes.io/managed-by=Helm --overwrite
436
+ ```
437
+
438
+ ### Troubleshooting decision tree
439
+
440
+ ```
441
+ helm install/upgrade failed?
442
+ ├─ "INSTALLATION FAILED: cannot re-use a name"
443
+ │ └─ Release name in use → helm uninstall <name> or pick a new name
444
+ ├─ "UPGRADE FAILED: another operation is in progress"
445
+ │ └─ Stuck release → helm rollback to last good revision
446
+ ├─ "rendered manifests contain a resource that already exists"
447
+ │ └─ Ownership conflict → annotate existing resources with Helm metadata
448
+ ├─ Template rendering error
449
+ │ ├─ "nil pointer evaluating interface"
450
+ │ │ └─ Missing values → add defaults in values.yaml or guard with {{- if }}
451
+ │ ├─ "function X not defined"
452
+ │ │ └─ Missing _helpers.tpl → ensure include() references defined templates
453
+ │ └─ "wrong type for value"
454
+ │ └─ Type mismatch → check values.yaml types match template expectations
455
+ ├─ Pods not starting after deploy
456
+ │ └─ See kubectl debugging: kubectl get pods, describe, logs --previous
457
+ └─ Helm test failing
458
+ ├─ Test pod CrashLoopBackOff → check test script, endpoint connectivity
459
+ └─ Timeout → increase --timeout or fix service readiness
460
+ ```
461
+
462
+ ## Quick reference
463
+
464
+ ```bash
465
+ # Build
466
+ chant build # synthesize chart
467
+ chant lint # pre-synth lint
468
+ chant check # post-synth checks
469
+
470
+ # Validate
471
+ helm lint dist/ # chart structure
472
+ helm template test dist/ # render templates
473
+ helm template test dist/ -f values-prod.yaml # render with overrides
474
+
475
+ # Deploy
476
+ helm install my-app dist/ # install
477
+ helm upgrade my-app dist/ # upgrade
478
+ helm upgrade --install my-app dist/ # idempotent install/upgrade
479
+ helm rollback my-app # rollback to previous
480
+
481
+ # Inspect
482
+ helm list # list releases
483
+ helm history my-app # release history
484
+ helm get values my-app # current values
485
+ helm get manifest my-app # current manifests
486
+
487
+ # Test
488
+ helm test my-app --logs # run chart tests
489
+
490
+ # Package and publish
491
+ helm package dist/ # create .tgz
492
+ helm push my-app-1.0.0.tgz oci://registry/charts # push to OCI
493
+
494
+ # Cleanup
495
+ helm uninstall my-app # remove release
496
+ ```
@@ -1,211 +0,0 @@
1
- ---
2
- skill: chant-helm
3
- description: Build, validate, and deploy Helm charts from a chant project
4
- user-invocable: true
5
- ---
6
-
7
- # Helm Chart Operational Playbook
8
-
9
- ## How chant and Helm relate
10
-
11
- chant is a **synthesis compiler** — it compiles TypeScript source files into a complete Helm chart directory (Chart.yaml, values.yaml, templates/, etc.). `chant build` does not call the Helm CLI; synthesis is pure and deterministic. Your job as an agent is to bridge synthesis and deployment:
12
-
13
- - Use **chant** for: build, lint, diff (local chart comparison)
14
- - Use **helm** for: install, upgrade, rollback, test, dependency update
15
-
16
- The source of truth is the TypeScript in `src/`. The generated chart directory is an intermediate artifact — never edit it by hand.
17
-
18
- ## Scaffolding a new project
19
-
20
- ### Initialize with a template
21
-
22
- ```bash
23
- chant init --lexicon helm # default: Deployment + Service chart
24
- ```
25
-
26
- ### Project structure after init
27
-
28
- ```
29
- my-chart/
30
- src/
31
- chart.ts ← Chart metadata, Values, K8s resources with Helm intrinsics
32
- chant.json ← project configuration
33
- package.json
34
- ```
35
-
36
- ## Key concepts
37
-
38
- ### Values proxy
39
-
40
- The `values` proxy creates `{{ .Values.x }}` template directives:
41
-
42
- ```typescript
43
- import { values } from "@intentius/chant-lexicon-helm";
44
-
45
- // values.replicaCount → {{ .Values.replicaCount }}
46
- // values.image.repository → {{ .Values.image.repository }}
47
- ```
48
-
49
- ### Template functions
50
-
51
- ```typescript
52
- import { include, printf, toYaml, quote, required, helmDefault } from "@intentius/chant-lexicon-helm";
53
-
54
- include("my-app.fullname") // {{ include "my-app.fullname" . }}
55
- printf("%s:%s", values.image.repo, values.image.tag) // {{ printf "%s:%s" ... }}
56
- toYaml(values.resources, 12) // {{ toYaml .Values.resources | nindent 12 }}
57
- ```
58
-
59
- ### Conditional resources
60
-
61
- ```typescript
62
- import { If, values } from "@intentius/chant-lexicon-helm";
63
-
64
- // Wrap an entire resource in {{- if .Values.ingress.enabled }}
65
- export const ingress = If(values.ingress.enabled, new Ingress({ ... }));
66
- ```
67
-
68
- ### Built-in objects
69
-
70
- ```typescript
71
- import { Release, ChartRef } from "@intentius/chant-lexicon-helm";
72
-
73
- Release.Name // {{ .Release.Name }}
74
- Release.Namespace // {{ .Release.Namespace }}
75
- ChartRef.Version // {{ .Chart.Version }}
76
- ```
77
-
78
- ## Build and validate workflow
79
-
80
- ```bash
81
- # Build the chart
82
- chant build
83
-
84
- # Lint the TypeScript (pre-synth rules)
85
- chant lint
86
-
87
- # Validate the generated chart (post-synth checks)
88
- chant check
89
-
90
- # Validate with helm CLI
91
- helm lint dist/
92
- helm template test dist/
93
- ```
94
-
95
- ## Common patterns
96
-
97
- ### Deployment with parameterized image
98
-
99
- ```typescript
100
- export const deployment = new Deployment({
101
- metadata: {
102
- name: include("my-app.fullname"),
103
- labels: include("my-app.labels"),
104
- },
105
- spec: {
106
- replicas: values.replicaCount,
107
- template: {
108
- spec: {
109
- containers: [{
110
- name: "my-app",
111
- image: printf("%s:%s", values.image.repository, values.image.tag),
112
- resources: toYaml(values.resources),
113
- }],
114
- },
115
- },
116
- },
117
- });
118
- ```
119
-
120
- ### Composites for common patterns
121
-
122
- ```typescript
123
- import { HelmWebApp, HelmMicroservice, HelmDaemonSet, HelmWorker } from "@intentius/chant-lexicon-helm";
124
-
125
- // Quick scaffold: Deployment + Service + Ingress + HPA + ServiceAccount
126
- const result = HelmWebApp({ name: "my-app", port: 3000, replicas: 3 });
127
-
128
- // Full microservice: + PDB + ConfigMap + health probes + resource limits
129
- const msvc = HelmMicroservice({ name: "api", port: 8080 });
130
-
131
- // DaemonSet for node-level agents (logging, monitoring)
132
- const agent = HelmDaemonSet({ name: "log-agent", imageRepository: "fluent/fluent-bit" });
133
-
134
- // Worker for background processors (no Service, exec probes, queue config)
135
- const worker = HelmWorker({ name: "job-processor", replicas: 4 });
136
- ```
137
-
138
- ### Secret management with ExternalSecret
139
-
140
- ```typescript
141
- import { HelmExternalSecret } from "@intentius/chant-lexicon-helm";
142
-
143
- const secrets = HelmExternalSecret({
144
- name: "app-secrets",
145
- secretStoreName: "vault",
146
- data: {
147
- DB_PASSWORD: "secret/data/db-password",
148
- API_KEY: "secret/data/api-key",
149
- },
150
- });
151
- ```
152
-
153
- ### Resource ordering
154
-
155
- ```typescript
156
- import { withOrder, argoWave } from "@intentius/chant-lexicon-helm";
157
-
158
- // Helm hook ordering (lower weight = runs first)
159
- metadata: { annotations: { ...withOrder(-5) } }
160
-
161
- // Argo CD sync waves
162
- metadata: { annotations: { ...argoWave(2) } }
163
- ```
164
-
165
- ### CRD lifecycle management
166
-
167
- ```typescript
168
- import { HelmCRDLifecycle } from "@intentius/chant-lexicon-helm";
169
-
170
- // Managed CRD lifecycle via Helm hooks (solves Helm's CRD limitation)
171
- const lifecycle = HelmCRDLifecycle({
172
- name: "my-operator",
173
- crdContent: crdYaml,
174
- });
175
- ```
176
-
177
- ## Lint rules
178
-
179
- | Rule | Description |
180
- |------|-------------|
181
- | WHM001 | Chart must have name, version, apiVersion |
182
- | WHM002 | Values should not contain bare secrets |
183
- | WHM003 | Container images should use values references |
184
- | WHM101 | Chart.yaml has valid apiVersion (v2) |
185
- | WHM102 | values.schema.json present when Values used |
186
- | WHM103 | Go template syntax valid (balanced braces) |
187
- | WHM104 | NOTES.txt exists for application charts |
188
- | WHM105 | _helpers.tpl exists |
189
- | WHM201 | Resources have standard Helm labels |
190
- | WHM301 | At least one test for application charts |
191
- | WHM302 | Resource limits set |
192
- | WHM401 | Image uses :latest tag or no tag |
193
- | WHM402 | runAsNonRoot not set |
194
- | WHM403 | readOnlyRootFilesystem not set |
195
- | WHM404 | privileged: true detected |
196
- | WHM405 | Resource spec missing cpu/memory |
197
- | WHM406 | CRD lifecycle limitation |
198
- | WHM407 | Secret with inline data |
199
- | WHM501 | Unused values keys |
200
- | WHM502 | Deprecated K8s API versions |
201
-
202
- ## Troubleshooting
203
-
204
- ### "apiVersion must be v2"
205
- Helm 3 requires `apiVersion: v2` in Chart.yaml. Update your Chart metadata.
206
-
207
- ### "unbalanced template braces"
208
- A Go template expression has mismatched `{{` / `}}`. Check your intrinsic usage.
209
-
210
- ### "hardcoded image tag"
211
- Use `printf("%s:%s", values.image.repository, values.image.tag)` instead of literal strings for container images.