From 68adc37655c4136b6538326d6a77eba8e4717b0a Mon Sep 17 00:00:00 2001 From: Wayne Starr Date: Tue, 2 Dec 2025 17:17:11 -0700 Subject: [PATCH 1/3] feat: implement import logic for Zarf Values Signed-off-by: Wayne Starr --- src/pkg/packager/load/import.go | 8 ++++++++ src/pkg/packager/load/import_test.go | 2 +- .../packager/load/testdata/import/variables/expected.yaml | 6 ++++++ .../load/testdata/import/variables/import/zarf.yaml | 4 ++++ .../load/testdata/import/variables/secondImport/zarf.yaml | 4 ++++ src/pkg/packager/load/testdata/import/variables/zarf.yaml | 6 ++++++ 6 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/pkg/packager/load/import.go b/src/pkg/packager/load/import.go index 0b24d084e2..cea0236532 100644 --- a/src/pkg/packager/load/import.go +++ b/src/pkg/packager/load/import.go @@ -10,6 +10,7 @@ import ( "fmt" "os" "path/filepath" + "slices" "strings" "time" @@ -55,6 +56,7 @@ func resolveImports(ctx context.Context, pkg v1alpha1.ZarfPackage, packagePath, "importStack", len(importStack), ) + var valuesFiles []string variables := pkg.Variables constants := pkg.Constants components := []v1alpha1.ZarfComponent{} @@ -156,8 +158,14 @@ func resolveImports(ctx context.Context, pkg v1alpha1.ZarfPackage, packagePath, components = append(components, composed) variables = append(variables, importedPkg.Variables...) constants = append(constants, importedPkg.Constants...) + for _, v := range importedPkg.Values.Files { + valuesFiles = append(valuesFiles, makePathRelativeTo(v, importPath)) + } } + valuesFiles = append(valuesFiles, pkg.Values.Files...) + valuesFiles = slices.Compact(valuesFiles) + pkg.Values.Files = valuesFiles pkg.Components = components varMap := map[string]bool{} diff --git a/src/pkg/packager/load/import_test.go b/src/pkg/packager/load/import_test.go index 713f898b76..cde0f2934d 100644 --- a/src/pkg/packager/load/import_test.go +++ b/src/pkg/packager/load/import_test.go @@ -48,7 +48,7 @@ func TestResolveImports(t *testing.T) { path: "./testdata/import/import-each-other", }, { - name: "variables and constants are resolved correctly", + name: "variables, constants, and values are resolved correctly", path: "./testdata/import/variables", }, { diff --git a/src/pkg/packager/load/testdata/import/variables/expected.yaml b/src/pkg/packager/load/testdata/import/variables/expected.yaml index d169e9e6b8..d39d312aa2 100644 --- a/src/pkg/packager/load/testdata/import/variables/expected.yaml +++ b/src/pkg/packager/load/testdata/import/variables/expected.yaml @@ -13,6 +13,12 @@ variables: default: "default from child" - name: SECONDARY_CHILD_VAR default: "default from child in component imported later" +values: + files: + - child-values.yaml + - secondary-child-values.yaml + - parent-values.yaml + schema: "parent-values.schema.json" components: - name: first-imported-component required: true diff --git a/src/pkg/packager/load/testdata/import/variables/import/zarf.yaml b/src/pkg/packager/load/testdata/import/variables/import/zarf.yaml index 4b7867a283..b267100eff 100644 --- a/src/pkg/packager/load/testdata/import/variables/import/zarf.yaml +++ b/src/pkg/packager/load/testdata/import/variables/import/zarf.yaml @@ -11,6 +11,10 @@ variables: default: "default from child" - name: CHILD_VAR default: "default from child" +values: + files: + - ../child-values.yaml + schema: "child-values.schema.json" components: - name: first-imported-component required: true diff --git a/src/pkg/packager/load/testdata/import/variables/secondImport/zarf.yaml b/src/pkg/packager/load/testdata/import/variables/secondImport/zarf.yaml index 7ce2250a59..7282c1a58c 100644 --- a/src/pkg/packager/load/testdata/import/variables/secondImport/zarf.yaml +++ b/src/pkg/packager/load/testdata/import/variables/secondImport/zarf.yaml @@ -13,6 +13,10 @@ variables: default: "default from child in component imported later" - name: SECONDARY_CHILD_VAR default: "default from child in component imported later" +values: + files: + - ../secondary-child-values.yaml + schema: "secondary-child-values.schema.json" components: - name: component-from-different-package required: true diff --git a/src/pkg/packager/load/testdata/import/variables/zarf.yaml b/src/pkg/packager/load/testdata/import/variables/zarf.yaml index 5eac4c1c93..00c5535931 100644 --- a/src/pkg/packager/load/testdata/import/variables/zarf.yaml +++ b/src/pkg/packager/load/testdata/import/variables/zarf.yaml @@ -7,11 +7,17 @@ constants: variables: - name: PARENT_VAR default: "default from parent" +values: + files: + - parent-values.yaml + schema: "parent-values.schema.json" + components: - name: first-imported-component required: true import: path: import + - name: same-package-imported-again required: true import: From e37ba46b628a17b1faf145183fb7feae88a607c1 Mon Sep 17 00:00:00 2001 From: Wayne Starr Date: Tue, 2 Dec 2025 17:38:35 -0700 Subject: [PATCH 2/3] add docs Signed-off-by: Wayne Starr --- site/src/content/docs/ref/components.mdx | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/site/src/content/docs/ref/components.mdx b/site/src/content/docs/ref/components.mdx index d5a62cf437..9bc967f07e 100644 --- a/site/src/content/docs/ref/components.mdx +++ b/site/src/content/docs/ref/components.mdx @@ -255,10 +255,18 @@ When merging components together Zarf will adopt the following strategies depend | Kind | Key(s) | Description | |----------------------------|----------------------------------------|-------------| -| Component Behavior | `name`, `group`, `default`, `required` | These keys control how Zarf interacts with a given component and will *always* take the value of the overriding component | -| Component Description | `description` | This key will only take the value of the overriding component if it is not empty | -| Un'name'd Primitive Arrays | `actions`, `dataInjections`, `files`, `images`, `repos` | These keys will append the overriding component's version of the array to the end of the base component's array | -| 'name'd Primitive Arrays | `charts`, `manifests` | For any given element in the overriding component, if the element matches based on `name` then its values will be merged with the base element of the same `name`. If not then the element will be appended to the end of the array | +| Component Behavior | `name`, `group`, `default`, `required` | These keys control how Zarf interacts with a given component and will *always* take the value of the importing component | +| Component Description | `description` | This key will only take the value of the importing component if it is not empty, otherwise it will take the value of the imported component | +| Un'name'd Primitive Arrays | `actions`, `dataInjections`, `files`, `images`, `repos` | These keys will append the importing component's array to the end of the imported component's array | +| 'name'd Primitive Arrays | `charts`, `manifests` | For any given element in the importing component, if the element matches based on `name` then its values will be merged with the imported element of the same `name`. If not, then the element will be appended to the end of the array | + +Some package level fields from imported components will also be merged with the importing package. These fields will be processed from the first component to the last component in a Zarf package definition. + +| Kind | Field(s) | Description | +|----------------------------|--------------------------|-------------| +| 'name'd Globals | `constants`, `variables` | These fields will match on `name` building up a map as components are processed (starting with the importing package definition). Any names that already exist will be skipped so the parent or an earlier component import will take precedence. | +| Un'name'd Primitive Arrays | `files.values` | The importing package definition's array will be appended to the end of the array from the imported component's package definition. Elements will be reappended regardless of whether they already exist in the array (since merge order impacts the final values). | +| Global Behavior | `files.schema` | This field will always take the value of the importing component's package definition (even if it is empty) | ### Health Checks From a2d4f095fb0fe244461812a57b3d7d463952c139 Mon Sep 17 00:00:00 2001 From: Wayne Starr Date: Thu, 11 Dec 2025 15:39:11 -0700 Subject: [PATCH 3/3] Update site/src/content/docs/ref/components.mdx Co-authored-by: Austin Abro <37223396+AustinAbro321@users.noreply.github.com> Signed-off-by: Wayne Starr --- site/src/content/docs/ref/components.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/src/content/docs/ref/components.mdx b/site/src/content/docs/ref/components.mdx index 9bc967f07e..b0b2e7273d 100644 --- a/site/src/content/docs/ref/components.mdx +++ b/site/src/content/docs/ref/components.mdx @@ -265,8 +265,8 @@ Some package level fields from imported components will also be merged with the | Kind | Field(s) | Description | |----------------------------|--------------------------|-------------| | 'name'd Globals | `constants`, `variables` | These fields will match on `name` building up a map as components are processed (starting with the importing package definition). Any names that already exist will be skipped so the parent or an earlier component import will take precedence. | -| Un'name'd Primitive Arrays | `files.values` | The importing package definition's array will be appended to the end of the array from the imported component's package definition. Elements will be reappended regardless of whether they already exist in the array (since merge order impacts the final values). | -| Global Behavior | `files.schema` | This field will always take the value of the importing component's package definition (even if it is empty) | +| Un'name'd Primitive Arrays | `values.files` | The importing package definition's array will be appended to the end of the array from the imported component's package definition. Elements will be reappended regardless of whether they already exist in the array (since merge order impacts the final values). | +| Global Behavior | `values.schema` | This field will always keep the value of the importing component's package definition (even if it is empty) | ### Health Checks