Description
For charts whose Kubernetes object names legitimately diverge (e.g. an umbrella
chart or multi-app manifest bundling several independent services), helmify silently
corrupts the generated resource names by stripping leading characters that were never
actually a shared prefix.
The output is still valid YAML/templates, so this is easy to miss and confusing to
debug. The derived values.yaml keys are mangled the same way.
Single-app charts are unaffected, because all their objects naturally share the
release-name prefix — which is likely why this hasn't been caught by existing
tests/examples.
Steps to reproduce
Save the following as manifests.yaml — four independent Deployments, as you'd have
in an umbrella chart. Note the names don't all share a common prefix, and two of them
(products, promotions) share a short one (pro):
apiVersion: apps/v1
kind: Deployment
metadata:
name: orders
namespace: default
spec:
replicas: 1
selector: {matchLabels: {app: orders}}
template:
metadata: {labels: {app: orders}}
spec:
containers: [{name: orders, image: nginx:1.25}]
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: payments
namespace: default
spec:
replicas: 1
selector: {matchLabels: {app: payments}}
template:
metadata: {labels: {app: payments}}
spec:
containers: [{name: payments, image: nginx:1.25}]
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: products
namespace: default
spec:
replicas: 1
selector: {matchLabels: {app: products}}
template:
metadata: {labels: {app: products}}
spec:
containers: [{name: products, image: nginx:1.25}]
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: promotions
namespace: default
spec:
replicas: 1
selector: {matchLabels: {app: promotions}}
template:
metadata: {labels: {app: promotions}}
spec:
containers: [{name: promotions, image: nginx:1.25}]
Run:
$ cat manifests.yaml | helmify mychart
Actual behavior
products and promotions lose their leading pro:
$ grep 'name: {{' mychart/templates/deployment.yaml
name: {{ include "mychart.fullname" . }}-orders
name: {{ include "mychart.fullname" . }}-payments
name: {{ include "mychart.fullname" . }}-ducts # <- should be -products
name: {{ include "mychart.fullname" . }}-motions # <- should be -promotions
The values.yaml keys are mangled identically:
$ grep -E '^[a-z]' mychart/values.yaml
ducts: # <- should be products
kubernetesClusterDomain: cluster.local
motions: # <- should be promotions
orders:
payments:
Expected behavior
name: {{ include "mychart.fullname" . }}-orders
name: {{ include "mychart.fullname" . }}-payments
name: {{ include "mychart.fullname" . }}-products
name: {{ include "mychart.fullname" . }}-promotions
No prefix should be stripped when the objects share no common prefix.
Root cause
In pkg/metadata/metadata.go, detectCommonPrefix uses prevName == "" to mean
"not initialized yet". But "" is also the correct running value once it's
determined that objects share no common prefix.
Walking the example (objects are folded in document order):
| step |
object |
running prefix |
note |
| 1 |
orders |
orders |
first object |
| 2 |
payments |
"" |
no common prefix with orders → correctly empty |
| 3 |
products |
products |
bug: empty prefix mistaken for "uninitialized", reset to full name |
| 4 |
promotions |
pro |
common of products and promotions |
The final prefix pro then gets stripped off every matching name by TrimName,
turning products → ducts and promotions → motions. The result also depends on
object ordering, so it's non-deterministic across inputs.
Expected fix direction
Track prefix-fold initialization with a dedicated boolean (e.g.
commonPrefixSet bool) instead of overloading prevName == "", so
detectCommonPrefix never resets an empty-but-initialized prefix.
Happy to open a PR with a regression test.
Description
For charts whose Kubernetes object names legitimately diverge (e.g. an umbrella
chart or multi-app manifest bundling several independent services), helmify silently
corrupts the generated resource names by stripping leading characters that were never
actually a shared prefix.
The output is still valid YAML/templates, so this is easy to miss and confusing to
debug. The derived
values.yamlkeys are mangled the same way.Single-app charts are unaffected, because all their objects naturally share the
release-name prefix — which is likely why this hasn't been caught by existing
tests/examples.
Steps to reproduce
Save the following as
manifests.yaml— four independent Deployments, as you'd havein an umbrella chart. Note the names don't all share a common prefix, and two of them
(
products,promotions) share a short one (pro):Run:
$ cat manifests.yaml | helmify mychartActual behavior
productsandpromotionslose their leadingpro:The
values.yamlkeys are mangled identically:Expected behavior
No prefix should be stripped when the objects share no common prefix.
Root cause
In
pkg/metadata/metadata.go,detectCommonPrefixusesprevName == ""to mean"not initialized yet". But
""is also the correct running value once it'sdetermined that objects share no common prefix.
Walking the example (objects are folded in document order):
ordersorderspayments""orders→ correctly emptyproductsproductspromotionsproproductsandpromotionsThe final prefix
prothen gets stripped off every matching name byTrimName,turning
products→ductsandpromotions→motions. The result also depends onobject ordering, so it's non-deterministic across inputs.
Expected fix direction
Track prefix-fold initialization with a dedicated boolean (e.g.
commonPrefixSet bool) instead of overloadingprevName == "", sodetectCommonPrefixnever resets an empty-but-initialized prefix.Happy to open a PR with a regression test.