If you are the only consumer of your helm chart - don't use helm
I find Helm to be against a fundamental principle of Kubernetes: Declarative Configuration (further rooted in Promise Theory).
While Helm is written in a mostly declarative-looking syntax, the control structures (among other things) result in it being procedural. The end result is that a helm chart and it's templates become deceptively complex and each value in the values file needs fresh new documentation - because it is unique to that one helm chart.
Usually you'll find something like this in a repo:
# values.yaml:
replicaCount: 2
image:
repository: blah.com/hello_world
tag: v10000
service:
type: ClusterIP
internalPort: 8000
ingress:
enabled: false
...
It looks declarative, but in reality all of those inputs are just fed into some procedural code in the chart to be interpreted uniquely by that procedural code and producing anything.
Engineering & Operations Divergence
As a practical consequence, I find that this results in an Engineering organization increasingly being detached from Kubernetes and and relying on a set of "Kubernetes experts" and thinking that Kubernetes is so complex that only those experts can work with it. However, generally this isn't the case.
With entry-level knowledge of Kubernetes' Deployment, Pod, Service and maybe PersistantVolume and Ingress any software engineer can be competent in making changes to any app deployed in Kubernetes. This is probably ~1 day to learn the basics and I'd say comparable learning curve to docker compose. For someone comfortable in a docker compose file, then it will be even easier!
What's the Alternative?
The alternative is instead of putting a Helm chart into a repo, put plain Kubernetes yaml resources into your repo. At most you can use kustomize and overlays to adjust them further (e.g. to adjust environment variables for different environments).
So What's Helm Good For?
Helm is good if you're distributing a "packaged application" to others to run in Kubernetes. For example, someone packaging a Wordpress with a database, Helm makes sense. In a case like this, the the internals of how all these things work inside the cluster don't matter to you and you won't have any other Kubernetes resources deployed that are coupled to them (within the cluster), then the packager can simplify things for you and update things over time and the consumers of the package don't have to know or worry about the details.
However, this is fundamentally different from an engineering organization developing and operating their own application internally. In that case the "infrastructure" of the application, is just as important for engineers to be able to understand and maintain as it is for them to understand the code. Putting that infrastructure behind opaque code that spits out a bunch of resources dynamically at runtime only adds complexity to understanding the resources. You still must understand all those resources, but now you must understand the procedural code that deployed those resources too. So why not just maintain the resulting resources and stop writing more code to produce them?