From ef4950b88efe34f8dc3563b8580ea8f09010a3b1 Mon Sep 17 00:00:00 2001 From: Spencer Judge Date: Thu, 16 Jan 2025 15:50:40 -0800 Subject: [PATCH 1/6] Add summary/details to workflow starting options --- temporalcli/commands.gen.go | 4 ++++ temporalcli/commands.workflow_exec.go | 2 ++ temporalcli/commandsgen/commands.yml | 10 ++++++++++ 3 files changed, 16 insertions(+) diff --git a/temporalcli/commands.gen.go b/temporalcli/commands.gen.go index 04c626589..ccab78306 100644 --- a/temporalcli/commands.gen.go +++ b/temporalcli/commands.gen.go @@ -190,6 +190,8 @@ type SharedWorkflowStartOptions struct { TaskTimeout Duration SearchAttribute []string Memo []string + StaticSummary string + StaticDetails string } func (v *SharedWorkflowStartOptions) buildFlags(cctx *CommandContext, f *pflag.FlagSet) { @@ -206,6 +208,8 @@ func (v *SharedWorkflowStartOptions) buildFlags(cctx *CommandContext, f *pflag.F f.Var(&v.TaskTimeout, "task-timeout", "Fail a Workflow Task if it lasts longer than `DURATION`. This is the Start-to-close timeout for a Workflow Task.") f.StringArrayVar(&v.SearchAttribute, "search-attribute", nil, "Search Attribute in `KEY=VALUE` format. Keys must be identifiers, and values must be JSON values. For example: 'YourKey={\"your\": \"value\"}'. Can be passed multiple times.") f.StringArrayVar(&v.Memo, "memo", nil, "Memo using 'KEY=\"VALUE\"' pairs. Use JSON values.") + f.StringVar(&v.StaticSummary, "static-summary", "", "Static Workflow summary for human consumption in UIs. Uses Temporal Markdown formatting, should be a single line.") + f.StringVar(&v.StaticDetails, "static-details", "", "Static Workflow details for human consumption in UIs. Uses Temporal Markdown formatting, may be multiple lines.") } type WorkflowStartOptions struct { diff --git a/temporalcli/commands.workflow_exec.go b/temporalcli/commands.workflow_exec.go index 08393a7d9..cb5cf77f6 100644 --- a/temporalcli/commands.workflow_exec.go +++ b/temporalcli/commands.workflow_exec.go @@ -386,6 +386,8 @@ func buildStartOptions(sw *SharedWorkflowStartOptions, w *WorkflowStartOptions) CronSchedule: w.Cron, WorkflowExecutionErrorWhenAlreadyStarted: w.FailExisting, StartDelay: w.StartDelay.Duration(), + StaticSummary: sw.StaticSummary, + StaticDetails: sw.StaticDetails, } if w.IdReusePolicy.Value != "" { var err error diff --git a/temporalcli/commandsgen/commands.yml b/temporalcli/commandsgen/commands.yml index 85ec87d2e..7ea34ec22 100644 --- a/temporalcli/commandsgen/commands.yml +++ b/temporalcli/commandsgen/commands.yml @@ -3991,6 +3991,16 @@ option-sets: description: | Memo using 'KEY="VALUE"' pairs. Use JSON values. + - name: static-summary + type: string + description: | + Static Workflow summary for human consumption in UIs. + Uses Temporal Markdown formatting, should be a single line. + - name: static-details + type: string + description: | + Static Workflow details for human consumption in UIs. + Uses Temporal Markdown formatting, may be multiple lines. - name: workflow-start options: From 212d1d26be169f33e724c761258ad11679f4b0af Mon Sep 17 00:00:00 2001 From: Spencer Judge Date: Thu, 16 Jan 2025 16:43:58 -0800 Subject: [PATCH 2/6] Add summary/details to describe --- temporalcli/commands.workflow_view.go | 14 +++++++ temporalcli/commands.workflow_view_test.go | 43 ++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/temporalcli/commands.workflow_view.go b/temporalcli/commands.workflow_view.go index a1b969322..70c25ddaa 100644 --- a/temporalcli/commands.workflow_view.go +++ b/temporalcli/commands.workflow_view.go @@ -134,6 +134,20 @@ func (c *TemporalWorkflowDescribeCommand) run(cctx *CommandContext, args []strin HistorySize: info.HistorySizeBytes, }, printer.StructuredOptions{}) + staticSummary := resp.GetExecutionConfig().GetUserMetadata().GetSummary() + staticDetails := resp.GetExecutionConfig().GetUserMetadata().GetDetails() + if len(staticSummary.GetData()) > 0 || len(staticDetails.GetData()) > 0 { + cctx.Printer.Println() + cctx.Printer.Println(color.MagentaString("Metadata:")) + _ = cctx.Printer.PrintStructured(struct { + StaticSummary *common.Payload + StaticDetails *common.Payload + }{ + StaticSummary: staticSummary, + StaticDetails: staticDetails, + }, printer.StructuredOptions{}) + } + if info.VersioningInfo != nil { cctx.Printer.Println() cctx.Printer.Println(color.MagentaString("Versioning Info:")) diff --git a/temporalcli/commands.workflow_view_test.go b/temporalcli/commands.workflow_view_test.go index fe169bbd4..31bfc96af 100644 --- a/temporalcli/commands.workflow_view_test.go +++ b/temporalcli/commands.workflow_view_test.go @@ -950,3 +950,46 @@ func (s *SharedServerSuite) Test_WorkflowResult() { s.Contains(output, `"message": "failed on purpose"`) s.Contains(output, "workflowExecutionFailedEventAttributes") } + +func (s *SharedServerSuite) TestWorkflow_Describe_WorkflowMetadata() { + workflowId := uuid.NewString() + + s.Worker().OnDevWorkflow(func(ctx workflow.Context, input any) (any, error) { + return map[string]string{"foo": "bar"}, nil + }) + + res := s.Execute( + "workflow", "start", + "--address", s.Address(), + "--task-queue", s.Worker().Options.TaskQueue, + "--type", "DevWorkflow", + "--workflow-id", workflowId, + "--static-summary", "summie", + "--static-details", "deets", + ) + s.NoError(res.Err) + + // Text + res = s.Execute( + "workflow", "describe", + "--address", s.Address(), + "-w", workflowId, + ) + s.NoError(res.Err) + out := res.Stdout.String() + s.ContainsOnSameLine(out, "StaticSummary", "summie") + s.ContainsOnSameLine(out, "StaticDetails", "deets") + + // JSON + res = s.Execute( + "workflow", "describe", + "-o", "json", + "--address", s.Address(), + "-w", workflowId, + ) + s.NoError(res.Err) + var jsonOut workflowservice.DescribeWorkflowExecutionResponse + s.NoError(temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonOut, true)) + s.NotNil(jsonOut.ExecutionConfig.UserMetadata.Summary) + s.NotNil(jsonOut.ExecutionConfig.UserMetadata.Details) +} From fe5d1aa5db870638ae5b8132642069706da1e53f Mon Sep 17 00:00:00 2001 From: Spencer Judge Date: Thu, 16 Jan 2025 16:45:07 -0800 Subject: [PATCH 3/6] Mark experimental --- temporalcli/commandsgen/commands.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/temporalcli/commandsgen/commands.yml b/temporalcli/commandsgen/commands.yml index 7ea34ec22..ea676a117 100644 --- a/temporalcli/commandsgen/commands.yml +++ b/temporalcli/commandsgen/commands.yml @@ -3993,11 +3993,13 @@ option-sets: Use JSON values. - name: static-summary type: string + experimental: true description: | Static Workflow summary for human consumption in UIs. Uses Temporal Markdown formatting, should be a single line. - name: static-details type: string + experimental: true description: | Static Workflow details for human consumption in UIs. Uses Temporal Markdown formatting, may be multiple lines. From be671e44abff3511fd6f5c0df720f1acb221b7e7 Mon Sep 17 00:00:00 2001 From: Spencer Judge Date: Thu, 16 Jan 2025 16:58:07 -0800 Subject: [PATCH 4/6] Ignore Zed dir --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a8a5794dc..14713bfa8 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,5 @@ # Used by IDE /.idea /.vscode +/.zed *~ - From 0fa74899b5c13a5989ef0dba64901fcd201c2e9e Mon Sep 17 00:00:00 2001 From: Spencer Judge Date: Fri, 17 Jan 2025 16:53:54 -0800 Subject: [PATCH 5/6] Add to schedules (incomplete, need release) --- temporalcli/commands.schedule_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/temporalcli/commands.schedule_test.go b/temporalcli/commands.schedule_test.go index ec2167438..529d8770d 100644 --- a/temporalcli/commands.schedule_test.go +++ b/temporalcli/commands.schedule_test.go @@ -176,6 +176,24 @@ func (s *SharedServerSuite) TestSchedule_CreateDescribe_SearchAttributes_Memo() s.ContainsOnSameLine(out, "Action", "wfMemo", b64(`"other data"`)) } +func (s *SharedServerSuite) TestSchedule_CreateDescribe_UserMetadata() { + schedId, _, res := s.createSchedule("--interval", "10d", + "--static-summary", "summ", + "--static-details", "details", + ) + s.NoError(res.Err) + + res = s.Execute( + "schedule", "describe", + "--address", s.Address(), + "-s", schedId, + ) + s.NoError(res.Err) + out := res.Stdout.String() + s.ContainsOnSameLine(out, "Action", "summary", "summ") + s.ContainsOnSameLine(out, "Action", "details", "farts") +} + func (s *SharedServerSuite) TestSchedule_List() { res := s.Execute( "operator", "search-attribute", "create", From aa1fbd8347d16efcbd02ec92c23b5e9201d4c3f1 Mon Sep 17 00:00:00 2001 From: Spencer Judge Date: Thu, 27 Feb 2025 09:48:50 -0800 Subject: [PATCH 6/6] Actually pipe through summ/details to schedule workflow action --- temporalcli/commands.schedule.go | 2 ++ temporalcli/commands.schedule_test.go | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/temporalcli/commands.schedule.go b/temporalcli/commands.schedule.go index 3d645cb2e..7cf300e88 100644 --- a/temporalcli/commands.schedule.go +++ b/temporalcli/commands.schedule.go @@ -270,6 +270,8 @@ func toScheduleAction(sw *SharedWorkflowStartOptions, i *PayloadInputOptions) (c // RetryPolicy not supported yet UntypedSearchAttributes: untypedSearchAttributes, Memo: opts.Memo, + StaticSummary: opts.StaticSummary, + StaticDetails: opts.StaticDetails, } if action.Args, err = i.buildRawInput(); err != nil { return nil, err diff --git a/temporalcli/commands.schedule_test.go b/temporalcli/commands.schedule_test.go index 529d8770d..d24dc02c2 100644 --- a/temporalcli/commands.schedule_test.go +++ b/temporalcli/commands.schedule_test.go @@ -190,8 +190,8 @@ func (s *SharedServerSuite) TestSchedule_CreateDescribe_UserMetadata() { ) s.NoError(res.Err) out := res.Stdout.String() - s.ContainsOnSameLine(out, "Action", "summary", "summ") - s.ContainsOnSameLine(out, "Action", "details", "farts") + s.ContainsOnSameLine(out, "Action", "Summary", "summ") + s.ContainsOnSameLine(out, "Action", "Details", "details") } func (s *SharedServerSuite) TestSchedule_List() {