Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions app/controlplane/pkg/biz/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,13 @@ 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
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 {
Expand Down
41 changes: 33 additions & 8 deletions app/controlplane/pkg/biz/workflowcontract.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -209,9 +210,29 @@ 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,
// 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",
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) {
Expand All @@ -232,16 +253,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
}

Expand Down
5 changes: 3 additions & 2 deletions app/controlplane/pkg/biz/workflowcontract_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,9 @@ 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 := contractWithVersion.Version.Schema
s.Equal(c.Format, unmarshal.RawFormatYAML)
s.Equal(c.Raw, contractWithVersion.Version.Schema.Raw)
s.NotNil(contractWithVersion.Version.Schema.Schema)
})
}
Expand Down
Loading