fix(render): preserve null chart defaults so helm-guarded keys match Argo CD#157
Conversation
… false-diffs
Both fix sweep-only false diffs in the compare engine's loadFile, not drydock render:
- cleanupEmptyMetaMaps: drydock correctly emits argocd.argoproj.io/tracking-id (real
Argo CD does too); the raw oracle lacks it; the ignore-rule strips it leaving an empty
{} that falsely diffs against the oracle's absent map. ~700 false diffs.
- trimStringScalars: the oracle's yq re-serialization appends a trailing newline to
block-scalar string values that drydock's faithful helm-Go-engine value lacks.
…ery resolves argocd/<name> home-ops PR #3229 added explicit metadata.namespace: argocd to the apps/argocd Application/ApplicationSet/AppProject manifests, so drydock default discovery resolves apps as argocd/<name> without rendering the apps/argocd kustomization (which inflated the argo-cd Helm chart on every run).
…Argo CD Replace CoalesceValues (via ToRenderValuesWithSchemaValidation) with MergeValues + ValidateAgainstSchema + inline top map. CoalesceValues strips null chart defaults via cleanNilValues, causing hasKey guards to evaluate false under drydock while helm v3 (Argo CD's bundled CLI) retains them. Verified against helm v4.2.1 coalesce.go: the two paths differ only in nil handling; subchart/global/schema coalescing is identical.
✅ Full home-ops live-parity sweep — pre-merge gate PASSRan 0 capture failures / 31 apps. Total diffs 795 (prior baseline) → 96:
Remaining 96 = the known, accepted oracle-fidelity bucket (28 helm-hook resources the raw oracle includes but Argo CD + drydock exclude; 34 namespace-injection pairs where raw helm omits the namespace and drydock correctly stamps it). 0 in-place field diffs, 0 new diffs — the compare cleanup only removes false diffs and the helm fix only touched cilium (whole-fleet before/after confirmed). These 96 are inherent to the cache-free oracle (raw kustomize/helm vs Argo CD's post-processed output), not drydock render bugs. Gate met: cilium 5 diffs → 0, ~700 empty-map false diffs retired, no regressions. |
Summary
Argo CD's repo-server bundles helm v3, which retains
nullchart defaults in.Values. Helm v4'sCoalesceValues(used byToRenderValuesWithSchemaValidation) strips them viacleanNilValues, so{{- if hasKey .Values "x" }}guards evaluatefalseunder drydock while evaluatingtrueunder Argo CD — the key renders in Argo CD but is absent in drydock.Fix: replace
CoalesceValueswithMergeValues(nil-preserving) + a separateValidateAgainstSchemacall (internal/render/helm.go). Verified line-by-line against helm v4.2.1coalesce.go: the two paths differ only in nil-handling; subchart/global/table coalescing is identical, and the engine rebuildsFiles/Subcharts/Templateitself, so the reconstructed rendervaluesmap is faithful. Single call site.Home-ops live-fleet validation (cilium, before/after)
debug-verbose,nodeport-addresses,policy-cidr-match-modemissing from drydock'scilium-config(+ 2cilium.io/cilium-configmap-checksumcascade diffs onDaemonSet cilium/Deployment cilium-operator)."", matching Argo CD's helm v3 output (verified against argocd v3.4.3 managed fields).MergeValuesswap has no unintended blast radius.Sweep tooling (
test:, not changelog)cleanupEmptyMetaMaps(internal/paritycompare/compare.go): removes emptyannotations/labelsmaps left after the ignore-rule stripsargocd.argoproj.io/tracking-id— retires ~700 false diffs (drydock correctly emits tracking-id like real Argo CD; the raw oracle lacks it).trimStringScalars: right-trims trailing\nfrom string scalars — the oracle'syqre-serialization appends\nto block scalars that drydock's faithful helm-Go-engine value lacks (cert-manager.data.config.yaml, velero.data.global).--discover-kustomizefromscripts/home-ops-live-parity.sh: home-ops #3229 added explicitmetadata.namespace: argocd, so default discovery resolvesargocd/<name>directly (no more re-rendering the argo-cd chart every run). Caveat: valid only when the live cluster is synced at/after #3229; otherwise apps under-resolve as capture failures (not silent wrong results).parity-helm-null-defaultsmoke fixture (testdata/argocd-parity/) added + registered inargocd-parity-smoke.sh— the lasting CI real-Argo-CD guard for this behavior.Caveats
ValidateAgainstSchemanow sees null values whereCoalesceValuessilently dropped them. A chart with atype: stringfield lackingnullable: trueand a null default would now fail validation (such a chart would already failrequiredchecks; this is correct behavior).Test plan
go test ./internal/... ./pkg/... ./pr-action/...— passgo vet ./.../golangci-lint run ./...— clean""{}/null/trailing-newline → 0 diffs"", fleet before/after only those + checksum, no other app changed