Evaluate bundle def against interface#3639
Conversation
Add EvaluateInterfaceMatch (pkg/cnab) and composeRequiredInterface (pkg/porter): binary, mode-aware match of a dependency's outputs/ params/creds against its declared bundle interface (document, reference, or ID-only). Gated behind FlagDependenciesV2; with the flag off, behavior is unchanged from before. Wire into findExistingInstallation so a v2 dependency declaring an interface can reuse an existing installation instead of always pulling a new bundle instance. Reject interface.reference + interface.document both set on one dependency (manifest validation + a runtime sentinel error), per BundleInterface's own doc comment that these are mutually exclusive. Closes getporter#2626 Signed-off-by: Kim Christensen <[email protected]>
There was a problem hiding this comment.
Pull request overview
Adds the missing “evaluate bundle def against interface” primitive (PEP003 / #2626) and uses it to allow v2 dependencies that declare a bundle interface (interface.document / interface.reference / ID-only) to reuse an existing installation when it satisfies the interface’s required outputs (in the “existing installation” resolution context from #2686), gated behind the dependencies-v2 experimental flag. Also enforces that interface.reference and interface.document are mutually exclusive at both manifest validation time and graph resolution time.
Changes:
- Introduce a CNAB-level interface matching primitive (
EvaluateInterfaceMatch) with mode support (outputs-only vs full match). - Compose required interface requirements for v2 dependencies and integrate those requirements into the existing-installation reuse path (flag-gated).
- Add/adjust unit + integration coverage and test fixtures for
interface.document,interface.reference, and negative fallback-to-pull scenarios; enforce mutually-exclusive interface fields in manifests and fixtures.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/integration/inspect_bundle_interface_test.go | New integration tests validating reuse/fallback behavior for interface.document and interface.reference. |
| pkg/porter/dependency_interface_resolver.go | New logic to compose required interface requirements for a dependency (including pulling an interface reference bundle). |
| pkg/porter/dependency_interface_resolver_test.go | Unit tests for composeRequiredInterface behavior and error cases. |
| pkg/porter/dependency_installation_resolver.go | Switch required-output checking to use the shared interface match evaluator (outputs-only mode). |
| pkg/porter/dependency_graph_test.go | Extend existing-installation graph tests to cover interface-enabled behavior under the experimental flag. |
| pkg/porter/dependency_graph_builder.go | Wire interface requirement composition into existing-installation reuse (flag-gated) and handle sentinel error. |
| pkg/manifest/manifest.go | Reject dependencies that set both bundle interface reference and document during manifest validation. |
| pkg/manifest/manifest_test.go | Tests for new manifest validation rule (reference XOR document). |
| pkg/cnab/interface_match.go | New interface matching primitive and supporting types (candidate/requirement/mode/result). |
| pkg/cnab/interface_match_test.go | Tests for interface matching behavior in outputs-only and full modes. |
| pkg/cnab/extensions/dependencies/v2/types.go | Add helpers to detect empty interface documents and extract sorted capability names. |
| pkg/cnab/extensions/dependencies/v2/types_test.go | Tests for new DependencyInterfaceDocument helpers. |
| pkg/cnab/config-adapter/testdata/porter-with-depsv2.yaml | Adjust fixture to avoid declaring both interface reference and document. |
| pkg/cnab/config-adapter/adapter_test.go | Update adapter test expectation to match updated fixture/interface shape. |
| build/testdata/bundles/wordpressv2-interface/porter.yaml | New bundle fixture declaring interface.document on a v2 dependency. |
| build/testdata/bundles/wordpressv2-interface/helpers.sh | Helper script for wordpressv2-interface fixture. |
| build/testdata/bundles/wordpressv2-interface-reference/porter.yaml | New bundle fixture declaring interface.reference on a v2 dependency. |
| build/testdata/bundles/wordpressv2-interface-reference/helpers.sh | Helper script for wordpressv2-interface-reference fixture. |
| build/testdata/bundles/wordpressv2-interface-missing/porter.yaml | New negative-case fixture requiring an output mysql won’t provide (forces fallback-to-pull). |
| build/testdata/bundles/wordpressv2-interface-missing/helpers.sh | Helper script for wordpressv2-interface-missing fixture. |
| build/testdata/bundles/mysql-interface/porter.yaml | New “interface-only” bundle fixture to back interface.reference tests. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
unionSorted returned a unchanged when b was empty, skipping dedup/sort despite the doc comment. Now always merges, only short-circuiting to nil when both inputs are empty. Signed-off-by: Kim Christensen <[email protected]>
Improves readability in TestEvaluateInterfaceMatch's table-driven subtests using t.Parallel(). Signed-off-by: Kim Christensen <[email protected]>
What does this change
Adds the missing evaluate primitive from PEP003: given a v2 dependency's declared bundle interface (
interface.document,interface.reference, or ID-only) and a candidate bundle/installation, decide whether it satisfies the interface. The match is binary (satisfies / doesn't) and mode-aware (outputs-only vs outputs+params+creds), matching how #2686 describes the same check being used in different resolution contexts.Wires this into the existing-installation reuse path added in #3631: a v2 dependency that declares a bundle interface can now reuse an already-installed installation instead of always pulling a new bundle, as long as the interface's required outputs are present. Gated behind the
dependencies-v2experimental flag; with the flag disabled, behavior is unchanged frommain.Also rejects a dependency declaring both
interface.referenceandinterface.document(previously silently allowed) —BundleInterface's own doc comment already said these are mutually exclusive; this enforces it atporter.yamlvalidation time and again at resolution time.Example:
porter inspect --show-dependencieson a bundle whose dependency declaresinterface: {document: {outputs: [...]}}now resolves to an existing installation when it has the required outputs, instead of always pulling.What issue does it fix
Closes #2626
Notes for the reviewer
interface.reference+interface.documentboth set is now a hard error (manifest validation + a runtime sentinel), not "reference wins". This caught an existing test fixture (porter-with-depsv2.yaml) that had both set at once; adjusted it to document-only.interface.document,interface.reference, and the falls-back-to-pull negative case.Checklist