Just kubectl apply the manifests. You can even use kubectl -k for the Kustomize configuration engine that can more or less replace most of what helm does today.
So what, I'm going to have a big Makefile or something with a bunch of kubectl applies? For each environment too? What if one of my dependencies (cert-manager for example) doesn't support directly applying via kubectl but have to be rendered with Helm? How do I manage versions of these dependencies too?
For better or for worse Helm is the defacto standard for deploying into k8s. Kustomizing toy apps or simple things may work but I have yet to see a large production stack use anything but Helm.
You can prerender helm charts into plain old manifests and apply those. How you want to handle applying them is up to you, even helm doesn't recommend or want people to run it as a service that auto applys charts anymore. Most folks check manifests into a git repo and setup automation to apply the state of the repo to their clusters--there are tons of tools to do this for you if you want.
Definitely check out kustomize, it's not a toy and it can easily handle one main manifest with specializations for each unique deployment environment. It's a very nice model of override and patching config instead of some insane monster template and yaml generation like helm.
I've worked 4 years for a client where everything was either plain K8S YAMLs Kustomizations, mostly the latter.
Large clusters, about 80 service teams and many hundreds of apps.
We (the platform team) managed roughly 30-40 services or controllers, including cert-manager, our own CRD for app deployments, ElasticSearch, Victoria Metrics, Grafana and others.
It was (still is, only I'm sadly not there anymore!) a high performing team and organisation with a lot going on.
We reviewed the decision to not use Helm many times and every time it was pretty much unanimous that we had a better solution than the opaque and awkward templating.
I'm not using Helm for deploying applications, though I use it for vendor manifests. It's not a small production stack, nor is it a toy app.
I'm not using Makefile either.
Helm is a kind of least-common denominator software that's better than doing nothing, but the template paradigm leaves a lot to be desired. It's main advantage is being language-agnostic.
Why would you need a Makefile? You have to run helm to apply helm charts, how is `kubectl apply -f .` any more complicated then that?
The entire existence of helm is superfluous. The features it provides are already part of Kubernetes. It was created (by /) for people who understand the package manager metaphor but don't understand how Kubernetes fundamentally works.
The metaphor is wrong! You are not installing applications on some new kind of OS. Using helm is like injecting untracked application code into a running application.
At best helm is just adding unnecessary complexity by re-framing existing features as features that helm adds.
In reality helm's obfuscation leads to an impenetrable mess of black boxes, that explodes the cost and complexity of managing a k8s cluster.
First off if you are packaging and/or publishing apps using helm charts, stop it!
There is purpose to the standardization of the Kubernetes configuration language. Just publish the damn configuration with a bit of documentation.... You know just like every other open source library! You're building the configuration for the helm chart anyway, so just publish that. It's a lot less work then creating stupid helm charts that serve no purpose but to obfuscate.
Here is your new no helm instructions:
We've stopped using helm to deploy our app. To use our recommended deployment, clone this repo of yaml configs. Copy these files into your kubernetes config repo, change any options you want (see inline comments). Apply with `kubectl apply -f .`, or let your continuous deployment system deploy it on commit.