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
4 changes: 3 additions & 1 deletion app/cli/internal/action/workflow_run_describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ func NewWorkflowRunDescribe(cfg *ActionsOpts) *WorkflowRunDescribe {

func (action *WorkflowRunDescribe) Run(runID string, verify bool, publicKey string) (*WorkflowRunItemFull, error) {
client := pb.NewWorkflowRunServiceClient(action.cfg.CPConnection)
resp, err := client.View(context.Background(), &pb.WorkflowRunServiceViewRequest{Id: runID})
resp, err := client.View(context.Background(), &pb.WorkflowRunServiceViewRequest{
Ref: &pb.WorkflowRunServiceViewRequest_Id{Id: runID},
})
if err != nil {
return nil, err
}
Expand Down
223 changes: 133 additions & 90 deletions app/controlplane/api/controlplane/v1/workflow_run.pb.go

Large diffs are not rendered by default.

63 changes: 58 additions & 5 deletions app/controlplane/api/controlplane/v1/workflow_run.pb.validate.go

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

8 changes: 7 additions & 1 deletion app/controlplane/api/controlplane/v1/workflow_run.proto
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,13 @@ message WorkflowRunServiceListResponse {
}

message WorkflowRunServiceViewRequest {
string id = 1 [(validate.rules).string.uuid = true];
// It can search by either ID or digest
oneof ref {
option (validate.required) = true;

string id = 1 [(validate.rules).string.uuid = true];
string digest = 2 [(validate.rules).string = {min_len: 1}];
}
}

message WorkflowRunServiceViewResponse {
Expand Down
26 changes: 21 additions & 5 deletions app/controlplane/api/gen/frontend/controlplane/v1/workflow_run.ts

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

26 changes: 26 additions & 0 deletions app/controlplane/internal/biz/mocks/WorkflowRunRepo.go

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

3 changes: 3 additions & 0 deletions app/controlplane/internal/biz/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ type WorkflowRepo interface {

type CreateOpts struct {
Name, OrgID, Project, Team, ContractID string
// Public means that the associated workflow runs, attestations and materials
// are reachable by other users, regardless of their organization
Public bool
}

type WorkflowUseCase struct {
Expand Down
10 changes: 9 additions & 1 deletion app/controlplane/internal/biz/workflowcontract.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package biz
import (
"context"
"errors"
"fmt"
"time"

schemav1 "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1"
Expand Down Expand Up @@ -152,7 +153,14 @@ func (uc *WorkflowContractUseCase) FindVersionByID(ctx context.Context, versionI
return nil, err
}

return uc.repo.FindVersionByID(ctx, versionUUID)
r, err := uc.repo.FindVersionByID(ctx, versionUUID)
if err != nil {
return nil, fmt.Errorf("finding contract version: %w", err)
} else if r == nil {
return nil, NewErrNotFound("contract version")
}

return r, nil
}

func (uc *WorkflowContractUseCase) Update(ctx context.Context, orgID, contractID, name string, schema *schemav1.CraftingSchema) (*WorkflowContractWithVersion, error) {
Expand Down
40 changes: 38 additions & 2 deletions app/controlplane/internal/biz/workflowrun.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const (
type WorkflowRunRepo interface {
Create(ctx context.Context, workflowID, robotaccountID, contractVersion uuid.UUID, runURL, runnerType string, casBackends []uuid.UUID) (*WorkflowRun, error)
FindByID(ctx context.Context, ID uuid.UUID) (*WorkflowRun, error)
FindByAttestationDigest(ctx context.Context, digest string) (*WorkflowRun, error)
FindByIDInOrg(ctx context.Context, orgID, ID uuid.UUID) (*WorkflowRun, error)
MarkAsFinished(ctx context.Context, ID uuid.UUID, status WorkflowRunStatus, reason string) error
SaveAttestation(ctx context.Context, ID uuid.UUID, att *dsse.Envelope, digest string) error
Expand Down Expand Up @@ -247,7 +248,8 @@ func (uc *WorkflowRunUseCase) List(ctx context.Context, orgID, workflowID string
return uc.wfRunRepo.List(ctx, orgUUID, workflowUUID, p)
}

func (uc *WorkflowRunUseCase) View(ctx context.Context, orgID, runID string) (*WorkflowRun, error) {
// Returns the workflow run with the provided ID if it belongs to the org or its public
func (uc *WorkflowRunUseCase) GetByIDInOrgOrPublic(ctx context.Context, orgID, runID string) (*WorkflowRun, error) {
orgUUID, err := uuid.Parse(orgID)
if err != nil {
return nil, NewErrInvalidUUID(err)
Expand All @@ -258,7 +260,41 @@ func (uc *WorkflowRunUseCase) View(ctx context.Context, orgID, runID string) (*W
return nil, NewErrInvalidUUID(err)
}

return uc.wfRunRepo.FindByIDInOrg(ctx, orgUUID, runUUID)
wfrun, err := uc.wfRunRepo.FindByID(ctx, runUUID)
if err != nil {
return nil, fmt.Errorf("finding workflow run: %w", err)
}

// If the workflow is public or belongs to the org we can return it
return workflowRunInOrgOrPublic(wfrun, orgUUID)
}

func (uc *WorkflowRunUseCase) GetByDigestInOrgOrPublic(ctx context.Context, orgID, digest string) (*WorkflowRun, error) {
orgUUID, err := uuid.Parse(orgID)
if err != nil {
return nil, NewErrInvalidUUID(err)
}

if _, err := v1.NewHash(digest); err != nil {
return nil, NewErrValidation(fmt.Errorf("invalid digest format: %w", err))
}

wfrun, err := uc.wfRunRepo.FindByAttestationDigest(ctx, digest)
if err != nil {
return nil, fmt.Errorf("finding workflow run: %w", err)
}

// If the workflow is public or belongs to the org we can return it
return workflowRunInOrgOrPublic(wfrun, orgUUID)
}

// filter the workflow runs that belong to the org or are public
func workflowRunInOrgOrPublic(wfRun *WorkflowRun, orgID uuid.UUID) (*WorkflowRun, error) {
if wfRun == nil || (wfRun.Workflow.OrgID != orgID && !wfRun.Workflow.Public) {
return nil, NewErrNotFound("workflow run")
}

return wfRun, nil
}

// Implements https://pkg.go.dev/entgo.io/ent/schema/field#EnumValues
Expand Down
Loading