Skip to content

Commit de32e7b

Browse files
authored
feat(workflows): describe workflow by name (#756)
Signed-off-by: Jose I. Paris <[email protected]>
1 parent 4dac4f6 commit de32e7b

File tree

9 files changed

+218
-63
lines changed

9 files changed

+218
-63
lines changed

app/cli/cmd/workflow_describe.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ import (
2121
)
2222

2323
func newWorkflowDescribeCmd() *cobra.Command {
24-
var workflowID string
24+
var workflowID, workflowName string
2525

2626
cmd := &cobra.Command{
2727
Use: "describe",
2828
Short: "Describe an existing workflow",
2929
RunE: func(cmd *cobra.Command, args []string) error {
30-
wf, err := action.NewWorkflowDescribe(actionOpts).Run(cmd.Context(), workflowID)
30+
wf, err := action.NewWorkflowDescribe(actionOpts).Run(cmd.Context(), workflowID, workflowName)
3131
if err != nil {
3232
return err
3333
}
@@ -37,8 +37,10 @@ func newWorkflowDescribeCmd() *cobra.Command {
3737
}
3838

3939
cmd.Flags().StringVar(&workflowID, "id", "", "workflow id")
40-
err := cmd.MarkFlagRequired("id")
41-
cobra.CheckErr(err)
40+
cmd.Flags().StringVar(&workflowName, "name", "", "workflow name")
41+
42+
cmd.MarkFlagsOneRequired("id", "name")
43+
cmd.MarkFlagsMutuallyExclusive("id", "name")
4244

4345
return cmd
4446
}

app/cli/internal/action/workflow_describe.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,14 @@ func NewWorkflowDescribe(cfg *ActionsOpts) *WorkflowDescribe {
2929
return &WorkflowDescribe{cfg}
3030
}
3131

32-
func (action *WorkflowDescribe) Run(ctx context.Context, workflowID string) (*WorkflowItem, error) {
32+
func (action *WorkflowDescribe) Run(ctx context.Context, workflowID, workflowName string) (*WorkflowItem, error) {
3333
client := pb.NewWorkflowServiceClient(action.cfg.CPConnection)
3434

35-
resp, err := client.View(ctx, &pb.WorkflowServiceViewRequest{Id: workflowID})
35+
req := &pb.WorkflowServiceViewRequest{Id: workflowID}
36+
if workflowName != "" {
37+
req.Name = workflowName
38+
}
39+
resp, err := client.View(ctx, req)
3640
if err != nil {
3741
return nil, err
3842
}

app/controlplane/api/controlplane/v1/workflow.pb.go

Lines changed: 73 additions & 48 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/controlplane/api/controlplane/v1/workflow.proto

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,30 @@ message WorkflowServiceListResponse {
7272
}
7373

7474
message WorkflowServiceViewRequest {
75-
string id = 1 [(buf.validate.field).string.uuid = true];
75+
string id = 1 [
76+
deprecated = true,
77+
(buf.validate.field) = {
78+
string: {uuid: true},
79+
ignore_empty: true,
80+
}
81+
];
82+
83+
string name = 2 [
84+
(buf.validate.field) = {
85+
ignore_empty: true,
86+
cel: {
87+
message: "name must be a valid DNS-1123 subdomain",
88+
expression: "this.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')",
89+
id: "name.dns-1123",
90+
},
91+
}
92+
];
93+
94+
option (buf.validate.message).cel = {
95+
id: "either-name-or-id-required",
96+
message: "either name or id are required",
97+
expression: "has(this.id) || has(this.name)"
98+
};
7699
}
77100

78101
message WorkflowServiceViewResponse {

app/controlplane/api/gen/frontend/controlplane/v1/workflow.ts

Lines changed: 16 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/controlplane/internal/biz/workflow.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ type WorkflowRepo interface {
4444
Update(ctx context.Context, id uuid.UUID, opts *WorkflowUpdateOpts) (*Workflow, error)
4545
List(ctx context.Context, orgID uuid.UUID) ([]*Workflow, error)
4646
GetOrgScoped(ctx context.Context, orgID, workflowID uuid.UUID) (*Workflow, error)
47+
GetOrgScopedByName(ctx context.Context, orgID uuid.UUID, workflowName string) (*Workflow, error)
4748
IncRunsCounter(ctx context.Context, workflowID uuid.UUID) error
4849
FindByID(ctx context.Context, workflowID uuid.UUID) (*Workflow, error)
4950
SoftDelete(ctx context.Context, workflowID uuid.UUID) error
@@ -231,6 +232,24 @@ func (uc *WorkflowUseCase) FindByIDInOrg(ctx context.Context, orgID, workflowID
231232
return wf, nil
232233
}
233234

235+
func (uc *WorkflowUseCase) FindByNameInOrg(ctx context.Context, orgID, workflowName string) (*Workflow, error) {
236+
orgUUID, err := uuid.Parse(orgID)
237+
if err != nil {
238+
return nil, NewErrInvalidUUID(err)
239+
}
240+
241+
if workflowName == "" {
242+
return nil, NewErrValidationStr("empty workflow name")
243+
}
244+
245+
wf, err := uc.wfRepo.GetOrgScopedByName(ctx, orgUUID, workflowName)
246+
if err != nil {
247+
return nil, fmt.Errorf("failed to get workflow: %w", err)
248+
}
249+
250+
return wf, nil
251+
}
252+
234253
// Delete soft-deletes the entry
235254
func (uc *WorkflowUseCase) Delete(ctx context.Context, orgID, workflowID string) error {
236255
orgUUID, err := uuid.Parse(orgID)

app/controlplane/internal/biz/workflow_integration_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,28 @@ func (s *workflowIntegrationTestSuite) TestContractLatestAvailable() {
5959
})
6060
}
6161

62+
func (s *workflowIntegrationTestSuite) TestView() {
63+
s.Run("finds by id in org", func() {
64+
wf, err := s.Workflow.FindByIDInOrg(context.TODO(), s.org.ID, s.wf.ID.String())
65+
s.NoError(err)
66+
s.Equal(s.wf.ID, wf.ID)
67+
})
68+
69+
s.Run("finds by name in org", func() {
70+
wf, err := s.Workflow.FindByNameInOrg(context.TODO(), s.org.ID, s.wf.Name)
71+
s.NoError(err)
72+
s.Equal(s.wf.ID, wf.ID)
73+
})
74+
75+
s.Run("fails if workflow belongs to a different org", func() {
76+
org2, err := s.Organization.CreateWithRandomName(context.Background())
77+
require.NoError(s.T(), err)
78+
79+
_, err = s.Workflow.FindByNameInOrg(context.TODO(), org2.ID, s.wf.Name)
80+
s.Error(err)
81+
})
82+
}
83+
6284
func (s *workflowIntegrationTestSuite) TestCreateDuplicatedName() {
6385
ctx := context.Background()
6486

@@ -310,6 +332,7 @@ func TestWorkflowUseCase(t *testing.T) {
310332
type workflowIntegrationTestSuite struct {
311333
testhelpers.UseCasesEachTestSuite
312334
org *biz.Organization
335+
wf *biz.Workflow
313336
}
314337

315338
func (s *workflowIntegrationTestSuite) SetupTest() {
@@ -320,6 +343,13 @@ func (s *workflowIntegrationTestSuite) SetupTest() {
320343
ctx := context.Background()
321344
s.org, err = s.Organization.CreateWithRandomName(ctx)
322345
assert.NoError(err)
346+
347+
s.wf, err = s.Workflow.Create(ctx, &biz.WorkflowCreateOpts{
348+
Name: "my-workflow",
349+
Project: "my-project",
350+
OrgID: s.org.ID,
351+
})
352+
assert.NoError(err)
323353
}
324354

325355
func toPtrS(s string) *string {

0 commit comments

Comments
 (0)