Changelog
1. 1.5.0
1.1. Pluggable Kubernetes client backend
jhelm can now run on either Kubernetes client library — the official
io.kubernetes:client-java (the historical default) or Fabric8
io.fabric8:kubernetes-client — selected by whichever one is on the classpath. Both
backends are behaviorally identical, down to a byte-identical sh.helm.release.v1.* release
Secret format (a release written by one backend is readable by the other). See
Choosing a Kubernetes client backend.
-
Classpath-selected backend —
jhelm-kubenow declares both clients as optional, so it ships neither transitively; the consumer puts one on the classpath (the CLI bundlesclient-java). A new Fabric8 backend implements the full cluster surface — release storage, server-side apply, delete/cascade, wait/status, and thelookup/kubeVersiontemplate data — at parity with the official-client backend (#776, #777, #778, #779). -
jhelm.kubernetes.backend—auto(default; prefersclient-javawhen both are present),client-java,fabric8, ornone(build no ambient client — the host supplies its own). Selection is deterministic — exactly one backend activates even with both libraries on the classpath (#778, #796). -
Library-agnostic retry — transient-failure classification reads the HTTP status from either client’s exception, so retry works on whichever backend is active (#780).
1.2. Embedding jhelm in a multi-cluster host
New building blocks let a Spring Boot host embed jhelm-core/jhelm-rest as a library and serve many clusters. See Embedding jhelm in a multi-cluster host.
-
Public per-cluster factory —
KubeServices.fabric8(client)/KubeServices.clientJava(apiClient)(andKubernetesProviders.*) build a fully-decoratedKubeService/provider from a host-supplied client, with no internal-package coupling (#795). -
Per-request cluster routing — a
KubeServiceResolverbean lets the release API resolve a per-clusterKubeServiceper request (e.g. from a header) instead of one ambient client (#773). -
Namespace-scoped release listing —
jhelm.kubernetes.release-namespaceslists releases across a namespace set instead of cluster-wide, so jhelm works on namespace-scoped RBAC without cluster-widesecrets:list(#798). -
Accurate error status — Kubernetes failures now surface the real HTTP status (401/403/404 pass through instead of collapsing to 500/502), with the cluster reason in the message (#797).
-
Host-security passthrough —
jhelm.rest.access-interceptor.enabled=falseopts out of jhelm’s access interceptor when the host secures the endpoints itself (#774). -
Health opt-out —
jhelm.kubernetes.health.enabled=falsesuppresses the ambient Kubernetes health indicator (#800). -
Embedded-safe repo config —
jhelm.config-pathis accepted under ajhelm.core.*alias, the resolved config/cache paths are logged at startup, and jhelm warns before implicitly reading/writing the operator’s~/.config/helm(#769).
1.3. External Java plugin JARs
Java plugins built against jhelm-plugin-api can now be loaded from a directory at runtime,
without being on the build classpath. See Loading external plugin JARs.
-
jhelm.plugins.path— one or more directories scanned for external plugin JARs. Each jar is loaded in its own class loader (isolated so plugins can carry conflicting transitive dependencies) and its declaredServiceLoaderservices are merged with the classpath and Spring-bean plugins. Works on every surface (CLI/REST/MCP/embedded), independent of how the application is launched (#765). -
CLI
--plugin-dir— a global flag (alsoJHELM_PLUGINS_PATH) to set the plugin directory for a run (#766).
1.4. Other improvements
-
Public chart-version comparator + cross-repo lookup —
ChartVersions.compare, aComparableChartVersion, andRepoManager.findChartVersions/latestOf, plus ajhelm outdated <chart>command reporting the latest available version and whether an upgrade is available (#771). -
charts/show/resolves the latest version* —showfor arepo/chartreference with no version now resolves the newest from the repo index instead of returning HTTP 500 (#772). -
snakeyaml-engine floor pinned — jhelm requires snakeyaml-engine 3.x; the version is now pinned so a transitive 2.x can’t cause a runtime
NoSuchMethodErroron the first chart load (#770).
2. 1.3.0
2.1. Helm plugin compatibility
jhelm now consumes real Helm plugins from the existing ecosystem (helm-diff, helm-secrets,
helm-s3, …), discovered from $HELM_PLUGINS and invoked the way Helm invokes them. See
Helm Plugin Compatibility. This is separate from jhelm’s existing
WASM (.jhp) plugin system, which stays as-is.
-
Subcommand plugins —
jhelm <name>runs an installed plugin (helm-diff, helm-secrets) as a subprocess with theHELM_*environment, propagating its exit code (#735). -
plugin installfrom Helm sources — git URL (with--version),.tar.gz/.tgz(local orhttp(s)), or a local directory, in addition to.jhp; runs the install hook (#736). -
plugin list/update/uninstall— list shows Helm and WASM plugins with aKINDcolumn; update doesgit pull+ update hook; uninstall runs the delete hook and removes the plugin (#737). -
Downloader plugins — a chart URL with a custom scheme (
s3://,gs://, …) is fetched via the matching downloader plugin using Helm’s downloader contract (#738). -
Post-renderer plugins —
--post-renderer <name>resolves an installed plugin (Helm 3.10+), with--post-renderer-args, ontemplate/install/upgrade(#739).
Running a native plugin (dispatch, downloader, post-renderer, hooks) is gated on the CLI’s
FULL security posture — the local kubeconfig is the trust boundary, as with helm.
2.2. Java plugin API
New jhelm-plugin-api module: extend jhelm by implementing a Java interface, discovered via
ServiceLoader or as a Spring bean. See Java Plugin API.
-
Post-renderers (
JhelmPostRenderer), chart downloaders (JhelmChartDownloader), lifecycle listeners (JhelmLifecycleListener), and template-function providers (JhelmTemplateFunctionProvider) run in the same render/fetch/lifecycle/engine paths as the native-Helm and WASM plugins, across every jhelm surface (CLI/REST/MCP/library). -
Java plugins run in-process (code already on the classpath), so they are not gated on the security posture; a
jhelm-plugin-api-samplemodule shows one of each.
3. 1.2.1
3.1. Dependencies
-
Template engine moved to
gotmpl4j 1.3.0(from 1.2.0). Picks up a Go-parity correctness fix — variadic method calls on values now resolve instead of silently returning nil — plus custom action delimiters, a thread-safe template cache, and the 1.3.0 engine perf batch (shareable function registry, cached method/field dispatch, cheaper scope handling). Additive and non-breaking; no jhelm API or rendering change (chart-parity suite unchanged).
3.2. Performance
The render hot path was profiled (JFR / jvmlens) and tightened. Every change is byte-for-byte identical to Helm across the full chart-parity suite (547 charts, 0 diffs):
-
Function registry reused across renders — the ServiceLoader result and the template-independent Sprig function set (~260 functions), plus their reflection/dispatch caches, are built once per
Engineand shared by every render instead of rebuilt each call (#717). -
Render thread reused instead of spawned per render — rendering runs on a single reused daemon executor rather than creating and joining a fresh large-stack thread every call. On the JMH render harness this is ~1.6x throughput with far less GC churn, and it also closes a pre-existing data race on shared engine state under concurrent renders (#721).
-
toYamlquote-stripping scans in one pass — the YAML post-processor no longer splits the document into aString[]and rebuilds it; it scans in place, allocating only for the lines it actually rewrites (#720). -
Render values boxed once per render — numeric leaf coercion runs a single time and the boxed leaves are reused, instead of deep-copying the value tree twice (#718).
-
Template parse cache on by default — a new
Engine()now keeps a 256-entry parsed-template cache, so re-rendering a chart skips re-parsing unchanged templates (#726).
3.3. Fixes
-
Library-chart
define`s are no longer served from a partial parse-cache entry— with the parse cache enabled, a global `define registered by an earlier template could be served from an incomplete cached node-delta when a second chart reused the same cache key, dropping the definition (include: Template '…' not found). Templates carrying adefinenow always parse in full, keeping the cache safe for library charts such as Bitnami Common (#726). -
install/upgradeno longer choke on---inside a YAML comment — a rendered manifest with a decorative comment such as# ---------------- Postgres ----------------failed to apply with a SnakeYAML parse error, because the manifest document splitter matched the---inside the comment as a document separator and produced an invalid fragment (jhelm templatewas unaffected; the bug was only in the apply/diff/get path that re-splits the manifest). The splitter is now line-anchored — only a line that is exactly---(optionally with trailing whitespace or a comment) starts a new document — via a sharedManifestDocuments.splitreused by hook stripping, manifest diffing, andget. #713.
4. 1.2.0
Closing CLI flag-parity gaps with Helm across the template, install, and query commands, so
more helm scripts run unchanged against jhelm. See CLI Flag Parity.
4.1. Helm parity
-
Machine-readable output on more commands —
-o table\|json\|yamlnow coversstatus,history,install,upgrade,repo list, andsearch hub, emitting Helm-shaped output (nestedinfo, snake_case keys) for scripts and agents (#678). -
templatesource markers — rendered manifests carry a Helm-style# Source: <chart>/templates/<file>marker before each document (#679). -
templaterender-control flags —-s/--show-only,--output-dir,--skip-tests,--include-crds, and--is-upgrade(#679). -
install --generate-name— omit the release name and pass-g/--generate-nameto auto-generate<chart>-<timestamp>, as Helm does (#680). -
install --description/--labels— store a custom release description and custom labels on the release Secret (#680). -
upgrade --description/--labels— set the new revision’s description and labels; without--labels, the previous release’s labels are carried forward, matching Helm (#680). -
--set-literal— oninstall,upgrade,template, andlint: set a value taken fully literally (no type coercion, no comma or escape interpretation), applied at the highest precedence in the--setfamily (#680). -
--dependency-update— oninstall,upgrade, andtemplate: update a local chart’scharts/from itsChart.yamldependencies (likehelm dependency update) before the operation. The update flow is now a reusableDependencyUpdateActionshared with thedependency updatecommand (#680). -
listfiltering & pagination —listgains-l/--selector(label selector,key=value/key!=value, comma-ANDed),--filter(regex on the release name), and--offset/-m/--max(paginate; default max 256). Results are sorted by name (#681). -
liststatus filters —-a/--allshows every status, and--deployed/--failed/--pending/--uninstalled/--uninstalling/--supersededrestrict to those states. The default view hides uninstalled and superseded releases, matching Helm (#681). -
list -A/--all-namespaces— list releases across every namespace, backed by a newKubeService.listAllReleases()(lists release Secrets cluster-wide). Releases are keyed by namespace+name so same-named releases in different namespaces stay distinct (#681). -
install/upgradefrom a repository — pass a chart name with--versionand an ad-hoc--repo <url>(plus--username/--passwordand TLS--cert-file/--key-file/--ca-file/--insecure-skip-tls-verify/--pass-credentials) to fetch the chart directly, matchinghelm install/upgrade --repo. Arepo/chartoroci://reference is also resolved via the registered repositories. Local chart paths still work unchanged (#682). -
uninstallwait/cascade semantics —--dry-run(report without deleting),--wait/--timeout(block until the resources are gone, backed by a newKubeService.waitForDeleted),--cascadebackground\|foreground\|orphan(Kubernetes deletion propagation), and--description(stored on the release when--keep-historyis set). Mirrored on REST (DELETEquery params) and MCP (#683). -
rollbackforce/cleanup semantics —--dry-run,--force(delete-and-recreate),--cleanup-on-fail(delete resources created during a failed rollback),--recreate-pods(rolling restart of the release’s workloads via a restart annotation), and--wait/--wait-for-jobs/--timeout. The rollback readiness wait now lives in the action so REST and MCP honor it too (#683). -
pullunpack & provenance —--untar/--untardirunpack the fetched chart (and drop the.tgz), and--verify/--prov/--keyringfetch the chart’s detached.provand check its PGP provenance before use (reusing theverifylayer). RESTPOST /repos/pullgains averifyflag.--devel(prerelease resolution) remains the one open pull gap — it needs semver latest-version resolution jhelm does not have yet (#684). -
repo addauth, TLS & update control —--username/--password/--cert-file/--key-file/--ca-file/--insecure-skip-tls-verify/--pass-credentialsare persisted intorepositories.yamland honored (host-gated) on every index refresh and chart pull;--force-updatereplaces an existing repo (a duplicate name otherwise fails) and--no-updateskips the immediate index fetch. Mirrored on RESTPOST /repos(#685). -
Validating
registry login—registry loginnow follows Helm’s flow: it validates the credentials against the registry (a/v2/ping and, on a Bearer challenge, a token exchange) before storing them, and honors the login-time transport flags--insecure,--plain-http,--ca-file,--cert-file, and--key-file. As in Helm, those transport options apply only to the handshake and are not persisted — only the credentials are stored. A wrong password, TLS failure, or unreachable registry now fails the login instead of silently saving. Completes #708. -
Global persistent flags — Helm’s cluster/config flags are now accepted on every command (before or after the subcommand):
--kubeconfig,--kube-context,--kube-apiserver,--registry-config,--repository-config,--repository-cache, and--debug. They are resolved before the application context is built (they configure startup beans) and take precedence over the equivalentjhelm.*properties/env (#708). -
Misc command flags —
package --version/--app-version(rewrites theChart.yamlinside the archive) and-u/--dependency-update;show chart\|values\|readme\|crds\|all--version/--repo/--username/--password+ TLS (show a chart from a repository without a priorpull);lint --quiet/--with-subcharts/--kube-version; andversion --template(Go-templates the version output).show --develremains a documented gap (#687). -
REST releases API now returns Helm-shaped JSON — the
/releaseslist/status/history and install/upgrade responses now use Helm’s-o jsonschema (snake_case, nestedinfo) instead of jhelm’s internal DTO, so REST consumers see the same shape ashelm … -o jsonand the CLI (#686). Breaking: clients reading the old fields must migrate (e.g.statusmoves from$.statusto$.info.status; listchartNamebecomeschart; historyversionbecomesrevision). -
MCP tools return structured JSON —
helm_list,helm_status, andhelm_historynow return Helm-shaped JSON (array of rows / nestedinfoobject) instead of prose text, so agents can parse them directly (#686). -
Install options on the API — the REST install endpoints and the MCP
helm_installtool acceptdescriptionandlabels, mirroring the CLI’s--description/--labels(#686). -
Template render controls on the API — the REST template endpoints and the MCP
helm_templatetool acceptshowOnly,skipTests,includeCrds, andisUpgrade, mirroring the CLI’s--show-only/--skip-tests/--include-crds/--is-upgrade(#686).
5. 1.1.0
The first release to extend beyond Helm parity: a Spring-Boot-style value-management layer — profiles, a Spring Cloud Config Server source, and encrypted secret values — layered on top of the Helm-compatible core. Every addition is opt-in; charts that don’t use these features render byte-for-byte as Go Helm.
5.1. Features
-
Value profiles — keep environment-specific values (dev, staging, prod, …) in one place and activate them at render/install/upgrade time with
-P/--profile, mirroring Spring Boot. Profiles come from----separated documents gated byspring.config.activate.on-profileor fromvalues-<profile>.yamlsidecars, and apply to a chart’s ownvalues.yamland to-ffiles (#670). -
Values from a Spring Cloud Config Server — fetch values from a central, git-backed Spring Cloud Config Server over jhelm’s SSRF-guarded HTTP path, reusing the active profiles for the requested profile and slotting into the override order the way Spring Boot’s config-data model does. Disabled by default (#671).
-
Encrypted values —
{cipher}<hex>secret tokens in any values source are decrypted at render time whenjhelm.encrypt.keyis set, byte-compatible with Spring Cloud Config’s encryption. Ships ajhelm encrypt/jhelm decryptCLI tool and a runnable, securedjhelm-config-server-samplemodule as a DevOps starting point and test fixture. Inert unless a key is configured (#674).
5.2. Fixes
-
jhelm testno longer hangs on a completed pod — terminal pod phases (Succeeded/Failed) are handled instead of being waited on indefinitely (#668). -
Manifests apply/delete as unstructured maps — resources are applied and deleted as unstructured maps rather than typed models, fixing kinds the typed path mishandled (#666).
6. 1.0.2
A maintenance release fixing two bugs found in triage. No public API changes.
6.1. Fixes
-
lookupreturns the full resource and queries the live cluster — thelookuptemplate function now returns the whole object (includingSecret/ConfigMapdataas base64), and is wired to the live Kubernetes API in the CLI and anyjhelm-kube-backed app, as Helm does during install/upgrade. Previously it silently returned the empty stub (and, even when reached, only the resource’s metadata), which regenerated the reuse-existing-password idiomindex $existing.data "key" \| b64decon every upgrade and corrupted bundled-database passwords (#663). -
CLI reports the real build version —
jhelm --version,-V,jhelm versionandjhelm envnow report the actual build version (sourced from Spring Boot build-info, the same source Actuator’s/actuator/infouses) instead of a hardcoded0.0.1. The REST OpenAPI document reports the same (#662).
7. 1.0.1
A maintenance release: bug fixes across the Kubernetes layer and the CLI, plus CLI startup and ergonomics improvements. No public API changes.
7.1. Fixes
-
Cluster-scoped resources — kinds such as
ClusterRole,ClusterRoleBinding,CustomResourceDefinition,Namespace,StorageClassandPriorityClassare now applied and deleted at the cluster scope instead of being forced through the namespaced API path, which the API server rejected (#650). -
CLI exit codes — commands exit non-zero on failure (for example a
--waitreadiness timeout), so scripts and CI can detect a failed operation instead of seeing a spurious success (#647).
7.2. CLI security
-
The CLI now honors
jhelm.security.modeand defaults toFULL(read-write), matchinghelm— the local kubeconfig and cluster RBAC are the trust boundary. Settingjhelm.security.mode=READ_ONLYrefuses the cluster-mutating commands (install,upgrade,uninstall,rollback,test) with a non-zero exit. The API key stays a REST/MCP concern and is not required to unlock the CLI (#653, #654, #657).
7.3. CLI ergonomics
-
Faster startup through lazy bean initialization and trimming auto-configurations a one-shot CLI never uses (#649, #651).
-
Quieted a benign picocli-spring
INFOline ("Unable to get bean of class interface java.util.List …") that surfaced on multi-value options such as--setand read like a stacktrace (#656).
8. 1.0.0
The first stable release. 1.0 draws a supported public API surface, hardens security and
provenance, verifies Helm interoperability against the real helm binary, and makes the
chart-parity claims honest about exactly what is measured.
8.1. Security
-
SSRF controls — an opt-in server-mode block of private / link-local / site-local targets (
jhelm.security.block-private-networks, default off) applied through the repository and OCI HTTP clients and a DNS-resolver guard, so a hosted jhelm cannot be steered at internal addresses. -
Credential and archive hardening — repository credentials are host-gated (not sent on a redirect to a different host), chart un-tar is capped against decompression bombs, OCI reference URLs are validated, and the written registry-credentials file gets owner-only permissions.
8.2. Provenance
-
Key usability checks —
verifynow rejects a revoked or expired signing key, so a retired or compromised provenance key can no longer validate a chart even with an intact signature. -
Clear-sign correctness — OpenPGP dash-escaping (RFC 4880 §7.1) is reversed before verifying, so a
helm/GnuPG-produced.provwhose signed body contains a--leading line verifies correctly.
8.3. Real cluster capabilities
-
.Capabilitiesfrom the cluster —.Capabilities.KubeVersionand.APIVersionsare now populated from the connected cluster forinstall/upgrade;templateaccepts--kube-versionand-a/--api-versionsto pin them offline (defaulting to a fixed Kubernetes version for deterministic rendering).
8.4. Helm interoperability
-
Shared release storage — the release record (including the embedded chart) is now byte-schema-compatible with Helm 3’s
sh.helm.release.v1Secret format, so a release installed by one tool is listable, upgradable, roll-back-able, and removable by the other. Covered by a two-wayhelm↔jhelmintegration suite that runs against a real cluster and the realhelmbinary in CI. See Interoperability with Helm. -
Shared configuration — jhelm honors Helm’s
HELM_*environment variables and reads/writes Helm’s ownrepositories.yamlandregistry/config.jsonat Helm’s locations. See Configuration.
8.5. CLI parity
-
New commands / flags —
repo update;list -o json|yaml;pull --repo <URL>with inline auth/TLS flags;upgrade --force(delete-and-recreate);--dry-run=client|server|nonewith real server-side dry-run and--wait-for-jobs; and an enrichedenvthat reports the effective Helm config locations. -
See the CLI flag parity reference for the full helm ↔ jhelm map.
8.6. REST & MCP
-
OpenAPI —
jhelm-restships a well-documented springdoc OpenAPI document. -
Upgrade value strategy — the upgrade endpoints expose
valueStrategy(DEFAULT/RESET/REUSE/RESET_THEN_REUSE), mirroring the CLI’s value-retention flags.
8.7. API surface & stability
-
Published API surface — a documented, supported public API with a stability statement (Supported API); the
jhelm-kubeservice implementation moved behind an.internalpackage, and theKubernetesProviderSPI plus the 1.0 model mutability contract are documented. -
Metrics — action-layer and chart-pull metrics in
JhelmMetrics.
8.8. Correctness & release quality
-
Honest parity — the chart-parity suite compares against
helm templatewith default values and a pinned--kube-version, byte-for-byte apart from a documented set of non-semantic comparison-ignores; over-emitting a resourcehelmdoes not is now a hard test failure rather than a warning. The docs state precisely what parity does and does not cover. -
Packaging — the CLI fat-jar is excluded from the Maven Central bundle; Javadoc doclint is enforced on build.
9. 0.4.0
The pre-1.0 API freeze release, plus an MCP server, a REST library/starter split, and the
upgrade value-handling fixes (including the value-retention flags listed as a known
limitation in 0.2.0).
9.1. API freeze (breaking, pre-1.0)
-
Unchecked exceptions — the action layer and
KubeServicenow throw the uncheckedJhelmExceptionhierarchy instead ofthrows Exception. -
No leaked client types — the kubernetes-client
ApiException/ApiClientare wrapped behindKubeClient, and the BouncyCastle PGP types behindSigningKey/VerificationKeyring. -
Options objects — the action API now takes immutable
InstallOptions,UpgradeOptions,UninstallOptions, andRollbackOptionsobjects instead of long parameter lists. -
Immutable result models —
Release,ReleaseInfo, andMapConfigare now immutable; releasestatusis a typedReleaseStatusenum and the lifecycle phase aLifecyclePhaseenum.
9.2. MCP server
-
jhelm-mcp+jhelm-mcp-starter— a new Model Context Protocol server exposing jhelm operations as tools for AI agents, built on Spring AI 2.0 and mirroring the REST operation set. AREAD_ONLY/FULLaccess mode (jhelm.mcp.mode, defaultREAD_ONLY) gates the cluster-mutating tools.
9.3. REST library/starter split
-
Pure library —
jhelm-restis now a pure library; the newjhelm-rest-startercarries the auto-configuration (Spring-Boot-Admin style). -
Access mode — a
READ_ONLY/FULLmode (jhelm.rest.mode, defaultFULL) gates the cluster-mutating endpoints. Authentication is the embedding application’s responsibility (Spring Security).
9.4. Upgrade value handling
-
User values persisted — user-supplied values are now persisted as the release config, fixing a data-loss bug (and
get values). -
Value-retention flags implemented —
--reset-values,--reuse-values, and--reset-then-reuse-valuesare now implemented. These were listed as a known limitation in0.2.0.
9.5. New flags
-
Value flags —
--setnow type-coerces like Helm (int/bool/null; floats and leading-zero values stay strings), joined by--set-string,--set-file, and--set-json. -
Lifecycle flags —
--no-hooks(install/upgrade/uninstall/rollback),--history-max(release-history pruning, default 10), and--create-namespace.
9.6. Engine
-
Loud render failures — recursive / too-deep template rendering now fails with a
TemplateRenderExceptioninstead of baking anERROR:string into the manifest. -
gotmpl4j 1.1.0 — the engine dependency moves to
gotmpl4j 1.1.0(perf wave: double formatting withoutBigDecimal, cached property accessors, an allocation-free lexer).
10. 0.2.0
Helm template-function conformance improvements, grinding jhelm-gotemplate-helm against
Helm’s own pkg/engine/funcs_test.go suite (the divergence backlog drops from 37 cases to 1).
-
Helm 4 duration helpers — implemented
mustToDuration,durationSeconds,durationMinutes,durationHours,durationDays,durationWeeks,durationMilliseconds,durationMicroseconds,durationNanoseconds,durationRoundTo, anddurationTruncateTo, as faithful ports of Go’stime.Duration(parsing, rounding, andString()formatting). -
fromerror reporting* —fromJson/fromYamlandfromJsonArray/fromYamlArraynow return Helm’smap[Error:<message>]/[<message>]with Go’sjson.Unmarshaltype-mismatch text when handed valid input of the wrong shape, instead of silently returning an empty container. -
toTomltable output — now emits Go BurntSushi-style[table]/headers with the matching key ordering and indentation, instead of Jackson’s dotted keys.
All 346 reference charts continue to render byte-identically to helm template.
10.1. Known limitations
-
The
helm upgradevalue-retention flags (--reset-values,--reuse-values,--reset-then-reuse-values) remain unimplemented. -
One
fromTomlconformance case (a malformed-input syntax error) still differs from Helm in the exact error wording, an inherent difference between the Jackson and Go (BurntSushi) TOML parsers.
11. 0.1.0 — first public prerelease
The first published release of jhelm, on Maven Central (marked pre-release).
-
Helm-faithful rendering — chart templates render byte-for-byte identically to
helm templateacross a CI-enforced suite of 346 real-world charts (Bitnami, Grafana, GitLab, Kubernetes-monitoring, and others). -
Go template engine — the full Go
text/templatelanguage plus Helm’s Sprig function set, provided by the standalone gotmpl4j library (gotmpl4j 0.3.0). Renders absent/nil values as the empty string (missingkey=zero), matching Helm. -
Helm template functions —
include,tpl,required,lookup,toYaml/fromYaml,toJson/fromJson,toToml, and the chart/capabilities/files helpers. -
Chart lifecycle — install, upgrade, rollback, uninstall, list, status, history, test.
-
Repositories & registries — classic HTTP repositories and OCI registries, with digest verification and content-based caching.
-
Dependency management — list, update, and build chart dependencies; recursive value coalescing across subcharts.
-
Packaging & provenance — package charts to
.tgz; PGP sign and verify. -
JSON Schema validation — chart values validated against
values.schema.json(Draft-07). -
Distribution surfaces — embeddable library, Spring Boot starter (auto-configured action beans), REST API (
jhelm-rest, with OpenAPI docs), Maven packaging plugin (jhelm-plugin), and a 22-command CLI. -
Built on Java 21, Spring Boot 4.0.7, Kubernetes Client 26.0.0, Picocli 4.7.7.
11.1. Known limitations
The following are out of scope for this first prerelease and are planned for 0.2.0:
-
helm upgradevalue-retention flags —--reset-values,--reuse-values, and--reset-then-reuse-valuesare not yet implemented.upgradeapplies the chart defaults merged with the values you pass on the command line. -
Helm function fidelity — a small number of functions have documented partial-fidelity behaviour: the Helm 4 duration helpers, the
fromYaml/fromJsonerror-map format, and nestedtoTomltables. See Function Coverage. -
Subchart value coalescing — deeply-nested umbrella charts (GitLab-scale) may differ from Helm in rare value-coalesce edge cases; the common cases render byte-identically (the 346-chart parity suite).