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
8 changes: 7 additions & 1 deletion app/cli/cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,13 @@ Supports multi-document YAML files. Each document must have a 'kind' field.`,
return err
}

logger.Info().Msgf("%d contracts applied", len(results))
for _, r := range results {
status := "applied"
if r.Unchanged {
status = "unchanged"
}
logger.Info().Msgf("%s/%s %s", r.Kind, r.Name, status)
}

return nil
},
Expand Down
8 changes: 6 additions & 2 deletions app/cli/cmd/workflow_contract_apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,16 @@ or update it if it already exists.`,
desc = &description
}

res, err := action.NewWorkflowContractApply(ActionOpts).Run(cmd.Context(), contractName, contractPath, desc, projectName)
res, unchanged, err := action.NewWorkflowContractApply(ActionOpts).Run(cmd.Context(), contractName, contractPath, desc, projectName)
if err != nil {
return err
}

logger.Info().Msg("Contract applied!")
status := "applied"
if unchanged {
status = "unchanged"
}
logger.Info().Msgf("Contract/%s %s", contractName, status)
return output.EncodeOutput(flagOutputFormat, res, contractItemTableOutput)
},
}
Expand Down
19 changes: 10 additions & 9 deletions app/cli/pkg/action/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ const (

// ApplyResult holds the outcome of a successfully applied resource document
type ApplyResult struct {
Kind string
Name string
Kind string
Name string
Unchanged bool
}

// YAMLDoc holds a parsed YAML document with its kind and raw bytes
Expand Down Expand Up @@ -67,16 +68,16 @@ func (a *Apply) Run(ctx context.Context, path string) ([]*ApplyResult, error) {
// Apply contracts
var results []*ApplyResult
for _, doc := range docs {
result := &ApplyResult{Kind: doc.Kind, Name: doc.Name}
switch doc.Kind {
case KindContract:
if err := ApplyContractFromRawData(ctx, a.cfg.CPConnection, doc.RawData); err != nil {
unchanged, err := ApplyContractFromRawData(ctx, a.cfg.CPConnection, doc.RawData)
if err != nil {
return results, fmt.Errorf("%s/%s: %w", doc.Kind, doc.Name, err)
}
results = append(results, &ApplyResult{Kind: doc.Kind, Name: doc.Name, Unchanged: unchanged})
default:
return results, fmt.Errorf("unsupported kind %q", doc.Kind)
}
results = append(results, result)
}

return results, nil
Expand Down Expand Up @@ -113,17 +114,17 @@ func ParseYAMLPath(path string) ([]*YAMLDoc, error) {
}

// ApplyContractFromRawData applies a single contract document using the gRPC client.
func ApplyContractFromRawData(ctx context.Context, conn *grpc.ClientConn, rawData []byte) error {
func ApplyContractFromRawData(ctx context.Context, conn *grpc.ClientConn, rawData []byte) (bool, error) {
client := pb.NewWorkflowContractServiceClient(conn)

_, err := client.Apply(ctx, &pb.WorkflowContractServiceApplyRequest{
resp, err := client.Apply(ctx, &pb.WorkflowContractServiceApplyRequest{
RawSchema: rawData,
})
if err != nil {
return fmt.Errorf("failed to apply contract: %w", err)
return false, fmt.Errorf("failed to apply contract: %w", err)
}

return nil
return resp.GetUnchanged(), nil
}

// CollectYAMLFiles returns YAML file paths from the given path.
Expand Down
18 changes: 11 additions & 7 deletions app/cli/pkg/action/workflow_contract_apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func NewWorkflowContractApply(cfg *ActionsOpts) *WorkflowContractApply {
return &WorkflowContractApply{cfg}
}

func (action *WorkflowContractApply) Run(ctx context.Context, contractName string, contractPath string, description *string, projectName string) (*WorkflowContractItem, error) {
func (action *WorkflowContractApply) Run(ctx context.Context, contractName string, contractPath string, description *string, projectName string) (*WorkflowContractItem, bool, error) {
client := pb.NewWorkflowContractServiceClient(action.cfg.CPConnection)

// Try to describe the specific contract first to determine if we should create or update
Expand All @@ -43,14 +43,16 @@ func (action *WorkflowContractApply) Run(ctx context.Context, contractName strin
raw, err := LoadFileOrURL(contractPath)
if err != nil {
action.cfg.Logger.Debug().Err(err).Msg("loading the contract")
return nil, err
return nil, false, err
}
rawContract = raw
}

_, err := client.Describe(ctx, describeReq)
describeRes, err := client.Describe(ctx, describeReq)
if err == nil {
// Contract exists, perform update
prevRevision := describeRes.Result.GetRevision().GetRevision()

updateReq := &pb.WorkflowContractServiceUpdateRequest{
Name: contractName,
Description: description,
Expand All @@ -59,10 +61,12 @@ func (action *WorkflowContractApply) Run(ctx context.Context, contractName strin

res, err := client.Update(ctx, updateReq)
if err != nil {
return nil, fmt.Errorf("failed to update existing contract '%s': %w", contractName, err)
return nil, false, fmt.Errorf("failed to update existing contract '%s': %w", contractName, err)
}

return pbWorkflowContractItemToAction(res.Result.Contract), nil
unchanged := prevRevision == res.Result.GetRevision().GetRevision()

return pbWorkflowContractItemToAction(res.Result.Contract), unchanged, nil
}

// Contract doesn't exist, perform create
Expand All @@ -80,8 +84,8 @@ func (action *WorkflowContractApply) Run(ctx context.Context, contractName strin

res, err := client.Create(ctx, createReq)
if err != nil {
return nil, fmt.Errorf("failed to create new contract '%s': %w", contractName, err)
return nil, false, fmt.Errorf("failed to create new contract '%s': %w", contractName, err)
}

return pbWorkflowContractItemToAction(res.Result), nil
return pbWorkflowContractItemToAction(res.Result), false, nil
}
18 changes: 14 additions & 4 deletions app/controlplane/api/controlplane/v1/workflow_contract.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions app/controlplane/api/controlplane/v1/workflow_contract.proto
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,6 @@ message WorkflowContractServiceApplyRequest {

message WorkflowContractServiceApplyResponse {
WorkflowContractItem result = 1;
// Whether the resource was unchanged
bool unchanged = 2;
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion app/controlplane/internal/service/workflowcontract.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,10 @@ func (s *WorkflowContractService) Apply(ctx context.Context, req *pb.WorkflowCon
return nil, handleUseCaseErr(err, s.log)
}

return &pb.WorkflowContractServiceApplyResponse{Result: bizWorkFlowContractToPb(schemaWithVersion.Contract)}, nil
return &pb.WorkflowContractServiceApplyResponse{
Result: bizWorkFlowContractToPb(schemaWithVersion.Contract),
Unchanged: schemaWithVersion.Unchanged,
}, nil
}

// Contract does not exist we create
Expand Down
10 changes: 7 additions & 3 deletions app/controlplane/pkg/biz/workflowcontract.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,9 @@ func (c *Contract) isV1Schema() bool {
}

type WorkflowContractWithVersion struct {
Contract *WorkflowContract
Version *WorkflowContractVersion
Contract *WorkflowContract
Version *WorkflowContractVersion
Unchanged bool
}

type WorkflowContractRepo interface {
Expand Down Expand Up @@ -425,13 +426,16 @@ func (uc *WorkflowContractUseCase) Update(ctx context.Context, orgID, name strin
}

// Check if the revisions have changed
if wfContractPreUpdate.LatestRevision != c.Version.Revision {
unchanged := wfContractPreUpdate.LatestRevision == c.Version.Revision
if !unchanged {
eventPayload.NewRevision = &c.Version.Revision
eventPayload.NewRevisionID = &c.Version.ID
}

uc.auditorUC.Dispatch(ctx, eventPayload, &orgUUID)

c.Unchanged = unchanged

return c, nil
}

Expand Down
Loading