Skip to content

feat(helm): add digest processor for Helm access type#2064

Merged
jakobmoellerdev merged 2 commits into
open-component-model:mainfrom
jakobmoellerdev:helm-digest-processor
Mar 25, 2026
Merged

feat(helm): add digest processor for Helm access type#2064
jakobmoellerdev merged 2 commits into
open-component-model:mainfrom
jakobmoellerdev:helm-digest-processor

Conversation

@jakobmoellerdev

Copy link
Copy Markdown
Member

What this PR does / why we need it

Add a digest processor that resolves chart digests from Helm repository index.yaml (HTTP/S) or OCI manifest (OCI registries) without downloading the full chart. Export GetterProviders for reuse (but only in internal package).

Which issue(s) this PR fixes

makes sure that controllers and cli can start to process digests for helm chart accesses.

Testing

How to test the changes

you need task init/go.work

Verification
  • I have tested the changes locally by running ocm

Add a digest processor that resolves chart digests from Helm repository
index.yaml (HTTP/S) or OCI manifest (OCI registries) without downloading
the full chart. Export GetterProviders for reuse.

Signed-off-by: Jakob Möller <contact@jakob-moeller.com>
@coderabbitai

coderabbitai Bot commented Mar 24, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

A new Helm digest processor plugin is introduced in Go that resolves and validates chart digests from Helm repositories. It supports both OCI registry and HTTP-based repository sources, with proper context cancellation handling and digest verification logic.

Changes

Cohort / File(s) Summary
Helm Digest Processor
bindings/go/helm/digest/digest.go, bindings/go/helm/digest/digest_test.go
New digest processor implementation handling Helm repository credential resolution, digest extraction from OCI registries and HTTP index files, and digest application/verification with context-aware operations and comprehensive test coverage.
Download Package Export
bindings/go/helm/internal/download/download.go
Exported previously unexported GetterProviders() helper function to enable reuse by the digest processor.

Sequence Diagram

sequenceDiagram
    participant Client
    participant DigestProcessor
    participant HelmRegistry as Helm Registry<br/>(OCI/HTTP)
    participant IndexFile as Index File<br/>(HTTP repos)
    participant Resource

    Client->>DigestProcessor: ProcessResourceDigest(ctx, resource, credentials)
    
    alt OCI Repository
        DigestProcessor->>HelmRegistry: Resolve OCI chart reference
        HelmRegistry-->>DigestProcessor: Chart digest
    else HTTP/S Repository
        DigestProcessor->>IndexFile: Fetch index.yaml
        IndexFile-->>DigestProcessor: Repository index
        DigestProcessor->>DigestProcessor: Extract chart digest by name/version
    end
    
    DigestProcessor->>Resource: Deep copy resource
    
    alt Digest is nil
        DigestProcessor->>Resource: Apply resolved digest
    else Digest exists
        DigestProcessor->>DigestProcessor: Verify match with resolved digest
        alt Mismatch
            DigestProcessor-->>Client: Error
        end
    end
    
    DigestProcessor-->>Client: Updated resource
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~35 minutes

Poem

🐰 A digest processor hops into place,
Helm charts checked with speed and grace,
From OCI streams and HTTP flows,
Verification logic that perfectly flows—
Trust in each chart, no guessing, hooray! 🎯

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding a digest processor for the Helm access type, which is the primary feature introduced across all modified files.
Description check ✅ Passed The description is directly related to the changeset, explaining what the digest processor does, why it's needed, and how it enables controllers and CLI to process Helm chart digests.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added kind/feature new feature, enhancement, improvement, extension size/l Large labels Mar 24, 2026
@jakobmoellerdev jakobmoellerdev marked this pull request as ready for review March 24, 2026 21:10
@jakobmoellerdev jakobmoellerdev requested a review from a team as a code owner March 24, 2026 21:10

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
bindings/go/helm/digest/digest_test.go (2)

260-277: Integration test relies on external resource stability.

The hardcoded digest assertion will fail if Grafana ever republishes grafana:8.8.2 with a different digest. Consider adding a comment noting this dependency, or verify only that the digest fields are populated without asserting the exact value.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bindings/go/helm/digest/digest_test.go` around lines 260 - 277, The
integration test TestProcessResourceDigest_RealRepo currently asserts a fixed
digest value which can break if the external Grafana chart is republished;
update the test to avoid asserting the exact digest string and instead verify
that ProcessResourceDigest (on digest.NewDigestProcessor) returns a non-nil
result with result.Digest populated and that result.Digest.HashAlgorithm and
result.Digest.NormalisationAlgorithm are non-empty (or match expected algorithm
names if stable), and add a comment above TestProcessResourceDigest_RealRepo
explaining the test depends on an external repo and may be brittle in CI;
alternatively mark it as an external-only/integration test by skipping in CI
environments.

1-16: Consider adding test coverage for OCI registry resolution.

The test suite covers HTTP/S repositories comprehensively, but there are no tests for the oci:// code path. Consider adding tests using a mock OCI registry or at least a real-repo integration test similar to TestProcessResourceDigest_RealRepo.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bindings/go/helm/digest/digest_test.go` around lines 1 - 16, Add test
coverage for the OCI registry code path by creating a new test in digest_test.go
(e.g., TestProcessResourceDigest_OCI) that mirrors
TestProcessResourceDigest_RealRepo but targets an oci:// reference; either mock
an OCI registry endpoint or use a real OCI repo setup and resolve via the digest
package's resolver/ProcessResourceDigest logic to assert correct digest
resolution and error handling. Ensure the test imports/uses the same helpers and
runtime setup as TestProcessResourceDigest_RealRepo, exercises the oci:// URL
path, and asserts expected digest values or failure modes using require/assert.
bindings/go/helm/digest/digest.go (1)

274-276: Error message has reversed semantics.

The error says "expected %s, got %s" with target.Value (the existing digest) as "expected" and d.Encoded() (the resolved digest) as "got". From the verification perspective, the resolved digest is what we expect the resource to have.

✏️ Suggested fix
 	if target.Value != d.Encoded() {
-		return fmt.Errorf("digest value mismatch: expected %s, got %s", target.Value, d.Encoded())
+		return fmt.Errorf("digest value mismatch: resolved %s, but resource has %s", d.Encoded(), target.Value)
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bindings/go/helm/digest/digest.go` around lines 274 - 276, The error message
in the comparison using fmt.Errorf has reversed semantics: when target.Value !=
d.Encoded() the resolved digest (d.Encoded()) is what we expect, and
target.Value is the current/actual value; update the fmt.Errorf call (the one
comparing target.Value and d.Encoded()) so the format arguments are swapped and
read "expected %s, got %s" with d.Encoded() as the expected value and
target.Value as the got/actual value so the message correctly reports expected
(d.Encoded()) vs actual (target.Value).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@bindings/go/helm/digest/digest.go`:
- Around line 72-78: The ProcessResourceDigest function lacks a nil check for
the resource parameter and may dereference resource.Access; update
ProcessResourceDigest to validate that the incoming resource (type
*runtime.Resource) is non-nil (and optionally that resource.Access is non-nil)
before using it, and return a descriptive error (wrap with fmt.Errorf) when
resource is nil so callers get a proper error instead of a panic; reference the
ProcessResourceDigest function and the resource.Access usage to locate where to
add the check.

---

Nitpick comments:
In `@bindings/go/helm/digest/digest_test.go`:
- Around line 260-277: The integration test TestProcessResourceDigest_RealRepo
currently asserts a fixed digest value which can break if the external Grafana
chart is republished; update the test to avoid asserting the exact digest string
and instead verify that ProcessResourceDigest (on digest.NewDigestProcessor)
returns a non-nil result with result.Digest populated and that
result.Digest.HashAlgorithm and result.Digest.NormalisationAlgorithm are
non-empty (or match expected algorithm names if stable), and add a comment above
TestProcessResourceDigest_RealRepo explaining the test depends on an external
repo and may be brittle in CI; alternatively mark it as an
external-only/integration test by skipping in CI environments.
- Around line 1-16: Add test coverage for the OCI registry code path by creating
a new test in digest_test.go (e.g., TestProcessResourceDigest_OCI) that mirrors
TestProcessResourceDigest_RealRepo but targets an oci:// reference; either mock
an OCI registry endpoint or use a real OCI repo setup and resolve via the digest
package's resolver/ProcessResourceDigest logic to assert correct digest
resolution and error handling. Ensure the test imports/uses the same helpers and
runtime setup as TestProcessResourceDigest_RealRepo, exercises the oci:// URL
path, and asserts expected digest values or failure modes using require/assert.

In `@bindings/go/helm/digest/digest.go`:
- Around line 274-276: The error message in the comparison using fmt.Errorf has
reversed semantics: when target.Value != d.Encoded() the resolved digest
(d.Encoded()) is what we expect, and target.Value is the current/actual value;
update the fmt.Errorf call (the one comparing target.Value and d.Encoded()) so
the format arguments are swapped and read "expected %s, got %s" with d.Encoded()
as the expected value and target.Value as the got/actual value so the message
correctly reports expected (d.Encoded()) vs actual (target.Value).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 388897a7-0ca9-4034-ba04-d84fea56c686

📥 Commits

Reviewing files that changed from the base of the PR and between 220c7f9 and abe1977.

📒 Files selected for processing (3)
  • bindings/go/helm/digest/digest.go
  • bindings/go/helm/digest/digest_test.go
  • bindings/go/helm/internal/download/download.go

Comment thread bindings/go/helm/digest/digest.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/feature new feature, enhancement, improvement, extension size/l Large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants