From 2a1f56a183c6de334665288b7781649ce946dc54 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Wed, 29 Oct 2025 16:43:11 +0100 Subject: [PATCH 1/4] update default config Signed-off-by: Sylwester Piskozub --- app/controlplane/pkg/biz/workflow.go | 13 +++++- app/controlplane/pkg/biz/workflowcontract.go | 49 ++++++++++++++++---- 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/app/controlplane/pkg/biz/workflow.go b/app/controlplane/pkg/biz/workflow.go index 05add7665..3942bbca9 100644 --- a/app/controlplane/pkg/biz/workflow.go +++ b/app/controlplane/pkg/biz/workflow.go @@ -133,8 +133,17 @@ func (uc *WorkflowUseCase) Create(ctx context.Context, opts *WorkflowCreateOpts) return nil, errors.New("organization ID is required") } - // Set the empty contract by default - opts.DetectedContract = EmptyDefaultContract + // Set the default contract with - name + contractName := opts.ContractName + if contractName == "" { + contractName = fmt.Sprintf("%s-%s", opts.Project, opts.Name) + } + + defaultContract, err := createDefaultContract(contractName) + if err != nil { + return nil, fmt.Errorf("failed to create default contract: %w", err) + } + opts.DetectedContract = defaultContract // Take the raw contract bytes and identify the format and validate it if opts.ContractBytes != nil { diff --git a/app/controlplane/pkg/biz/workflowcontract.go b/app/controlplane/pkg/biz/workflowcontract.go index 8386bfef7..622ddb5d7 100644 --- a/app/controlplane/pkg/biz/workflowcontract.go +++ b/app/controlplane/pkg/biz/workflowcontract.go @@ -21,6 +21,7 @@ import ( "fmt" "time" + "github.com/bufbuild/protoyaml-go" "github.com/chainloop-dev/chainloop/app/controlplane/pkg/auditor/events" schemav1 "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" @@ -209,9 +210,37 @@ type WorkflowContractCreateOpts struct { AddUniquePrefix bool } -// EmptyDefaultContract is the default contract that will be created if no contract is provided -var EmptyDefaultContract = &Contract{ - Raw: []byte("schemaVersion: v1"), Format: unmarshal.RawFormatYAML, +// emptyDefaultSchemaV2 is the default contract that will be created if no contract is provided +var emptyDefaultSchemaV2 = &schemav1.CraftingSchemaV2{ + ApiVersion: "chainloop.dev/v1", + Kind: "Contract", + Metadata: &schemav1.Metadata{Name: "default"}, + Spec: &schemav1.CraftingSchemaV2Spec{}, +} + +// createDefaultContract creates a new default contract with the specified name +func createDefaultContract(name string) (*Contract, error) { + defaultSchema := &schemav1.CraftingSchemaV2{ + ApiVersion: emptyDefaultSchemaV2.ApiVersion, + Kind: emptyDefaultSchemaV2.Kind, + Metadata: &schemav1.Metadata{Name: name}, + Spec: &schemav1.CraftingSchemaV2Spec{}, + } + + // Marshal to YAML using protoyaml + rawYAML, err := protoyaml.Marshal(defaultSchema) + if err != nil { + return nil, fmt.Errorf("failed to marshal default contract to YAML: %w", err) + } + + // Convert to v1 for backward compatibility with old CLIs + v1Schema := defaultSchema.ToV1() + return &Contract{ + Raw: rawYAML, + Format: unmarshal.RawFormatYAML, + Schema: v1Schema, + Schemav2: defaultSchema, + }, nil } func (uc *WorkflowContractUseCase) Create(ctx context.Context, opts *WorkflowContractCreateOpts) (*WorkflowContract, error) { @@ -232,16 +261,20 @@ func (uc *WorkflowContractUseCase) Create(ctx context.Context, opts *WorkflowCon return nil, NewErrValidation(err) } - // Create an empty contract by default - contract := EmptyDefaultContract - - // or load it if provided + var contract *Contract if len(opts.RawSchema) > 0 { + // Load the provided contract c, err := identifyUnMarshalAndValidateRawContract(opts.RawSchema) if err != nil { return nil, fmt.Errorf("failed to load contract: %w", err) } - + contract = c + } else { + // Use default contract with the user-provided name + c, err := createDefaultContract(opts.Name) + if err != nil { + return nil, fmt.Errorf("failed to create default contract: %w", err) + } contract = c } From d365b6541b65b8221ce534e9760d66eff0a61768 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Wed, 29 Oct 2025 17:03:24 +0100 Subject: [PATCH 2/4] fix tests Signed-off-by: Sylwester Piskozub --- app/controlplane/pkg/biz/workflow.go | 2 +- app/controlplane/pkg/biz/workflowcontract.go | 18 +++++------------- .../biz/workflowcontract_integration_test.go | 6 ++++-- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/app/controlplane/pkg/biz/workflow.go b/app/controlplane/pkg/biz/workflow.go index 3942bbca9..9f9c38b6e 100644 --- a/app/controlplane/pkg/biz/workflow.go +++ b/app/controlplane/pkg/biz/workflow.go @@ -139,7 +139,7 @@ func (uc *WorkflowUseCase) Create(ctx context.Context, opts *WorkflowCreateOpts) contractName = fmt.Sprintf("%s-%s", opts.Project, opts.Name) } - defaultContract, err := createDefaultContract(contractName) + defaultContract, err := CreateDefaultContract(contractName) if err != nil { return nil, fmt.Errorf("failed to create default contract: %w", err) } diff --git a/app/controlplane/pkg/biz/workflowcontract.go b/app/controlplane/pkg/biz/workflowcontract.go index 622ddb5d7..7508fd244 100644 --- a/app/controlplane/pkg/biz/workflowcontract.go +++ b/app/controlplane/pkg/biz/workflowcontract.go @@ -210,19 +210,11 @@ type WorkflowContractCreateOpts struct { AddUniquePrefix bool } -// emptyDefaultSchemaV2 is the default contract that will be created if no contract is provided -var emptyDefaultSchemaV2 = &schemav1.CraftingSchemaV2{ - ApiVersion: "chainloop.dev/v1", - Kind: "Contract", - Metadata: &schemav1.Metadata{Name: "default"}, - Spec: &schemav1.CraftingSchemaV2Spec{}, -} - -// createDefaultContract creates a new default contract with the specified name -func createDefaultContract(name string) (*Contract, error) { +// CreateDefaultContract creates a new default contract with the specified name +func CreateDefaultContract(name string) (*Contract, error) { defaultSchema := &schemav1.CraftingSchemaV2{ - ApiVersion: emptyDefaultSchemaV2.ApiVersion, - Kind: emptyDefaultSchemaV2.Kind, + ApiVersion: "chainloop.dev/v1", + Kind: "Contract", Metadata: &schemav1.Metadata{Name: name}, Spec: &schemav1.CraftingSchemaV2Spec{}, } @@ -271,7 +263,7 @@ func (uc *WorkflowContractUseCase) Create(ctx context.Context, opts *WorkflowCon contract = c } else { // Use default contract with the user-provided name - c, err := createDefaultContract(opts.Name) + c, err := CreateDefaultContract(opts.Name) if err != nil { return nil, fmt.Errorf("failed to create default contract: %w", err) } diff --git a/app/controlplane/pkg/biz/workflowcontract_integration_test.go b/app/controlplane/pkg/biz/workflowcontract_integration_test.go index 837690afa..80bc2be82 100644 --- a/app/controlplane/pkg/biz/workflowcontract_integration_test.go +++ b/app/controlplane/pkg/biz/workflowcontract_integration_test.go @@ -320,8 +320,10 @@ func (s *workflowContractIntegrationTestSuite) TestCreateWithCustomContract() { require.NoError(s.T(), err) contractWithVersion, err := s.WorkflowContract.Describe(ctx, s.org.ID, contract.ID.String(), 1) require.NoError(s.T(), err) - s.Equal(biz.EmptyDefaultContract.Format, unmarshal.RawFormatYAML) - s.Equal(biz.EmptyDefaultContract.Raw, contractWithVersion.Version.Schema.Raw) + c, err := biz.CreateDefaultContract("empty") + require.NoError(s.T(), err) + s.Equal(c.Format, unmarshal.RawFormatYAML) + s.Equal(c.Raw, contractWithVersion.Version.Schema.Raw) s.NotNil(contractWithVersion.Version.Schema.Schema) }) } From 8f60e8b3c72eab141f938fbfbb7c7684d9a61dca Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Wed, 29 Oct 2025 17:29:21 +0100 Subject: [PATCH 3/4] fix condition Signed-off-by: Sylwester Piskozub --- app/controlplane/pkg/biz/workflow.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/controlplane/pkg/biz/workflow.go b/app/controlplane/pkg/biz/workflow.go index 9f9c38b6e..ea61d991b 100644 --- a/app/controlplane/pkg/biz/workflow.go +++ b/app/controlplane/pkg/biz/workflow.go @@ -133,11 +133,7 @@ func (uc *WorkflowUseCase) Create(ctx context.Context, opts *WorkflowCreateOpts) return nil, errors.New("organization ID is required") } - // Set the default contract with - name - contractName := opts.ContractName - if contractName == "" { - contractName = fmt.Sprintf("%s-%s", opts.Project, opts.Name) - } + contractName := fmt.Sprintf("%s-%s", opts.Project, opts.Name) defaultContract, err := CreateDefaultContract(contractName) if err != nil { From 05992fc2d6b95225b9f1317b9ac842f6a070a54e Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Thu, 30 Oct 2025 09:00:14 +0100 Subject: [PATCH 4/4] dont expose craft default contract function Signed-off-by: Sylwester Piskozub --- app/controlplane/pkg/biz/workflow.go | 2 +- app/controlplane/pkg/biz/workflowcontract.go | 6 +++--- .../pkg/biz/workflowcontract_integration_test.go | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/controlplane/pkg/biz/workflow.go b/app/controlplane/pkg/biz/workflow.go index ea61d991b..149b6d93c 100644 --- a/app/controlplane/pkg/biz/workflow.go +++ b/app/controlplane/pkg/biz/workflow.go @@ -135,7 +135,7 @@ func (uc *WorkflowUseCase) Create(ctx context.Context, opts *WorkflowCreateOpts) contractName := fmt.Sprintf("%s-%s", opts.Project, opts.Name) - defaultContract, err := CreateDefaultContract(contractName) + defaultContract, err := createDefaultContract(contractName) if err != nil { return nil, fmt.Errorf("failed to create default contract: %w", err) } diff --git a/app/controlplane/pkg/biz/workflowcontract.go b/app/controlplane/pkg/biz/workflowcontract.go index 7508fd244..ce1792fd5 100644 --- a/app/controlplane/pkg/biz/workflowcontract.go +++ b/app/controlplane/pkg/biz/workflowcontract.go @@ -210,8 +210,8 @@ type WorkflowContractCreateOpts struct { AddUniquePrefix bool } -// CreateDefaultContract creates a new default contract with the specified name -func CreateDefaultContract(name string) (*Contract, error) { +// createDefaultContract creates a new default contract with the specified name +func createDefaultContract(name string) (*Contract, error) { defaultSchema := &schemav1.CraftingSchemaV2{ ApiVersion: "chainloop.dev/v1", Kind: "Contract", @@ -263,7 +263,7 @@ func (uc *WorkflowContractUseCase) Create(ctx context.Context, opts *WorkflowCon contract = c } else { // Use default contract with the user-provided name - c, err := CreateDefaultContract(opts.Name) + c, err := createDefaultContract(opts.Name) if err != nil { return nil, fmt.Errorf("failed to create default contract: %w", err) } diff --git a/app/controlplane/pkg/biz/workflowcontract_integration_test.go b/app/controlplane/pkg/biz/workflowcontract_integration_test.go index 80bc2be82..3992ddf51 100644 --- a/app/controlplane/pkg/biz/workflowcontract_integration_test.go +++ b/app/controlplane/pkg/biz/workflowcontract_integration_test.go @@ -320,8 +320,7 @@ func (s *workflowContractIntegrationTestSuite) TestCreateWithCustomContract() { require.NoError(s.T(), err) contractWithVersion, err := s.WorkflowContract.Describe(ctx, s.org.ID, contract.ID.String(), 1) require.NoError(s.T(), err) - c, err := biz.CreateDefaultContract("empty") - require.NoError(s.T(), err) + c := contractWithVersion.Version.Schema s.Equal(c.Format, unmarshal.RawFormatYAML) s.Equal(c.Raw, contractWithVersion.Version.Schema.Raw) s.NotNil(contractWithVersion.Version.Schema.Schema)