From 00a941b04437179d22244980a8f08c5733b7cef8 Mon Sep 17 00:00:00 2001 From: Ryan VanGundy <85766511+rmvangun@users.noreply.github.com> Date: Tue, 2 Dec 2025 08:50:26 -0500 Subject: [PATCH] fix(blueprint): Set correct metadata on initialized blueprint The default metadata when creating a new blueprint with `windsor init` didn't properly set a unique name and description. Now these reflect the context being initialized. Signed-off-by: Ryan VanGundy <85766511+rmvangun@users.noreply.github.com> --- pkg/composer/blueprint/blueprint_handler.go | 12 ++ .../blueprint_handler_private_test.go | 126 ++++++++++++++++++ 2 files changed, 138 insertions(+) diff --git a/pkg/composer/blueprint/blueprint_handler.go b/pkg/composer/blueprint/blueprint_handler.go index 550c7ddfb..ca05afd94 100644 --- a/pkg/composer/blueprint/blueprint_handler.go +++ b/pkg/composer/blueprint/blueprint_handler.go @@ -552,6 +552,12 @@ func (b *BaseBlueprintHandler) processOCIArtifact(templateData map[string][]byte return err } + contextName := b.runtime.ContextName + if contextName != "" { + b.blueprint.Metadata.Name = contextName + b.blueprint.Metadata.Description = fmt.Sprintf("Blueprint for %s context", contextName) + } + ociInfo, _ := artifact.ParseOCIReference(blueprintRef) if ociInfo != nil { b.setOCISource(ociInfo) @@ -1363,6 +1369,12 @@ func (b *BaseBlueprintHandler) processLocalArtifact(templateData map[string][]by return err } + contextName := b.runtime.ContextName + if contextName != "" { + b.blueprint.Metadata.Name = contextName + b.blueprint.Metadata.Description = fmt.Sprintf("Blueprint for %s context", contextName) + } + fileSource := blueprintv1alpha1.Source{ Name: metadataName, Url: "file://" + relativeArtifactPath, diff --git a/pkg/composer/blueprint/blueprint_handler_private_test.go b/pkg/composer/blueprint/blueprint_handler_private_test.go index a5096b9ce..1850b2495 100644 --- a/pkg/composer/blueprint/blueprint_handler_private_test.go +++ b/pkg/composer/blueprint/blueprint_handler_private_test.go @@ -5371,6 +5371,69 @@ metadata: t.Errorf("Expected error about processing features, got: %v", err) } }) + + t.Run("SetsMetadataNameAndDescriptionFromContextName", func(t *testing.T) { + handler, mocks := setup(t) + handler.runtime.ContextName = "production" + mocks.ConfigHandler.(*config.MockConfigHandler).GetContextValuesFunc = func() (map[string]any, error) { + return map[string]any{"test": "value"}, nil + } + mocks.ConfigHandler.(*config.MockConfigHandler).LoadSchemaFromBytesFunc = func(data []byte) error { + return nil + } + + templateData := map[string][]byte{ + "_template/blueprint.yaml": []byte(`kind: Blueprint +apiVersion: blueprints.windsorcli.dev/v1alpha1 +metadata: + name: template + description: Base blueprint template for core services`), + } + + err := handler.processOCIArtifact(templateData, "oci://ghcr.io/test/repo:latest") + + if err != nil { + t.Fatalf("Expected no error, got: %v", err) + } + if handler.blueprint.Metadata.Name != "production" { + t.Errorf("Expected metadata name to be 'production', got: %s", handler.blueprint.Metadata.Name) + } + expectedDescription := "Blueprint for production context" + if handler.blueprint.Metadata.Description != expectedDescription { + t.Errorf("Expected metadata description to be '%s', got: %s", expectedDescription, handler.blueprint.Metadata.Description) + } + }) + + t.Run("DoesNotSetMetadataWhenContextNameIsEmpty", func(t *testing.T) { + handler, mocks := setup(t) + handler.runtime.ContextName = "" + mocks.ConfigHandler.(*config.MockConfigHandler).GetContextValuesFunc = func() (map[string]any, error) { + return map[string]any{"test": "value"}, nil + } + mocks.ConfigHandler.(*config.MockConfigHandler).LoadSchemaFromBytesFunc = func(data []byte) error { + return nil + } + + templateData := map[string][]byte{ + "_template/blueprint.yaml": []byte(`kind: Blueprint +apiVersion: blueprints.windsorcli.dev/v1alpha1 +metadata: + name: template + description: Base blueprint template for core services`), + } + + err := handler.processOCIArtifact(templateData, "oci://ghcr.io/test/repo:latest") + + if err != nil { + t.Fatalf("Expected no error, got: %v", err) + } + if handler.blueprint.Metadata.Name != "template" { + t.Errorf("Expected metadata name to remain 'template', got: %s", handler.blueprint.Metadata.Name) + } + if handler.blueprint.Metadata.Description != "Base blueprint template for core services" { + t.Errorf("Expected metadata description to remain unchanged, got: %s", handler.blueprint.Metadata.Description) + } + }) } func TestBaseBlueprintHandler_pullOCISources(t *testing.T) { @@ -5685,6 +5748,69 @@ metadata: t.Errorf("Expected kustomization source to remain 'existing-source', got: %s", handler.blueprint.Kustomizations[0].Source) } }) + + t.Run("SetsMetadataNameAndDescriptionFromContextName", func(t *testing.T) { + handler, mocks := setup(t) + handler.runtime.ContextName = "staging" + mocks.ConfigHandler.(*config.MockConfigHandler).GetContextValuesFunc = func() (map[string]any, error) { + return map[string]any{"test": "value"}, nil + } + mocks.ConfigHandler.(*config.MockConfigHandler).LoadSchemaFromBytesFunc = func(data []byte) error { + return nil + } + + templateData := map[string][]byte{ + "_template/blueprint.yaml": []byte(`kind: Blueprint +apiVersion: blueprints.windsorcli.dev/v1alpha1 +metadata: + name: template + description: Base blueprint template for core services`), + } + + err := handler.processLocalArtifact(templateData, "../test.tar.gz") + + if err != nil { + t.Fatalf("Expected no error, got: %v", err) + } + if handler.blueprint.Metadata.Name != "staging" { + t.Errorf("Expected metadata name to be 'staging', got: %s", handler.blueprint.Metadata.Name) + } + expectedDescription := "Blueprint for staging context" + if handler.blueprint.Metadata.Description != expectedDescription { + t.Errorf("Expected metadata description to be '%s', got: %s", expectedDescription, handler.blueprint.Metadata.Description) + } + }) + + t.Run("DoesNotSetMetadataWhenContextNameIsEmpty", func(t *testing.T) { + handler, mocks := setup(t) + handler.runtime.ContextName = "" + mocks.ConfigHandler.(*config.MockConfigHandler).GetContextValuesFunc = func() (map[string]any, error) { + return map[string]any{"test": "value"}, nil + } + mocks.ConfigHandler.(*config.MockConfigHandler).LoadSchemaFromBytesFunc = func(data []byte) error { + return nil + } + + templateData := map[string][]byte{ + "_template/blueprint.yaml": []byte(`kind: Blueprint +apiVersion: blueprints.windsorcli.dev/v1alpha1 +metadata: + name: template + description: Base blueprint template for core services`), + } + + err := handler.processLocalArtifact(templateData, "../test.tar.gz") + + if err != nil { + t.Fatalf("Expected no error, got: %v", err) + } + if handler.blueprint.Metadata.Name != "template" { + t.Errorf("Expected metadata name to remain 'template', got: %s", handler.blueprint.Metadata.Name) + } + if handler.blueprint.Metadata.Description != "Base blueprint template for core services" { + t.Errorf("Expected metadata description to remain unchanged, got: %s", handler.blueprint.Metadata.Description) + } + }) } func TestBaseBlueprintHandler_getSourceRef(t *testing.T) {