Skip to content

Make CRD merging deduplication deterministic#4

Merged
tamalsaha merged 1 commit into
masterfrom
deterministic-crd-dedup
Jul 12, 2026
Merged

Make CRD merging deduplication deterministic#4
tamalsaha merged 1 commit into
masterfrom
deterministic-crd-dedup

Conversation

@tamalsaha

Copy link
Copy Markdown
Contributor

Problem

The crd-only command produced nondeterministic output for the same input chart. After deduplicating CRDs into crdMap (keyed by GroupKind), the final crdFiles slice was built by ranging over the map — and Go map iteration order is randomized per run. This made the generated chart's CRD file set order vary between otherwise identical runs.

Fix

Collect the map keys, sort them by Group then Kind, and build crdFiles in that stable order. Same input now yields byte-identical output.

The dedup precedence itself was already deterministic (parent-first, then dependencies — both stable slices; CRDObjects() returns sorted files), so only the final slice construction needed fixing. crd-less needed no change since it only preserves existing slice order.

Build the deduplicated CRD file slice from map keys sorted by group then
kind, instead of ranging over the crdMap Go map whose iteration order is
randomized per run. This makes repeated runs over the same input produce
byte-identical output.

Signed-off-by: Tamal Saha <tamal@appscode.com>
@tamalsaha
tamalsaha merged commit d58d215 into master Jul 12, 2026
4 checks passed
@tamalsaha
tamalsaha deleted the deterministic-crd-dedup branch July 12, 2026 21:52
tamalsaha added a commit that referenced this pull request Jul 13, 2026
crd-only deduplicates CRDs by GroupKind, keeping the first copy seen. The
winner was decided by the order Helm's CRDObjects() enumerates charts, which
is not stable — it varies with how subcharts were loaded (directory vs .tgz,
freshly pulled OCI deps, Helm version). #4 only sorted the output file order,
not which duplicate wins, so the generated crds-only chart still flapped
between conflicting copies of the same CRD.

Collect every candidate with its source chart path and a content digest, then
pick the winner by a total order: group, kind, chart depth (the parent chart
wins over its subcharts), chart path, filename, and finally content digest.
The digest tiebreak covers the case where one subchart is present as both a
directory and a .tgz (or reached via a diamond dependency) with differing
content and therefore an otherwise identical (group, kind, path, filename)
key. Warn only when a dropped copy actually differs from the winner.

Signed-off-by: Tamal Saha <tamal@appscode.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant