From 728274ac4b1cd7e7031c87e068eed0e78d608dac Mon Sep 17 00:00:00 2001 From: Spencer Judge Date: Thu, 27 Feb 2025 10:08:07 -0800 Subject: [PATCH 01/11] User Metadata set on start / desc (#742) --- .gitignore | 2 +- temporalcli/commands.gen.go | 4 ++ temporalcli/commands.schedule.go | 2 + temporalcli/commands.schedule_test.go | 18 +++++++++ temporalcli/commands.workflow_exec.go | 2 + temporalcli/commands.workflow_view.go | 14 +++++++ temporalcli/commands.workflow_view_test.go | 43 ++++++++++++++++++++++ temporalcli/commandsgen/commands.yml | 12 ++++++ 8 files changed, 96 insertions(+), 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 *~ - 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.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 ec2167438..d24dc02c2 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", "details") +} + func (s *SharedServerSuite) TestSchedule_List() { res := s.Execute( "operator", "search-attribute", "create", 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/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) +} diff --git a/temporalcli/commandsgen/commands.yml b/temporalcli/commandsgen/commands.yml index 85ec87d2e..ea676a117 100644 --- a/temporalcli/commandsgen/commands.yml +++ b/temporalcli/commandsgen/commands.yml @@ -3991,6 +3991,18 @@ option-sets: description: | Memo using 'KEY="VALUE"' pairs. 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. - name: workflow-start options: From cbf2b52eb78a011d843c1c0005b5d24257938bcc Mon Sep 17 00:00:00 2001 From: Antonio Lain <135073478+antlai-temporal@users.noreply.github.com> Date: Thu, 27 Feb 2025 12:31:19 -0800 Subject: [PATCH 02/11] Fix batch deployment test nil pointer exception (#769) --- temporalcli/commands.workflow_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/temporalcli/commands.workflow_test.go b/temporalcli/commands.workflow_test.go index 8e479c82f..02fddb10f 100644 --- a/temporalcli/commands.workflow_test.go +++ b/temporalcli/commands.workflow_test.go @@ -528,7 +528,9 @@ func (s *SharedServerSuite) TestWorkflow_Batch_Update_Options_Versioning_Overrid var jsonResp workflowservice.DescribeWorkflowExecutionResponse assert.NoError(t, temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonResp, true)) - versioningInfo := jsonResp.WorkflowExecutionInfo.VersioningInfo + + versioningInfo := jsonResp.GetWorkflowExecutionInfo().GetVersioningInfo() + assert.NotNil(t, versioningInfo) assert.NotNil(t, versioningInfo.VersioningOverride) assert.Equal(t, version2, versioningInfo.VersioningOverride.PinnedVersion) } From 97cc6c27149b812d92f43abef2c2250ca79c53e0 Mon Sep 17 00:00:00 2001 From: Yuri Date: Thu, 27 Feb 2025 12:49:39 -0800 Subject: [PATCH 03/11] Add fields from extended info to DescribeWorkflow output (#771) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What was changed Add extended info to the DescribeWorkflow output. ## Why? Customer request. --- temporalcli/commands.workflow_view.go | 67 ++++++++++++++++----------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/temporalcli/commands.workflow_view.go b/temporalcli/commands.workflow_view.go index 70c25ddaa..75f1db34e 100644 --- a/temporalcli/commands.workflow_view.go +++ b/temporalcli/commands.workflow_view.go @@ -102,36 +102,47 @@ func (c *TemporalWorkflowDescribeCommand) run(cctx *CommandContext, args []strin cctx.Printer.Println(color.MagentaString("Execution Info:")) info := resp.WorkflowExecutionInfo + extendedInfo := resp.WorkflowExtendedInfo _ = cctx.Printer.PrintStructured(struct { - WorkflowId string - RunId string - Type string - Namespace string - TaskQueue string - AssignedBuildId string - StartTime time.Time - CloseTime time.Time `cli:",cardOmitEmpty"` - ExecutionTime time.Time `cli:",cardOmitEmpty"` - Memo map[string]*common.Payload `cli:",cardOmitEmpty"` - SearchAttributes map[string]*common.Payload `cli:",cardOmitEmpty"` - StateTransitionCount int64 - HistoryLength int64 - HistorySize int64 + WorkflowId string + RunId string + Type string + Namespace string + TaskQueue string + AssignedBuildId string + StartTime time.Time + CloseTime time.Time `cli:",cardOmitEmpty"` + ExecutionTime time.Time `cli:",cardOmitEmpty"` + Memo map[string]*common.Payload `cli:",cardOmitEmpty"` + SearchAttributes map[string]*common.Payload `cli:",cardOmitEmpty"` + StateTransitionCount int64 + HistoryLength int64 + HistorySize int64 + ExecutionExpirationTime time.Time `cli:",cardOmitEmpty"` + RunExpirationTime time.Time `cli:",cardOmitEmpty"` + CancelRequested bool + LastResetTime time.Time `cli:",cardOmitEmpty"` + OriginalStartTime time.Time `cli:",cardOmitEmpty"` }{ - WorkflowId: info.Execution.WorkflowId, - RunId: info.Execution.RunId, - Type: info.Type.GetName(), - Namespace: c.Parent.Namespace, - TaskQueue: info.TaskQueue, - AssignedBuildId: info.GetAssignedBuildId(), - StartTime: timestampToTime(info.StartTime), - CloseTime: timestampToTime(info.CloseTime), - ExecutionTime: timestampToTime(info.ExecutionTime), - Memo: info.Memo.GetFields(), - SearchAttributes: info.SearchAttributes.GetIndexedFields(), - StateTransitionCount: info.StateTransitionCount, - HistoryLength: info.HistoryLength, - HistorySize: info.HistorySizeBytes, + WorkflowId: info.Execution.WorkflowId, + RunId: info.Execution.RunId, + Type: info.Type.GetName(), + Namespace: c.Parent.Namespace, + TaskQueue: info.TaskQueue, + AssignedBuildId: info.GetAssignedBuildId(), + StartTime: timestampToTime(info.StartTime), + CloseTime: timestampToTime(info.CloseTime), + ExecutionTime: timestampToTime(info.ExecutionTime), + Memo: info.Memo.GetFields(), + SearchAttributes: info.SearchAttributes.GetIndexedFields(), + StateTransitionCount: info.StateTransitionCount, + HistoryLength: info.HistoryLength, + HistorySize: info.HistorySizeBytes, + ExecutionExpirationTime: timestampToTime(extendedInfo.ExecutionExpirationTime), + RunExpirationTime: timestampToTime(extendedInfo.RunExpirationTime), + CancelRequested: extendedInfo.CancelRequested, + LastResetTime: timestampToTime(extendedInfo.LastResetTime), + OriginalStartTime: timestampToTime(extendedInfo.OriginalStartTime), }, printer.StructuredOptions{}) staticSummary := resp.GetExecutionConfig().GetUserMetadata().GetSummary() From 94883d3b86f70b77f9d2e22c6a8015603fd88d05 Mon Sep 17 00:00:00 2001 From: Thomas Hardy Date: Fri, 28 Feb 2025 09:32:02 -0800 Subject: [PATCH 04/11] added `workflow start-update-with-start` and `workflow execute-update-with-start` commands (#762) added `temporal workflow start-update-with-start` and `temporal workflow execute-update-with-start` commands `temporal workflow start-update-with-start` usage: ``` temporal workflow start-update-with-start \ --update-name YourUpdate \ --update-input '{"update-key": "update-value"}' \ --update-wait-for-stage accepted \ --workflow-id YourWorkflowId \ --type YourWorkflowType \ --task-queue YourTaskQueue \ --id-conflict-policy Fail \ --input '{"wf-key": "wf-value"}' ``` `temporal workflow execute-update-with-start` usage: ``` temporal workflow execute-update-with-start \ --update-name YourUpdate \ --update-input '{"update-key": "update-value"}' \ --workflow-id YourWorkflowId \ --type YourWorkflowType \ --task-queue YourTaskQueue \ --id-conflict-policy Fail \ --input '{"wf-key": "wf-value"}' ``` 1. Closes #664 2. How was this tested: 3. Any docs updates needed? Yes --- temporalcli/commands.gen.go | 114 +++++++- temporalcli/commands.workflow_exec.go | 182 ++++++++++++- temporalcli/commands.workflow_exec_test.go | 290 +++++++++++++++++---- temporalcli/commandsgen/commands.yml | 158 +++++++++++ 4 files changed, 693 insertions(+), 51 deletions(-) diff --git a/temporalcli/commands.gen.go b/temporalcli/commands.gen.go index ccab78306..45a4069ca 100644 --- a/temporalcli/commands.gen.go +++ b/temporalcli/commands.gen.go @@ -2859,6 +2859,7 @@ func NewTemporalWorkflowCommand(cctx *CommandContext, parent *TemporalCommand) * s.Command.AddCommand(&NewTemporalWorkflowDeleteCommand(cctx, &s).Command) s.Command.AddCommand(&NewTemporalWorkflowDescribeCommand(cctx, &s).Command) s.Command.AddCommand(&NewTemporalWorkflowExecuteCommand(cctx, &s).Command) + s.Command.AddCommand(&NewTemporalWorkflowExecuteUpdateWithStartCommand(cctx, &s).Command) s.Command.AddCommand(&NewTemporalWorkflowFixHistoryJsonCommand(cctx, &s).Command) s.Command.AddCommand(&NewTemporalWorkflowListCommand(cctx, &s).Command) s.Command.AddCommand(&NewTemporalWorkflowMetadataCommand(cctx, &s).Command) @@ -2870,6 +2871,7 @@ func NewTemporalWorkflowCommand(cctx *CommandContext, parent *TemporalCommand) * s.Command.AddCommand(&NewTemporalWorkflowSignalWithStartCommand(cctx, &s).Command) s.Command.AddCommand(&NewTemporalWorkflowStackCommand(cctx, &s).Command) s.Command.AddCommand(&NewTemporalWorkflowStartCommand(cctx, &s).Command) + s.Command.AddCommand(&NewTemporalWorkflowStartUpdateWithStartCommand(cctx, &s).Command) s.Command.AddCommand(&NewTemporalWorkflowTerminateCommand(cctx, &s).Command) s.Command.AddCommand(&NewTemporalWorkflowTraceCommand(cctx, &s).Command) s.Command.AddCommand(&NewTemporalWorkflowUpdateCommand(cctx, &s).Command) @@ -3026,6 +3028,58 @@ func NewTemporalWorkflowExecuteCommand(cctx *CommandContext, parent *TemporalWor return &s } +type TemporalWorkflowExecuteUpdateWithStartCommand struct { + Parent *TemporalWorkflowCommand + Command cobra.Command + SharedWorkflowStartOptions + WorkflowStartOptions + PayloadInputOptions + UpdateName string + UpdateFirstExecutionRunId string + UpdateId string + RunId string + UpdateInput []string + UpdateInputFile []string + UpdateInputMeta []string + UpdateInputBase64 bool +} + +func NewTemporalWorkflowExecuteUpdateWithStartCommand(cctx *CommandContext, parent *TemporalWorkflowCommand) *TemporalWorkflowExecuteUpdateWithStartCommand { + var s TemporalWorkflowExecuteUpdateWithStartCommand + s.Parent = parent + s.Command.DisableFlagsInUseLine = true + s.Command.Use = "execute-update-with-start [flags]" + s.Command.Short = "Send an Update and wait for it to complete (Experimental)" + if hasHighlighting { + s.Command.Long = "Send a message to a Workflow Execution to invoke an Update handler, and wait for\nthe update to complete. If the Workflow Execution is not running, then a new workflow\nexecution is started and the update is sent.\n\nExperimental.\n\n\x1b[1mtemporal workflow execute-update-with-start \\\n --update-name YourUpdate \\\n --update-input '{\"update-key\": \"update-value\"}' \\\n --workflow-id YourWorkflowId \\\n --type YourWorkflowType \\\n --task-queue YourTaskQueue \\\n --id-conflict-policy Fail \\\n --input '{\"wf-key\": \"wf-value\"}'\x1b[0m" + } else { + s.Command.Long = "Send a message to a Workflow Execution to invoke an Update handler, and wait for\nthe update to complete. If the Workflow Execution is not running, then a new workflow\nexecution is started and the update is sent.\n\nExperimental.\n\n```\ntemporal workflow execute-update-with-start \\\n --update-name YourUpdate \\\n --update-input '{\"update-key\": \"update-value\"}' \\\n --workflow-id YourWorkflowId \\\n --type YourWorkflowType \\\n --task-queue YourTaskQueue \\\n --id-conflict-policy Fail \\\n --input '{\"wf-key\": \"wf-value\"}'\n```" + } + s.Command.Args = cobra.NoArgs + s.Command.Flags().StringVar(&s.UpdateName, "update-name", "", "Update name. Required. Aliased as \"--update-type\".") + _ = cobra.MarkFlagRequired(s.Command.Flags(), "update-name") + s.Command.Flags().StringVar(&s.UpdateFirstExecutionRunId, "update-first-execution-run-id", "", "Parent Run ID. The update is sent to the last Workflow Execution in the chain started with this Run ID.") + s.Command.Flags().StringVar(&s.UpdateId, "update-id", "", "Update ID. If unset, defaults to a UUID.") + s.Command.Flags().StringVarP(&s.RunId, "run-id", "r", "", "Run ID. If unset, looks for an Update against the currently-running Workflow Execution.") + s.Command.Flags().StringArrayVar(&s.UpdateInput, "update-input", nil, "Update input value. Use JSON content or set --update-input-meta to override. Can't be combined with --update-input-file. Can be passed multiple times to pass multiple arguments.") + s.Command.Flags().StringArrayVar(&s.UpdateInputFile, "update-input-file", nil, "A path or paths for input file(s). Use JSON content or set --update-input-meta to override. Can't be combined with --update-input. Can be passed multiple times to pass multiple arguments.") + s.Command.Flags().StringArrayVar(&s.UpdateInputMeta, "update-input-meta", nil, "Input update payload metadata as a `KEY=VALUE` pair. When the KEY is \"encoding\", this overrides the default (\"json/plain\"). Can be passed multiple times.") + s.Command.Flags().BoolVar(&s.UpdateInputBase64, "update-input-base64", false, "Assume update inputs are base64-encoded and attempt to decode them.") + s.SharedWorkflowStartOptions.buildFlags(cctx, s.Command.Flags()) + s.WorkflowStartOptions.buildFlags(cctx, s.Command.Flags()) + s.PayloadInputOptions.buildFlags(cctx, s.Command.Flags()) + s.Command.Flags().SetNormalizeFunc(aliasNormalizer(map[string]string{ + "name": "type", + "update-type": "update-name", + })) + s.Command.Run = func(c *cobra.Command, args []string) { + if err := s.run(cctx, args); err != nil { + cctx.Options.Fail(err) + } + } + return &s +} + type TemporalWorkflowFixHistoryJsonCommand struct { Parent *TemporalWorkflowCommand Command cobra.Command @@ -3407,6 +3461,62 @@ func NewTemporalWorkflowStartCommand(cctx *CommandContext, parent *TemporalWorkf return &s } +type TemporalWorkflowStartUpdateWithStartCommand struct { + Parent *TemporalWorkflowCommand + Command cobra.Command + SharedWorkflowStartOptions + WorkflowStartOptions + PayloadInputOptions + UpdateName string + UpdateFirstExecutionRunId string + UpdateWaitForStage StringEnum + UpdateId string + RunId string + UpdateInput []string + UpdateInputFile []string + UpdateInputMeta []string + UpdateInputBase64 bool +} + +func NewTemporalWorkflowStartUpdateWithStartCommand(cctx *CommandContext, parent *TemporalWorkflowCommand) *TemporalWorkflowStartUpdateWithStartCommand { + var s TemporalWorkflowStartUpdateWithStartCommand + s.Parent = parent + s.Command.DisableFlagsInUseLine = true + s.Command.Use = "start-update-with-start [flags]" + s.Command.Short = "Send an Update and wait for it to be accepted or rejected (Experimental)" + if hasHighlighting { + s.Command.Long = "Send a message to a Workflow Execution to invoke an Update handler, and wait for\nthe update to be accepted or rejected. If the Workflow Execution is not running, \nthen a new workflow execution is started and the update is sent.\n\nExperimental.\n\n\x1b[1mtemporal workflow start-update-with-start \\\n --update-name YourUpdate \\\n --update-input '{\"update-key\": \"update-value\"}' \\\n --update-wait-for-stage accepted \\\n --workflow-id YourWorkflowId \\\n --type YourWorkflowType \\\n --task-queue YourTaskQueue \\\n --id-conflict-policy Fail \\\n --input '{\"wf-key\": \"wf-value\"}'\x1b[0m" + } else { + s.Command.Long = "Send a message to a Workflow Execution to invoke an Update handler, and wait for\nthe update to be accepted or rejected. If the Workflow Execution is not running, \nthen a new workflow execution is started and the update is sent.\n\nExperimental.\n\n```\ntemporal workflow start-update-with-start \\\n --update-name YourUpdate \\\n --update-input '{\"update-key\": \"update-value\"}' \\\n --update-wait-for-stage accepted \\\n --workflow-id YourWorkflowId \\\n --type YourWorkflowType \\\n --task-queue YourTaskQueue \\\n --id-conflict-policy Fail \\\n --input '{\"wf-key\": \"wf-value\"}'\n```" + } + s.Command.Args = cobra.NoArgs + s.Command.Flags().StringVar(&s.UpdateName, "update-name", "", "Update name. Required. Aliased as \"--update-type\".") + _ = cobra.MarkFlagRequired(s.Command.Flags(), "update-name") + s.Command.Flags().StringVar(&s.UpdateFirstExecutionRunId, "update-first-execution-run-id", "", "Parent Run ID. The update is sent to the last Workflow Execution in the chain started with this Run ID.") + s.UpdateWaitForStage = NewStringEnum([]string{"accepted"}, "") + s.Command.Flags().Var(&s.UpdateWaitForStage, "update-wait-for-stage", "Update stage to wait for. The only option is `accepted`, but this option is required. This is to allow a future version of the CLI to choose a default value. Accepted values: accepted. Required.") + _ = cobra.MarkFlagRequired(s.Command.Flags(), "update-wait-for-stage") + s.Command.Flags().StringVar(&s.UpdateId, "update-id", "", "Update ID. If unset, defaults to a UUID.") + s.Command.Flags().StringVarP(&s.RunId, "run-id", "r", "", "Run ID. If unset, looks for an Update against the currently-running Workflow Execution.") + s.Command.Flags().StringArrayVar(&s.UpdateInput, "update-input", nil, "Update input value. Use JSON content or set --update-input-meta to override. Can't be combined with --update-input-file. Can be passed multiple times to pass multiple arguments.") + s.Command.Flags().StringArrayVar(&s.UpdateInputFile, "update-input-file", nil, "A path or paths for input file(s). Use JSON content or set --update-input-meta to override. Can't be combined with --update-input. Can be passed multiple times to pass multiple arguments.") + s.Command.Flags().StringArrayVar(&s.UpdateInputMeta, "update-input-meta", nil, "Input update payload metadata as a `KEY=VALUE` pair. When the KEY is \"encoding\", this overrides the default (\"json/plain\"). Can be passed multiple times.") + s.Command.Flags().BoolVar(&s.UpdateInputBase64, "update-input-base64", false, "Assume update inputs are base64-encoded and attempt to decode them.") + s.SharedWorkflowStartOptions.buildFlags(cctx, s.Command.Flags()) + s.WorkflowStartOptions.buildFlags(cctx, s.Command.Flags()) + s.PayloadInputOptions.buildFlags(cctx, s.Command.Flags()) + s.Command.Flags().SetNormalizeFunc(aliasNormalizer(map[string]string{ + "name": "type", + "update-type": "update-name", + })) + s.Command.Run = func(c *cobra.Command, args []string) { + if err := s.run(cctx, args); err != nil { + cctx.Options.Fail(err) + } + } + return &s +} + type TemporalWorkflowTerminateCommand struct { Parent *TemporalWorkflowCommand Command cobra.Command @@ -3599,9 +3709,9 @@ func NewTemporalWorkflowUpdateStartCommand(cctx *CommandContext, parent *Tempora s.Command.Use = "start [flags]" s.Command.Short = "Send an Update and wait for it to be accepted or rejected (Experimental)" if hasHighlighting { - s.Command.Long = "Send a message to a Workflow Execution to invoke an Update handler, and wait for\nthe update to be accepted or rejected. You can subsequently wait for the update\nto complete by using \x1b[1mtemporal workflow update execute\x1b[0m.\n\nExperimental.\n\n\x1b[1mtemporal workflow update start \\\n --workflow-id YourWorkflowId \\\n --name YourUpdate \\\n --input '{\"some-key\": \"some-value\"}'\x1b[0m" + s.Command.Long = "Send a message to a Workflow Execution to invoke an Update handler, and wait for\nthe update to be accepted or rejected. You can subsequently wait for the update\nto complete by using \x1b[1mtemporal workflow update execute\x1b[0m.\n\nExperimental.\n\n\x1b[1mtemporal workflow update start \\\n --workflow-id YourWorkflowId \\\n --name YourUpdate \\\n --input '{\"some-key\": \"some-value\"}'\n --wait-for-stage accepted\x1b[0m" } else { - s.Command.Long = "Send a message to a Workflow Execution to invoke an Update handler, and wait for\nthe update to be accepted or rejected. You can subsequently wait for the update\nto complete by using `temporal workflow update execute`.\n\nExperimental.\n\n```\ntemporal workflow update start \\\n --workflow-id YourWorkflowId \\\n --name YourUpdate \\\n --input '{\"some-key\": \"some-value\"}'\n```" + s.Command.Long = "Send a message to a Workflow Execution to invoke an Update handler, and wait for\nthe update to be accepted or rejected. You can subsequently wait for the update\nto complete by using `temporal workflow update execute`.\n\nExperimental.\n\n```\ntemporal workflow update start \\\n --workflow-id YourWorkflowId \\\n --name YourUpdate \\\n --input '{\"some-key\": \"some-value\"}'\n --wait-for-stage accepted\n```" } s.Command.Args = cobra.NoArgs s.WaitForStage = NewStringEnum([]string{"accepted"}, "") diff --git a/temporalcli/commands.workflow_exec.go b/temporalcli/commands.workflow_exec.go index cb5cf77f6..a88d89ba7 100644 --- a/temporalcli/commands.workflow_exec.go +++ b/temporalcli/commands.workflow_exec.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "os" "reflect" @@ -121,7 +122,7 @@ func (c *TemporalWorkflowSignalWithStartCommand) run(cctx *CommandContext, _ []s signalPayloadInputOpts := PayloadInputOptions{ Input: c.SignalInput, InputFile: c.SignalInputFile, - InputMeta: c.InputMeta, + InputMeta: c.SignalInputMeta, InputBase64: c.SignalInputBase64, } signalInput, err := signalPayloadInputOpts.buildRawInputPayloads() @@ -194,16 +195,191 @@ func (c *TemporalWorkflowSignalWithStartCommand) run(cctx *CommandContext, _ []s RunId string `json:"runId"` Type string `json:"type"` Namespace string `json:"namespace"` - TaskQueue string `json:"taskQueue"` }{ WorkflowId: c.WorkflowId, RunId: resp.RunId, Type: c.Type, Namespace: c.Parent.Namespace, - TaskQueue: c.TaskQueue, }, printer.StructuredOptions{}) } +func (c *TemporalWorkflowStartUpdateWithStartCommand) run(cctx *CommandContext, _ []string) error { + waitForStage := client.WorkflowUpdateStageUnspecified + switch c.UpdateWaitForStage.Value { + case "accepted": + waitForStage = client.WorkflowUpdateStageAccepted + } + if waitForStage != client.WorkflowUpdateStageAccepted { + return fmt.Errorf("invalid wait for stage: %v, valid values are: 'accepted'", c.UpdateWaitForStage) + } + + updatePayloadInputOpts := PayloadInputOptions{ + Input: c.UpdateInput, + InputFile: c.UpdateInputFile, + InputMeta: c.UpdateInputMeta, + InputBase64: c.UpdateInputBase64, + } + updateInput, err := updatePayloadInputOpts.buildRawInput() + if err != nil { + return err + } + updateOpts := client.UpdateWorkflowOptions{ + UpdateID: c.UpdateId, + WorkflowID: c.WorkflowId, + RunID: c.RunId, + UpdateName: c.UpdateName, + Args: updateInput, + WaitForStage: waitForStage, + FirstExecutionRunID: c.UpdateFirstExecutionRunId, + } + + handle, err := executeUpdateWithStartWorkflow( + cctx, + c.Parent.ClientOptions, + c.SharedWorkflowStartOptions, + c.WorkflowStartOptions, + c.PayloadInputOptions, + updateOpts, + ) + if err != nil { + return err + } + + // Currently we only accept 'accepted' as a valid wait for stage value, but we intend + // to support more in the future. + if waitForStage == client.WorkflowUpdateStageAccepted { + // Use a canceled context to check whether the initial server response + // shows that the update has _already_ failed, without issuing a second request. + ctx, cancel := context.WithCancel(cctx) + cancel() + err = handle.Get(ctx, nil) + var timeoutOrCanceledErr *client.WorkflowUpdateServiceTimeoutOrCanceledError + if err != nil && !errors.As(err, &timeoutOrCanceledErr) { + return fmt.Errorf("unable to update workflow: %w", err) + } + } + + cctx.Printer.Println(color.MagentaString("Running execution:")) + return cctx.Printer.PrintStructured(struct { + WorkflowId string `json:"workflowId"` + RunId string `json:"runId"` + Type string `json:"type"` + Namespace string `json:"namespace"` + UpdateName string `json:"updateName"` + UpdateID string `json:"updateId"` + }{ + WorkflowId: c.WorkflowId, + RunId: handle.RunID(), + Type: c.Type, + Namespace: c.Parent.Namespace, + UpdateName: c.UpdateName, + UpdateID: handle.UpdateID(), + }, printer.StructuredOptions{}) +} + +func (c *TemporalWorkflowExecuteUpdateWithStartCommand) run(cctx *CommandContext, _ []string) error { + updatePayloadInputOpts := PayloadInputOptions{ + Input: c.UpdateInput, + InputFile: c.UpdateInputFile, + InputMeta: c.UpdateInputMeta, + InputBase64: c.UpdateInputBase64, + } + updateInput, err := updatePayloadInputOpts.buildRawInput() + if err != nil { + return err + } + + updateOpts := client.UpdateWorkflowOptions{ + UpdateName: c.UpdateName, + UpdateID: c.UpdateId, + WorkflowID: c.WorkflowId, + RunID: c.RunId, + Args: updateInput, + WaitForStage: client.WorkflowUpdateStageCompleted, + FirstExecutionRunID: c.UpdateFirstExecutionRunId, + } + + handle, err := executeUpdateWithStartWorkflow( + cctx, + c.Parent.ClientOptions, + c.SharedWorkflowStartOptions, + c.WorkflowStartOptions, + c.PayloadInputOptions, + updateOpts, + ) + if err != nil { + return err + } + + var valuePtr interface{} + err = handle.Get(cctx, &valuePtr) + if err != nil { + return fmt.Errorf("unable to update workflow: %w", err) + } + + cctx.Printer.Println(color.MagentaString("Running execution:")) + return cctx.Printer.PrintStructured(struct { + WorkflowId string `json:"workflowId"` + RunId string `json:"runId"` + Type string `json:"type"` + Namespace string `json:"namespace"` + UpdateName string `json:"updateName"` + UpdateID string `json:"updateId"` + UpdateResult interface{} `json:"updateResult"` + }{ + WorkflowId: c.WorkflowId, + RunId: handle.RunID(), + Type: c.Type, + Namespace: c.Parent.Namespace, + UpdateName: c.UpdateName, + UpdateID: c.UpdateId, + UpdateResult: valuePtr, + }, printer.StructuredOptions{}) +} + +func executeUpdateWithStartWorkflow( + cctx *CommandContext, + clientOpts ClientOptions, + sharedWfOpts SharedWorkflowStartOptions, + wfStartOpts WorkflowStartOptions, + wfInputOpts PayloadInputOptions, + updateWfOpts client.UpdateWorkflowOptions, +) (client.WorkflowUpdateHandle, error) { + if sharedWfOpts.WorkflowId == "" { + return nil, fmt.Errorf("--workflow-id flag must be provided") + } + if wfStartOpts.IdConflictPolicy.Value == "" { + return nil, fmt.Errorf("--id-conflict-policy flag must be provided") + } + cl, err := clientOpts.dialClient(cctx) + if err != nil { + return nil, err + } + defer cl.Close() + + clStartWfOpts, err := buildStartOptions(&sharedWfOpts, &wfStartOpts) + if err != nil { + return nil, err + } + + wfArgs, err := wfInputOpts.buildRawInput() + if err != nil { + return nil, err + } + + startOp := cl.NewWithStartWorkflowOperation( + clStartWfOpts, + sharedWfOpts.Type, + wfArgs..., + ) + + // Execute the update with start operation + return cl.UpdateWithStartWorkflow(cctx, client.UpdateWithStartWorkflowOptions{ + StartWorkflowOperation: startOp, + UpdateOptions: updateWfOpts, + }) +} + type workflowJSONResult struct { WorkflowId string `json:"workflowId"` RunId string `json:"runId"` diff --git a/temporalcli/commands.workflow_exec_test.go b/temporalcli/commands.workflow_exec_test.go index e706d9465..9d88a1100 100644 --- a/temporalcli/commands.workflow_exec_test.go +++ b/temporalcli/commands.workflow_exec_test.go @@ -675,8 +675,40 @@ func (s *SharedServerSuite) TestWorkflow_SignalWithStart_WorkflowIDMandatory() { s.ErrorContains(res.Err, "--workflow-id flag must be provided") } -func (s *SharedServerSuite) TestWorkflow_SignalWithStart_StartsWorkflow() { +func (s *SharedServerSuite) TestWorkflow_SignalWithStart_StartNewWorkflow() { + s.testSignalWithStartHelper(false) +} + +func (s *SharedServerSuite) TestWorkflow_SignalWithStart_SendSignalToExistingWorkflow() { + s.testSignalWithStartHelper(true) +} + +func (s *SharedServerSuite) testSignalWithStartHelper(useExistingWorkflow bool) { wfId := uuid.NewString() + signalWfInput := `"workflow-input"` + signalInput := `"signal-input"` + expectedWfOutput := map[string]string{ + "workflow": "workflow-input", + "signal": "signal-input", + } + + if useExistingWorkflow { + run, err := s.Client.ExecuteWorkflow(s.Context, client.StartWorkflowOptions{TaskQueue: s.Worker().Options.TaskQueue}, DevWorkflow, "not-signal-with-start-input") + s.NoError(err) + // Re-assign wfId for the signal to be sent to an existing workflow. + wfId = run.GetID() + expectedWfOutput["workflow"] = "not-signal-with-start-input" + } + + // Run workflow, block on signal. + s.Worker().OnDevWorkflow(func(ctx workflow.Context, wfInput any) (any, error) { + wfState := make(map[string]string) + wfState["workflow"] = wfInput.(string) + var sigReceived string + workflow.GetSignalChannel(ctx, "sigName").Receive(ctx, &sigReceived) + wfState["signal"] = sigReceived + return wfState, nil + }) // Send signal-with-start command. res := s.Execute( @@ -684,84 +716,250 @@ func (s *SharedServerSuite) TestWorkflow_SignalWithStart_StartsWorkflow() { "--address", s.Address(), "--workflow-id", wfId, "--type", "DevWorkflow", - "--input", `{"wf-signal-with-start": "workflow-input"}`, - "--task-queue", "tq", + "--input", signalWfInput, + "--task-queue", s.Worker().Options.TaskQueue, "--signal-name", "sigName", - "--signal-input", `{"signal-with-start": "signal-input"}`, + "--signal-input", signalInput, ) - s.NoError(res.Err) - // Confirm text output has key/vals as expected out := res.Stdout.String() s.ContainsOnSameLine(out, "WorkflowId", wfId) s.Contains(out, "RunId") - s.ContainsOnSameLine(out, "TaskQueue", "tq") s.ContainsOnSameLine(out, "Type", "DevWorkflow") s.ContainsOnSameLine(out, "Namespace", "default") - // Check that new workflow was started with expected workflow ID. - run := s.Client.GetWorkflow(s.Context, wfId, "") - s.Equal(wfId, run.GetID()) - - // Run workflow, block on signal. - var sigReceived any - s.StartDevWorker(s.t, DevWorkerOptions{TaskQueue: "tq"}).OnDevWorkflow(func(ctx workflow.Context, wfInput any) (any, error) { - workflow.GetSignalChannel(ctx, "sigName").Receive(ctx, &sigReceived) - return wfInput, nil - }) + // Check that a new workflow was started with expected workflow ID. + if !useExistingWorkflow { + run := s.Client.GetWorkflow(s.Context, wfId, "") + s.Equal(wfId, run.GetID()) + } // Wait for workflow to complete. - var wfReturn any + wfReturn := make(map[string]string) err := s.Client.GetWorkflow(s.Context, wfId, "").Get(s.Context, &wfReturn) s.NoError(err) - // Expect workflow to have received signal and given inputs from signal-with-start. - s.Equal(map[string]any{"signal-with-start": "signal-input"}, sigReceived) - s.Equal(map[string]any{"wf-signal-with-start": "workflow-input"}, wfReturn) + // Compare the extracted values with what the workflow returned + s.Equal(expectedWfOutput["signal"], wfReturn["signal"]) + s.Equal(expectedWfOutput["workflow"], wfReturn["workflow"]) } -func (s *SharedServerSuite) TestWorkflow_SignalWithStart_ExistingWorkflow() { - // Run workflow, block on signal. - var sigReceived any +func (s *SharedServerSuite) TestWorkflow_StartUpdateWithStart_RuntimeOptionChecks() { + res := s.Execute( + "workflow", "start-update-with-start", + "--type", "wfType", + "--task-queue", "tq", + "--update-name", "updateName", + "--update-wait-for-stage", "accepted", + ) + s.ErrorContains(res.Err, "--workflow-id flag must be provided") + res = s.Execute( + "workflow", "start-update-with-start", + "--type", "wfType", + "--task-queue", "tq", + "--update-name", "updateName", + "--update-wait-for-stage", "accepted", + "--workflow-id", "wfId", + ) + s.ErrorContains(res.Err, "--id-conflict-policy flag must be provided") +} + +func (s *SharedServerSuite) TestWorkflow_ExecuteUpdateWithStart_RuntimeOptionChecks() { + res := s.Execute( + "workflow", "execute-update-with-start", + "--type", "wfType", + "--task-queue", "tq", + "--update-name", "updateName", + ) + s.ErrorContains(res.Err, "--workflow-id flag must be provided") + res = s.Execute( + "workflow", "execute-update-with-start", + "--type", "wfType", + "--task-queue", "tq", + "--update-name", "updateName", + "--workflow-id", "wfId", + ) + s.ErrorContains(res.Err, "--id-conflict-policy flag must be provided") +} + +type updateWithStartTest struct { + updateWithStartSetup + useStart bool + idConflictPolicy string + expectedError string + expectedUpdateResult string + expectedWfOutput map[string]string +} + +type updateWithStartSetup struct { + wfId string + updateName string + updateId string + useExistingWorkflow bool +} + +func (s *SharedServerSuite) TestWorkflow_StartUpdateWithStart_StartsNewWorkflow() { + updateWithStartSetup := s.updateWithStartTestSetup(false) + s.testStartUpdateWithStartHelper(updateWithStartTest{ + updateWithStartSetup: updateWithStartSetup, + useStart: true, + idConflictPolicy: "Fail", + expectedWfOutput: map[string]string{"workflow": "workflow-input", "update": "update-input"}, + }) +} + +func (s *SharedServerSuite) TestWorkflow_StartUpdateWithStart_SendUpdateToExistingWorkflow() { + updateWithStartSetup := s.updateWithStartTestSetup(true) + s.testStartUpdateWithStartHelper(updateWithStartTest{ + updateWithStartSetup: updateWithStartSetup, + useStart: true, + idConflictPolicy: "Fail", + expectedError: "Workflow execution is already running", + }) + s.testStartUpdateWithStartHelper(updateWithStartTest{ + updateWithStartSetup: updateWithStartSetup, + useStart: true, + idConflictPolicy: "UseExisting", + expectedWfOutput: map[string]string{"workflow": "not-update-with-start-workflow-input", "update": "update-input"}, + }) +} + +func (s *SharedServerSuite) TestWorkflow_ExecuteUpdateWithStart_StartsWorkflow() { + updateWithStartSetup := s.updateWithStartTestSetup(false) + s.testStartUpdateWithStartHelper(updateWithStartTest{ + updateWithStartSetup: updateWithStartSetup, + useStart: false, + idConflictPolicy: "Fail", + expectedUpdateResult: "update-input", + expectedWfOutput: map[string]string{"workflow": "workflow-input", "update": "update-input"}, + }) +} + +func (s *SharedServerSuite) TestWorkflow_ExecuteUpdateWithStart_SendUpdateToExistingWorkflow() { + updateWithStartSetup := s.updateWithStartTestSetup(true) + s.testStartUpdateWithStartHelper(updateWithStartTest{ + updateWithStartSetup: updateWithStartSetup, + useStart: false, + idConflictPolicy: "Fail", + expectedError: "Workflow execution is already running", + expectedWfOutput: map[string]string{"workflow": "workflow-input", "update": "update-input"}, + }) + s.testStartUpdateWithStartHelper(updateWithStartTest{ + updateWithStartSetup: updateWithStartSetup, + useStart: false, + idConflictPolicy: "UseExisting", + expectedWfOutput: map[string]string{"workflow": "not-update-with-start-workflow-input", "update": "update-input"}, + }) +} + +func (s *SharedServerSuite) updateWithStartTestSetup(useExistingWorkflow bool) updateWithStartSetup { + wfId := uuid.NewString() + updateName := "test-update-name" + updateId := uuid.NewString() + if useExistingWorkflow { + // Start a workflow with a specific workflow ID. + run, err := s.Client.ExecuteWorkflow( + s.Context, + client.StartWorkflowOptions{ + TaskQueue: s.Worker().Options.TaskQueue, + }, + DevWorkflow, + "not-update-with-start-workflow-input", + ) + s.NoError(err) + // Re-assign wfId for the update to be sent to an existing workflow. + wfId = run.GetID() + } + + // Run workflow. s.Worker().OnDevWorkflow(func(ctx workflow.Context, wfInput any) (any, error) { - workflow.GetSignalChannel(ctx, "sigName").Receive(ctx, &sigReceived) - return wfInput, nil + wfState := make(map[string]string) + wfState["workflow"] = wfInput.(string) + + err := workflow.SetUpdateHandlerWithOptions( + ctx, + updateName, + func(ctx workflow.Context, updateInput string) (string, error) { + wfState["update"] = updateInput + return updateInput, nil + }, + workflow.UpdateHandlerOptions{}, + ) + if err != nil { + return nil, err + } + // Block workflow completion on signal. + workflow.GetSignalChannel(ctx, "complete").Receive(ctx, nil) + return wfState, nil }) + return updateWithStartSetup{wfId, updateName, updateId, useExistingWorkflow} +} - // Start workflow - run, err := s.Client.ExecuteWorkflow(s.Context, client.StartWorkflowOptions{TaskQueue: s.Worker().Options.TaskQueue}, DevWorkflow, "not-signal-with-start-input") - s.NoError(err) +func (s *SharedServerSuite) testStartUpdateWithStartHelper(opts updateWithStartTest) { + cmdName := "execute-update-with-start" + additionalArgs := []string{} - wfId := run.GetID() + if opts.useStart { + cmdName = "start-update-with-start" + additionalArgs = []string{"--update-wait-for-stage", "accepted"} + } - // Send signal-with-start command. - res := s.Execute( - "workflow", "signal-with-start", + baseArgs := []string{ + "workflow", cmdName, "--address", s.Address(), - "--workflow-id", wfId, + "--workflow-id", opts.wfId, "--type", "DevWorkflow", - "--input", `{"workflow": "workflow-input"}`, + "--input", `"workflow-input"`, "--task-queue", s.Worker().Options.TaskQueue, - "--signal-name", "sigName", - "--signal-input", `{"signal-with-start": "signal-input"}`, - ) + "--id-conflict-policy", opts.idConflictPolicy, + "--update-name", opts.updateName, + "--update-id", opts.updateId, + "--update-input", `"update-input"`, + } + + // Send start-update-with-start command. + args := append(baseArgs, additionalArgs...) + res := s.Execute(args...) + + // Check expected error. + if opts.expectedError != "" { + s.ErrorContains(res.Err, opts.expectedError) + return + } + s.NoError(res.Err) // Confirm text output has key/vals as expected out := res.Stdout.String() - s.ContainsOnSameLine(out, "WorkflowId", wfId) + s.ContainsOnSameLine(out, "WorkflowId", opts.wfId) s.Contains(out, "RunId") - s.ContainsOnSameLine(out, "TaskQueue", s.Worker().Options.TaskQueue) s.ContainsOnSameLine(out, "Type", "DevWorkflow") s.ContainsOnSameLine(out, "Namespace", "default") + s.ContainsOnSameLine(out, "UpdateName", opts.updateName) + s.ContainsOnSameLine(out, "UpdateID", opts.updateId) + + // Check expected update result. + if opts.expectedUpdateResult != "" { + s.ContainsOnSameLine(out, "UpdateResult", opts.expectedUpdateResult) + } + + // Check that new workflow was started with expected workflow ID. + if !opts.useExistingWorkflow { + run := s.Client.GetWorkflow(s.Context, opts.wfId, "") + s.Equal(opts.wfId, run.GetID()) + } + + // Send signal to complete workflow. + err := s.Client.SignalWorkflow(s.Context, opts.wfId, "", "complete", nil) + s.NoError(err) // Wait for workflow to complete. - var ret any - s.NoError(run.Get(s.Context, &ret)) + wfReturn := make(map[string]string) + err = s.Client.GetWorkflow(s.Context, opts.wfId, "").Get(s.Context, &wfReturn) + s.NoError(err) - // Expect workflow to have not been started by the signal-with-start command. - s.Equal("not-signal-with-start-input", ret) - // Expect signal to have been received with given input. - s.Equal(map[string]any{"signal-with-start": "signal-input"}, sigReceived) + // Expect workflow to have received update and given inputs from start-update-with-start. + s.Equal(opts.expectedWfOutput["workflow"], wfReturn["workflow"]) + s.Equal(opts.expectedWfOutput["update"], wfReturn["update"]) } diff --git a/temporalcli/commandsgen/commands.yml b/temporalcli/commandsgen/commands.yml index ea676a117..b0e6597a8 100644 --- a/temporalcli/commandsgen/commands.yml +++ b/temporalcli/commandsgen/commands.yml @@ -3673,6 +3673,7 @@ commands: --workflow-id YourWorkflowId \ --name YourUpdate \ --input '{"some-key": "some-value"}' + --wait-for-stage accepted ``` option-sets: - update-starting @@ -3688,6 +3689,163 @@ commands: - accepted required: true + - name: temporal workflow start-update-with-start + summary: Send an Update and wait for it to be accepted or rejected (Experimental) + description: | + Send a message to a Workflow Execution to invoke an Update handler, and wait for + the update to be accepted or rejected. If the Workflow Execution is not running, + then a new workflow execution is started and the update is sent. + + Experimental. + + ``` + temporal workflow start-update-with-start \ + --update-name YourUpdate \ + --update-input '{"update-key": "update-value"}' \ + --update-wait-for-stage accepted \ + --workflow-id YourWorkflowId \ + --type YourWorkflowType \ + --task-queue YourTaskQueue \ + --id-conflict-policy Fail \ + --input '{"wf-key": "wf-value"}' + ``` + option-sets: + # workflow-id and id-conflict-policy are "required" (runtime checks) + - shared-workflow-start + - workflow-start + - payload-input + options: + - name: update-name + type: string + description: Update name. + required: true + aliases: + - update-type + - name: update-first-execution-run-id + type: string + description: | + Parent Run ID. + The update is sent to the last Workflow Execution in the chain started + with this Run ID. + - name: update-wait-for-stage + type: string-enum + description: | + Update stage to wait for. + The only option is `accepted`, but this option is required. This is to allow + a future version of the CLI to choose a default value. + enum-values: + - accepted + required: true + - name: update-id + type: string + description: | + Update ID. + If unset, defaults to a UUID. + - name: run-id + type: string + short: r + description: | + Run ID. + If unset, looks for an Update against the currently-running Workflow Execution. + - name: update-input + type: string[] + description: | + Update input value. + Use JSON content or set --update-input-meta to override. + Can't be combined with --update-input-file. + Can be passed multiple times to pass multiple arguments. + - name: update-input-file + type: string[] + description: | + A path or paths for input file(s). + Use JSON content or set --update-input-meta to override. + Can't be combined with --update-input. + Can be passed multiple times to pass multiple arguments. + - name: update-input-meta + type: string[] + description: | + Input update payload metadata as a `KEY=VALUE` pair. + When the KEY is "encoding", this overrides the default ("json/plain"). + Can be passed multiple times. + - name: update-input-base64 + type: bool + description: | + Assume update inputs are base64-encoded and attempt to decode them. + + - name: temporal workflow execute-update-with-start + summary: Send an Update and wait for it to complete (Experimental) + description: | + Send a message to a Workflow Execution to invoke an Update handler, and wait for + the update to complete. If the Workflow Execution is not running, then a new workflow + execution is started and the update is sent. + + Experimental. + + ``` + temporal workflow execute-update-with-start \ + --update-name YourUpdate \ + --update-input '{"update-key": "update-value"}' \ + --workflow-id YourWorkflowId \ + --type YourWorkflowType \ + --task-queue YourTaskQueue \ + --id-conflict-policy Fail \ + --input '{"wf-key": "wf-value"}' + ``` + + option-sets: + # workflow-id and id-conflict-policy are "required" (runtime checks) + - shared-workflow-start + - workflow-start + - payload-input + options: + - name: update-name + type: string + description: Update name. + required: true + aliases: + - update-type + - name: update-first-execution-run-id + type: string + description: | + Parent Run ID. + The update is sent to the last Workflow Execution in the chain started + with this Run ID. + - name: update-id + type: string + description: | + Update ID. + If unset, defaults to a UUID. + - name: run-id + type: string + short: r + description: | + Run ID. + If unset, looks for an Update against the currently-running Workflow Execution. + - name: update-input + type: string[] + description: | + Update input value. + Use JSON content or set --update-input-meta to override. + Can't be combined with --update-input-file. + Can be passed multiple times to pass multiple arguments. + - name: update-input-file + type: string[] + description: | + A path or paths for input file(s). + Use JSON content or set --update-input-meta to override. + Can't be combined with --update-input. + Can be passed multiple times to pass multiple arguments. + - name: update-input-meta + type: string[] + description: | + Input update payload metadata as a `KEY=VALUE` pair. + When the KEY is "encoding", this overrides the default ("json/plain"). + Can be passed multiple times. + - name: update-input-base64 + type: bool + description: | + Assume update inputs are base64-encoded and attempt to decode them. + option-sets: - name: client options: From 57e8cecf5ecd6a69d77edc7aaa190036588eb257 Mon Sep 17 00:00:00 2001 From: Jacob Barzee Date: Wed, 5 Mar 2025 15:46:59 -0700 Subject: [PATCH 05/11] quote attribute type to make whitespace more obvious (#772) ## What was changed quote attribute type in error message ## Why? To make whitespace more obvious --------- Co-authored-by: Rodrigo Zhou <2068124+rodrigozhou@users.noreply.github.com> --- temporalcli/commands.operator_search_attribute.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/temporalcli/commands.operator_search_attribute.go b/temporalcli/commands.operator_search_attribute.go index 405a31b85..afdca478c 100644 --- a/temporalcli/commands.operator_search_attribute.go +++ b/temporalcli/commands.operator_search_attribute.go @@ -60,7 +60,7 @@ func searchAttributeTypeStringToEnum(search string) (enums.IndexedValueType, err return enums.IndexedValueType(v), nil } } - return enums.INDEXED_VALUE_TYPE_UNSPECIFIED, fmt.Errorf("unsupported search attribute type: %v", search) + return enums.INDEXED_VALUE_TYPE_UNSPECIFIED, fmt.Errorf("unsupported search attribute type: %q", search) } func (c *TemporalOperatorSearchAttributeRemoveCommand) run(cctx *CommandContext, args []string) error { From 1a88da6ffe6b2957f13ca3ec9954e4b549ec3948 Mon Sep 17 00:00:00 2001 From: Yuri Date: Fri, 7 Mar 2025 12:34:07 -0800 Subject: [PATCH 06/11] Fix for DescribeWorkflow (#773) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What was changed Check if extended info is not nil. ## Why? https://github.com/temporalio/cli/pull/771 Code assumes that some extended info exists in proto. Which is not true for older server versions.. --- temporalcli/commands.workflow_view.go | 85 +++++++++++++++------------ 1 file changed, 46 insertions(+), 39 deletions(-) diff --git a/temporalcli/commands.workflow_view.go b/temporalcli/commands.workflow_view.go index 75f1db34e..94e721dec 100644 --- a/temporalcli/commands.workflow_view.go +++ b/temporalcli/commands.workflow_view.go @@ -102,49 +102,56 @@ func (c *TemporalWorkflowDescribeCommand) run(cctx *CommandContext, args []strin cctx.Printer.Println(color.MagentaString("Execution Info:")) info := resp.WorkflowExecutionInfo - extendedInfo := resp.WorkflowExtendedInfo _ = cctx.Printer.PrintStructured(struct { - WorkflowId string - RunId string - Type string - Namespace string - TaskQueue string - AssignedBuildId string - StartTime time.Time - CloseTime time.Time `cli:",cardOmitEmpty"` - ExecutionTime time.Time `cli:",cardOmitEmpty"` - Memo map[string]*common.Payload `cli:",cardOmitEmpty"` - SearchAttributes map[string]*common.Payload `cli:",cardOmitEmpty"` - StateTransitionCount int64 - HistoryLength int64 - HistorySize int64 - ExecutionExpirationTime time.Time `cli:",cardOmitEmpty"` - RunExpirationTime time.Time `cli:",cardOmitEmpty"` - CancelRequested bool - LastResetTime time.Time `cli:",cardOmitEmpty"` - OriginalStartTime time.Time `cli:",cardOmitEmpty"` + WorkflowId string + RunId string + Type string + Namespace string + TaskQueue string + AssignedBuildId string + StartTime time.Time + CloseTime time.Time `cli:",cardOmitEmpty"` + ExecutionTime time.Time `cli:",cardOmitEmpty"` + Memo map[string]*common.Payload `cli:",cardOmitEmpty"` + SearchAttributes map[string]*common.Payload `cli:",cardOmitEmpty"` + StateTransitionCount int64 + HistoryLength int64 + HistorySize int64 }{ - WorkflowId: info.Execution.WorkflowId, - RunId: info.Execution.RunId, - Type: info.Type.GetName(), - Namespace: c.Parent.Namespace, - TaskQueue: info.TaskQueue, - AssignedBuildId: info.GetAssignedBuildId(), - StartTime: timestampToTime(info.StartTime), - CloseTime: timestampToTime(info.CloseTime), - ExecutionTime: timestampToTime(info.ExecutionTime), - Memo: info.Memo.GetFields(), - SearchAttributes: info.SearchAttributes.GetIndexedFields(), - StateTransitionCount: info.StateTransitionCount, - HistoryLength: info.HistoryLength, - HistorySize: info.HistorySizeBytes, - ExecutionExpirationTime: timestampToTime(extendedInfo.ExecutionExpirationTime), - RunExpirationTime: timestampToTime(extendedInfo.RunExpirationTime), - CancelRequested: extendedInfo.CancelRequested, - LastResetTime: timestampToTime(extendedInfo.LastResetTime), - OriginalStartTime: timestampToTime(extendedInfo.OriginalStartTime), + WorkflowId: info.Execution.WorkflowId, + RunId: info.Execution.RunId, + Type: info.Type.GetName(), + Namespace: c.Parent.Namespace, + TaskQueue: info.TaskQueue, + AssignedBuildId: info.GetAssignedBuildId(), + StartTime: timestampToTime(info.StartTime), + CloseTime: timestampToTime(info.CloseTime), + ExecutionTime: timestampToTime(info.ExecutionTime), + Memo: info.Memo.GetFields(), + SearchAttributes: info.SearchAttributes.GetIndexedFields(), + StateTransitionCount: info.StateTransitionCount, + HistoryLength: info.HistoryLength, + HistorySize: info.HistorySizeBytes, }, printer.StructuredOptions{}) + extendedInfo := resp.WorkflowExtendedInfo + if extendedInfo != nil { + cctx.Printer.Println(color.MagentaString("Extended Execution Info:")) + _ = cctx.Printer.PrintStructured(struct { + CancelRequested bool + ExecutionExpirationTime time.Time `cli:",cardOmitEmpty"` + RunExpirationTime time.Time `cli:",cardOmitEmpty"` + LastResetTime time.Time `cli:",cardOmitEmpty"` + OriginalStartTime time.Time `cli:",cardOmitEmpty"` + }{ + CancelRequested: extendedInfo.CancelRequested, + ExecutionExpirationTime: timestampToTime(extendedInfo.ExecutionExpirationTime), + RunExpirationTime: timestampToTime(extendedInfo.RunExpirationTime), + LastResetTime: timestampToTime(extendedInfo.LastResetTime), + OriginalStartTime: timestampToTime(extendedInfo.OriginalStartTime), + }, printer.StructuredOptions{}) + } + staticSummary := resp.GetExecutionConfig().GetUserMetadata().GetSummary() staticDetails := resp.GetExecutionConfig().GetUserMetadata().GetDetails() if len(staticSummary.GetData()) > 0 || len(staticDetails.GetData()) > 0 { From cbd133b524e4a2f82f5075cc4c50cfa69fdbac91 Mon Sep 17 00:00:00 2001 From: Spencer Judge Date: Tue, 25 Mar 2025 19:03:18 +0000 Subject: [PATCH 07/11] Expose parent and root execution in describe call (#781) --- temporalcli/commands.workflow_view.go | 8 +++ temporalcli/commands.workflow_view_test.go | 61 ++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/temporalcli/commands.workflow_view.go b/temporalcli/commands.workflow_view.go index 94e721dec..9bfb5337f 100644 --- a/temporalcli/commands.workflow_view.go +++ b/temporalcli/commands.workflow_view.go @@ -117,6 +117,10 @@ func (c *TemporalWorkflowDescribeCommand) run(cctx *CommandContext, args []strin StateTransitionCount int64 HistoryLength int64 HistorySize int64 + ParentWorkflowId string `cli:",cardOmitEmpty"` + ParentRunId string `cli:",cardOmitEmpty"` + RootWorkflowId string `cli:",cardOmitEmpty"` + RootRunId string `cli:",cardOmitEmpty"` }{ WorkflowId: info.Execution.WorkflowId, RunId: info.Execution.RunId, @@ -132,6 +136,10 @@ func (c *TemporalWorkflowDescribeCommand) run(cctx *CommandContext, args []strin StateTransitionCount: info.StateTransitionCount, HistoryLength: info.HistoryLength, HistorySize: info.HistorySizeBytes, + ParentWorkflowId: info.GetParentExecution().GetWorkflowId(), + ParentRunId: info.GetParentExecution().GetRunId(), + RootWorkflowId: info.GetRootExecution().GetWorkflowId(), + RootRunId: info.GetRootExecution().GetRunId(), }, printer.StructuredOptions{}) extendedInfo := resp.WorkflowExtendedInfo diff --git a/temporalcli/commands.workflow_view_test.go b/temporalcli/commands.workflow_view_test.go index 31bfc96af..a758b7815 100644 --- a/temporalcli/commands.workflow_view_test.go +++ b/temporalcli/commands.workflow_view_test.go @@ -993,3 +993,64 @@ func (s *SharedServerSuite) TestWorkflow_Describe_WorkflowMetadata() { s.NotNil(jsonOut.ExecutionConfig.UserMetadata.Summary) s.NotNil(jsonOut.ExecutionConfig.UserMetadata.Details) } + +func (s *SharedServerSuite) TestWorkflow_Describe_RootWorkflow() { + s.Worker().OnDevWorkflow(func(ctx workflow.Context, input any) (any, error) { + if input.(string) == "child" { + return "done", nil + } + ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{ + StartToCloseTimeout: 10 * time.Second, + }) + childHandle := workflow.ExecuteChildWorkflow(ctx, DevWorkflow, "child") + var childWE workflow.Execution + err := childHandle.GetChildWorkflowExecution().Get(ctx, &childWE) + if err != nil { + return nil, err + } + err = childHandle.Get(ctx, nil) + if err != nil { + return nil, err + } + return childWE.ID, err + }) + + run, err := s.Client.ExecuteWorkflow( + s.Context, + client.StartWorkflowOptions{TaskQueue: s.Worker().Options.TaskQueue}, + DevWorkflow, + "ignored", + ) + s.NoError(err) + var wfRes string + err = run.Get(s.Context, &wfRes) + s.NoError(err) + + // Text + res := s.Execute( + "workflow", "describe", + "--address", s.Address(), + "-w", wfRes, + ) + s.NoError(res.Err) + out := res.Stdout.String() + s.ContainsOnSameLine(out, "ParentWorkflowId", run.GetID()) + s.ContainsOnSameLine(out, "ParentRunId", run.GetRunID()) + s.ContainsOnSameLine(out, "RootWorkflowId", run.GetID()) + s.ContainsOnSameLine(out, "RootRunId", run.GetRunID()) + + // JSON + res = s.Execute( + "workflow", "describe", + "-o", "json", + "--address", s.Address(), + "-w", wfRes, + ) + s.NoError(res.Err) + var jsonOut workflowservice.DescribeWorkflowExecutionResponse + s.NoError(temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonOut, true)) + s.Equal(run.GetID(), jsonOut.WorkflowExecutionInfo.ParentExecution.GetWorkflowId()) + s.Equal(run.GetRunID(), jsonOut.WorkflowExecutionInfo.ParentExecution.GetRunId()) + s.Equal(run.GetID(), jsonOut.WorkflowExecutionInfo.RootExecution.GetWorkflowId()) + s.Equal(run.GetRunID(), jsonOut.WorkflowExecutionInfo.RootExecution.GetRunId()) +} From 99210f3dec51a7e3b4d20df96e510ae3ee2f3c27 Mon Sep 17 00:00:00 2001 From: Dan Davison Date: Thu, 27 Mar 2025 07:55:48 -0400 Subject: [PATCH 08/11] Remove experimental notice on Update (#782) --- temporalcli/commands.gen.go | 32 ++++++++++++++-------------- temporalcli/commandsgen/commands.yml | 24 ++++++--------------- 2 files changed, 23 insertions(+), 33 deletions(-) diff --git a/temporalcli/commands.gen.go b/temporalcli/commands.gen.go index 45a4069ca..d67c6c433 100644 --- a/temporalcli/commands.gen.go +++ b/temporalcli/commands.gen.go @@ -3049,7 +3049,7 @@ func NewTemporalWorkflowExecuteUpdateWithStartCommand(cctx *CommandContext, pare s.Parent = parent s.Command.DisableFlagsInUseLine = true s.Command.Use = "execute-update-with-start [flags]" - s.Command.Short = "Send an Update and wait for it to complete (Experimental)" + s.Command.Short = "Send an Update-With-Start and wait for it to complete (Experimental)" if hasHighlighting { s.Command.Long = "Send a message to a Workflow Execution to invoke an Update handler, and wait for\nthe update to complete. If the Workflow Execution is not running, then a new workflow\nexecution is started and the update is sent.\n\nExperimental.\n\n\x1b[1mtemporal workflow execute-update-with-start \\\n --update-name YourUpdate \\\n --update-input '{\"update-key\": \"update-value\"}' \\\n --workflow-id YourWorkflowId \\\n --type YourWorkflowType \\\n --task-queue YourTaskQueue \\\n --id-conflict-policy Fail \\\n --input '{\"wf-key\": \"wf-value\"}'\x1b[0m" } else { @@ -3483,7 +3483,7 @@ func NewTemporalWorkflowStartUpdateWithStartCommand(cctx *CommandContext, parent s.Parent = parent s.Command.DisableFlagsInUseLine = true s.Command.Use = "start-update-with-start [flags]" - s.Command.Short = "Send an Update and wait for it to be accepted or rejected (Experimental)" + s.Command.Short = "Send an Update-With-Start and wait for it to be accepted or rejected (Experimental)" if hasHighlighting { s.Command.Long = "Send a message to a Workflow Execution to invoke an Update handler, and wait for\nthe update to be accepted or rejected. If the Workflow Execution is not running, \nthen a new workflow execution is started and the update is sent.\n\nExperimental.\n\n\x1b[1mtemporal workflow start-update-with-start \\\n --update-name YourUpdate \\\n --update-input '{\"update-key\": \"update-value\"}' \\\n --update-wait-for-stage accepted \\\n --workflow-id YourWorkflowId \\\n --type YourWorkflowType \\\n --task-queue YourTaskQueue \\\n --id-conflict-policy Fail \\\n --input '{\"wf-key\": \"wf-value\"}'\x1b[0m" } else { @@ -3598,8 +3598,8 @@ func NewTemporalWorkflowUpdateCommand(cctx *CommandContext, parent *TemporalWork var s TemporalWorkflowUpdateCommand s.Parent = parent s.Command.Use = "update" - s.Command.Short = "Updates (Experimental)" - s.Command.Long = "An Update is a synchronous call to a Workflow Execution that can change its\nstate, control its flow, and return a result.\n\nExperimental." + s.Command.Short = "Send and interact with Updates" + s.Command.Long = "An Update is a synchronous call to a Workflow Execution that can change its\nstate, control its flow, and return a result." s.Command.Args = cobra.NoArgs s.Command.AddCommand(&NewTemporalWorkflowUpdateDescribeCommand(cctx, &s).Command) s.Command.AddCommand(&NewTemporalWorkflowUpdateExecuteCommand(cctx, &s).Command) @@ -3619,11 +3619,11 @@ func NewTemporalWorkflowUpdateDescribeCommand(cctx *CommandContext, parent *Temp s.Parent = parent s.Command.DisableFlagsInUseLine = true s.Command.Use = "describe [flags]" - s.Command.Short = "Obtain status info about a specific Update (Experimental)" + s.Command.Short = "Obtain status info about a specific Update" if hasHighlighting { - s.Command.Long = "Given a Workflow Execution and an Update ID, return information about its current status, including\na result if it has finished.\n\nExperimental.\n\n\x1b[1mtemporal workflow update describe \\\n --workflow-id YourWorkflowId \\\n --update-id YourUpdateId\x1b[0m" + s.Command.Long = "Given a Workflow Execution and an Update ID, return information about its current status, including\na result if it has finished.\n\n\x1b[1mtemporal workflow update describe \\\n --workflow-id YourWorkflowId \\\n --update-id YourUpdateId\x1b[0m" } else { - s.Command.Long = "Given a Workflow Execution and an Update ID, return information about its current status, including\na result if it has finished.\n\nExperimental.\n\n```\ntemporal workflow update describe \\\n --workflow-id YourWorkflowId \\\n --update-id YourUpdateId\n```" + s.Command.Long = "Given a Workflow Execution and an Update ID, return information about its current status, including\na result if it has finished.\n\n```\ntemporal workflow update describe \\\n --workflow-id YourWorkflowId \\\n --update-id YourUpdateId\n```" } s.Command.Args = cobra.NoArgs s.UpdateTargetingOptions.buildFlags(cctx, s.Command.Flags()) @@ -3647,11 +3647,11 @@ func NewTemporalWorkflowUpdateExecuteCommand(cctx *CommandContext, parent *Tempo s.Parent = parent s.Command.DisableFlagsInUseLine = true s.Command.Use = "execute [flags]" - s.Command.Short = "Send an Update and wait for it to complete (Experimental)" + s.Command.Short = "Send an Update and wait for it to complete" if hasHighlighting { - s.Command.Long = "Send a message to a Workflow Execution to invoke an Update handler, and wait for\nthe update to complete or fail. You can also use this to wait for an existing\nupdate to complete, by submitting an existing update ID.\n\nExperimental.\n\n\x1b[1mtemporal workflow update execute \\\n --workflow-id YourWorkflowId \\\n --name YourUpdate \\\n --input '{\"some-key\": \"some-value\"}'\x1b[0m" + s.Command.Long = "Send a message to a Workflow Execution to invoke an Update handler, and wait for\nthe update to complete or fail. You can also use this to wait for an existing\nupdate to complete, by submitting an existing update ID.\n\n\x1b[1mtemporal workflow update execute \\\n --workflow-id YourWorkflowId \\\n --name YourUpdate \\\n --input '{\"some-key\": \"some-value\"}'\x1b[0m" } else { - s.Command.Long = "Send a message to a Workflow Execution to invoke an Update handler, and wait for\nthe update to complete or fail. You can also use this to wait for an existing\nupdate to complete, by submitting an existing update ID.\n\nExperimental.\n\n```\ntemporal workflow update execute \\\n --workflow-id YourWorkflowId \\\n --name YourUpdate \\\n --input '{\"some-key\": \"some-value\"}'\n```" + s.Command.Long = "Send a message to a Workflow Execution to invoke an Update handler, and wait for\nthe update to complete or fail. You can also use this to wait for an existing\nupdate to complete, by submitting an existing update ID.\n\n```\ntemporal workflow update execute \\\n --workflow-id YourWorkflowId \\\n --name YourUpdate \\\n --input '{\"some-key\": \"some-value\"}'\n```" } s.Command.Args = cobra.NoArgs s.UpdateStartingOptions.buildFlags(cctx, s.Command.Flags()) @@ -3678,11 +3678,11 @@ func NewTemporalWorkflowUpdateResultCommand(cctx *CommandContext, parent *Tempor s.Parent = parent s.Command.DisableFlagsInUseLine = true s.Command.Use = "result [flags]" - s.Command.Short = "Wait for a specific Update to complete (Experimental)" + s.Command.Short = "Wait for a specific Update to complete" if hasHighlighting { - s.Command.Long = "Given a Workflow Execution and an Update ID, wait for the Update to complete or fail and\nprint the result.\n\nExperimental.\n\n\x1b[1mtemporal workflow update result \\\n --workflow-id YourWorkflowId \\\n --update-id YourUpdateId\x1b[0m" + s.Command.Long = "Given a Workflow Execution and an Update ID, wait for the Update to complete or fail and\nprint the result.\n\n\x1b[1mtemporal workflow update result \\\n --workflow-id YourWorkflowId \\\n --update-id YourUpdateId\x1b[0m" } else { - s.Command.Long = "Given a Workflow Execution and an Update ID, wait for the Update to complete or fail and\nprint the result.\n\nExperimental.\n\n```\ntemporal workflow update result \\\n --workflow-id YourWorkflowId \\\n --update-id YourUpdateId\n```" + s.Command.Long = "Given a Workflow Execution and an Update ID, wait for the Update to complete or fail and\nprint the result.\n\n```\ntemporal workflow update result \\\n --workflow-id YourWorkflowId \\\n --update-id YourUpdateId\n```" } s.Command.Args = cobra.NoArgs s.UpdateTargetingOptions.buildFlags(cctx, s.Command.Flags()) @@ -3707,11 +3707,11 @@ func NewTemporalWorkflowUpdateStartCommand(cctx *CommandContext, parent *Tempora s.Parent = parent s.Command.DisableFlagsInUseLine = true s.Command.Use = "start [flags]" - s.Command.Short = "Send an Update and wait for it to be accepted or rejected (Experimental)" + s.Command.Short = "Send an Update and wait for it to be accepted or rejected" if hasHighlighting { - s.Command.Long = "Send a message to a Workflow Execution to invoke an Update handler, and wait for\nthe update to be accepted or rejected. You can subsequently wait for the update\nto complete by using \x1b[1mtemporal workflow update execute\x1b[0m.\n\nExperimental.\n\n\x1b[1mtemporal workflow update start \\\n --workflow-id YourWorkflowId \\\n --name YourUpdate \\\n --input '{\"some-key\": \"some-value\"}'\n --wait-for-stage accepted\x1b[0m" + s.Command.Long = "Send a message to a Workflow Execution to invoke an Update handler, and wait for\nthe update to be accepted or rejected. You can subsequently wait for the update\nto complete by using \x1b[1mtemporal workflow update execute\x1b[0m.\n\n\x1b[1mtemporal workflow update start \\\n --workflow-id YourWorkflowId \\\n --name YourUpdate \\\n --input '{\"some-key\": \"some-value\"}'\n --wait-for-stage accepted\x1b[0m" } else { - s.Command.Long = "Send a message to a Workflow Execution to invoke an Update handler, and wait for\nthe update to be accepted or rejected. You can subsequently wait for the update\nto complete by using `temporal workflow update execute`.\n\nExperimental.\n\n```\ntemporal workflow update start \\\n --workflow-id YourWorkflowId \\\n --name YourUpdate \\\n --input '{\"some-key\": \"some-value\"}'\n --wait-for-stage accepted\n```" + s.Command.Long = "Send a message to a Workflow Execution to invoke an Update handler, and wait for\nthe update to be accepted or rejected. You can subsequently wait for the update\nto complete by using `temporal workflow update execute`.\n\n```\ntemporal workflow update start \\\n --workflow-id YourWorkflowId \\\n --name YourUpdate \\\n --input '{\"some-key\": \"some-value\"}'\n --wait-for-stage accepted\n```" } s.Command.Args = cobra.NoArgs s.WaitForStage = NewStringEnum([]string{"accepted"}, "") diff --git a/temporalcli/commandsgen/commands.yml b/temporalcli/commandsgen/commands.yml index b0e6597a8..2e94dad79 100644 --- a/temporalcli/commandsgen/commands.yml +++ b/temporalcli/commandsgen/commands.yml @@ -3601,21 +3601,17 @@ commands: - workflow-reference - name: temporal workflow update - summary: Updates (Experimental) + summary: Send and interact with Updates description: | An Update is a synchronous call to a Workflow Execution that can change its state, control its flow, and return a result. - Experimental. - - name: temporal workflow update describe - summary: Obtain status info about a specific Update (Experimental) + summary: Obtain status info about a specific Update description: | Given a Workflow Execution and an Update ID, return information about its current status, including a result if it has finished. - Experimental. - ``` temporal workflow update describe \ --workflow-id YourWorkflowId \ @@ -3625,14 +3621,12 @@ commands: - update-targeting - name: temporal workflow update execute - summary: Send an Update and wait for it to complete (Experimental) + summary: Send an Update and wait for it to complete description: | Send a message to a Workflow Execution to invoke an Update handler, and wait for the update to complete or fail. You can also use this to wait for an existing update to complete, by submitting an existing update ID. - Experimental. - ``` temporal workflow update execute \ --workflow-id YourWorkflowId \ @@ -3644,13 +3638,11 @@ commands: - payload-input - name: temporal workflow update result - summary: Wait for a specific Update to complete (Experimental) + summary: Wait for a specific Update to complete description: | Given a Workflow Execution and an Update ID, wait for the Update to complete or fail and print the result. - Experimental. - ``` temporal workflow update result \ --workflow-id YourWorkflowId \ @@ -3660,14 +3652,12 @@ commands: - update-targeting - name: temporal workflow update start - summary: Send an Update and wait for it to be accepted or rejected (Experimental) + summary: Send an Update and wait for it to be accepted or rejected description: | Send a message to a Workflow Execution to invoke an Update handler, and wait for the update to be accepted or rejected. You can subsequently wait for the update to complete by using `temporal workflow update execute`. - Experimental. - ``` temporal workflow update start \ --workflow-id YourWorkflowId \ @@ -3690,7 +3680,7 @@ commands: required: true - name: temporal workflow start-update-with-start - summary: Send an Update and wait for it to be accepted or rejected (Experimental) + summary: Send an Update-With-Start and wait for it to be accepted or rejected (Experimental) description: | Send a message to a Workflow Execution to invoke an Update handler, and wait for the update to be accepted or rejected. If the Workflow Execution is not running, @@ -3773,7 +3763,7 @@ commands: Assume update inputs are base64-encoded and attempt to decode them. - name: temporal workflow execute-update-with-start - summary: Send an Update and wait for it to complete (Experimental) + summary: Send an Update-With-Start and wait for it to complete (Experimental) description: | Send a message to a Workflow Execution to invoke an Update handler, and wait for the update to complete. If the Workflow Execution is not running, then a new workflow From a466ce097c0d31736add4a2016f7ec5ccce89544 Mon Sep 17 00:00:00 2001 From: Andrew Yuan Date: Fri, 28 Mar 2025 12:21:51 -0700 Subject: [PATCH 09/11] Pin modernc/sqlite version 1.34.1 (#784) ## What was changed Pinned v1.34.1 for modernc/sqlite ## Why? 1.34.2 has a regression, waiting on https://gitlab.com/cznic/sqlite/-/issues/196 to be resolved. See https://github.com/temporalio/temporal/pull/7333 for more details ## Checklist 1. Closes #777 2. How was this tested: 3. Any docs updates needed? --- .github/workflows/ci.yaml | 2 +- cmd/temporal/main.go | 3 + go.mod | 122 ++++++++-------- go.sum | 278 ++++++++++++++++++------------------- temporalcli/sqlite_test.go | 23 +++ 5 files changed, 228 insertions(+), 200 deletions(-) create mode 100644 temporalcli/sqlite_test.go diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index dec27bbdf..ee1a773a1 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -8,7 +8,7 @@ on: jobs: build-test: strategy: - fail-fast: true + fail-fast: false matrix: os: [ubuntu-latest, macos-latest, macos-13, windows-latest, ubuntu-arm] include: diff --git a/cmd/temporal/main.go b/cmd/temporal/main.go index 27a4c4f4e..82203bf0c 100644 --- a/cmd/temporal/main.go +++ b/cmd/temporal/main.go @@ -5,6 +5,9 @@ import ( "github.com/temporalio/cli/temporalcli" + // Prevent the pinned version of sqlite driver from unintentionally changing + // until https://gitlab.com/cznic/sqlite/-/issues/196 is resolved. + _ "modernc.org/sqlite" // Embed time zone database as a fallback if platform database can't be found _ "time/tzdata" ) diff --git a/go.mod b/go.mod index f251a0628..29df67da3 100644 --- a/go.mod +++ b/go.mod @@ -11,31 +11,32 @@ require ( github.com/mattn/go-isatty v0.0.20 github.com/nexus-rpc/sdk-go v0.3.0 github.com/olekukonko/tablewriter v0.0.5 - github.com/spf13/cobra v1.8.1 + github.com/spf13/cobra v1.9.1 github.com/spf13/pflag v1.0.6 github.com/stretchr/testify v1.10.0 github.com/temporalio/ui-server/v2 v2.36.0 - go.temporal.io/api v1.45.0 + go.temporal.io/api v1.46.0 go.temporal.io/sdk v1.33.0 go.temporal.io/server v1.27.1 - google.golang.org/grpc v1.70.0 - google.golang.org/protobuf v1.36.5 + google.golang.org/grpc v1.71.0 + google.golang.org/protobuf v1.36.6 gopkg.in/yaml.v3 v3.0.1 + modernc.org/sqlite v1.34.1 ) require ( - cel.dev/expr v0.20.0 // indirect - cloud.google.com/go v0.118.2 // indirect - cloud.google.com/go/auth v0.14.1 // indirect - cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect + cel.dev/expr v0.22.1 // indirect + cloud.google.com/go v0.120.0 // indirect + cloud.google.com/go/auth v0.15.0 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.6.0 // indirect - cloud.google.com/go/iam v1.4.0 // indirect - cloud.google.com/go/monitoring v1.24.0 // indirect - cloud.google.com/go/storage v1.50.0 // indirect + cloud.google.com/go/iam v1.4.2 // indirect + cloud.google.com/go/monitoring v1.24.1 // indirect + cloud.google.com/go/storage v1.51.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.26.0 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 // indirect github.com/apache/thrift v0.21.0 // indirect github.com/aws/aws-sdk-go v1.55.6 // indirect github.com/benbjohnson/clock v1.3.5 // indirect @@ -45,8 +46,8 @@ require ( github.com/cactus/go-statsd-client/v5 v5.1.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42 // indirect - github.com/coreos/go-oidc/v3 v3.11.0 // indirect + github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f // indirect + github.com/coreos/go-oidc/v3 v3.13.0 // indirect github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect @@ -56,34 +57,35 @@ require ( github.com/go-jose/go-jose/v4 v4.0.5 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-sql-driver/mysql v1.9.0 // indirect + github.com/go-sql-driver/mysql v1.9.1 // indirect github.com/gocql/gocql v1.7.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt v3.2.2+incompatible // indirect - github.com/golang-jwt/jwt/v4 v4.5.1 // indirect + github.com/golang-jwt/jwt/v4 v4.5.2 // indirect github.com/golang/mock v1.7.0-rc.1 // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/gomarkdown/markdown v0.0.0-20241105142532-d03b89096d81 // indirect + github.com/golang/snappy v1.0.0 // indirect + github.com/gomarkdown/markdown v0.0.0-20250311123330-531bef5e742b // indirect + github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e // indirect github.com/google/s2a-go v0.1.9 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect github.com/googleapis/gax-go/v2 v2.14.1 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/securecookie v1.1.2 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect - github.com/jackc/pgx/v5 v5.7.2 // indirect + github.com/jackc/pgx/v5 v5.7.4 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmoiron/sqlx v1.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/compress v1.18.0 // indirect - github.com/labstack/echo/v4 v4.9.1 // indirect - github.com/labstack/gommon v0.4.0 // indirect + github.com/labstack/echo/v4 v4.13.3 // indirect + github.com/labstack/gommon v0.4.2 // indirect github.com/lib/pq v1.10.9 // indirect github.com/mailru/easyjson v0.9.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect @@ -97,10 +99,10 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.21.0 // indirect + github.com/prometheus/client_golang v1.21.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.62.0 // indirect - github.com/prometheus/procfs v0.15.1 // indirect + github.com/prometheus/common v0.63.0 // indirect + github.com/prometheus/procfs v0.16.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rivo/uniseg v0.4.7 // indirect @@ -116,45 +118,49 @@ require ( github.com/uber-common/bark v1.3.0 // indirect github.com/uber-go/tally/v4 v4.1.17-0.20240412215630-22fe011f5ff0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasttemplate v1.2.1 // indirect + github.com/valyala/fasttemplate v1.2.2 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/detectors/gcp v1.34.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect - go.opentelemetry.io/otel v1.34.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect - go.opentelemetry.io/otel/exporters/prometheus v0.56.0 // indirect - go.opentelemetry.io/otel/metric v1.34.0 // indirect - go.opentelemetry.io/otel/sdk v1.34.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect - go.opentelemetry.io/otel/trace v1.34.0 // indirect + go.opentelemetry.io/contrib/detectors/gcp v1.35.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect + go.opentelemetry.io/otel v1.35.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 // indirect + go.opentelemetry.io/otel/exporters/prometheus v0.57.0 // indirect + go.opentelemetry.io/otel/metric v1.35.0 // indirect + go.opentelemetry.io/otel/sdk v1.35.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect + go.opentelemetry.io/otel/trace v1.35.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect go.temporal.io/version v0.3.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.18.0 // indirect + go.uber.org/dig v1.18.1 // indirect go.uber.org/fx v1.23.0 // indirect go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.33.0 // indirect - golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa // indirect - golang.org/x/net v0.35.0 // indirect - golang.org/x/oauth2 v0.26.0 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.22.0 // indirect - golang.org/x/time v0.10.0 // indirect - google.golang.org/api v0.222.0 // indirect - google.golang.org/genproto v0.0.0-20250218202821-56aae31c358a // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect + golang.org/x/net v0.38.0 // indirect + golang.org/x/oauth2 v0.28.0 // indirect + golang.org/x/sync v0.12.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/text v0.23.0 // indirect + golang.org/x/time v0.11.0 // indirect + google.golang.org/api v0.228.0 // indirect + google.golang.org/genproto v0.0.0-20250324211829-b45e905df463 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/validator.v2 v2.0.1 // indirect - modernc.org/libc v1.61.11 // indirect + modernc.org/cc/v4 v4.25.2 // indirect + modernc.org/gc/v2 v2.6.5 // indirect + modernc.org/gc/v3 v3.0.0 // indirect + modernc.org/libc v1.55.3 // indirect modernc.org/mathutil v1.7.1 // indirect - modernc.org/memory v1.8.2 // indirect - modernc.org/sqlite v1.34.5 // indirect + modernc.org/memory v1.9.1 // indirect + modernc.org/strutil v1.2.1 // indirect + modernc.org/token v1.1.0 // indirect ) diff --git a/go.sum b/go.sum index 62d3e7b05..c8a7eea02 100644 --- a/go.sum +++ b/go.sum @@ -1,24 +1,24 @@ -cel.dev/expr v0.20.0 h1:OunBvVCfvpWlt4dN7zg3FM6TDkzOePe1+foGJ9AXeeI= -cel.dev/expr v0.20.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +cel.dev/expr v0.22.1 h1:xoFEsNh972Yzey8N9TCPx2nDvMN7TMhQEzxLuj/iRrI= +cel.dev/expr v0.22.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.118.2 h1:bKXO7RXMFDkniAAvvuMrAPtQ/VHrs9e7J5UT3yrGdTY= -cloud.google.com/go v0.118.2/go.mod h1:CFO4UPEPi8oV21xoezZCrd3d81K4fFkDTEJu4R8K+9M= -cloud.google.com/go/auth v0.14.1 h1:AwoJbzUdxA/whv1qj3TLKwh3XX5sikny2fc40wUl+h0= -cloud.google.com/go/auth v0.14.1/go.mod h1:4JHUxlGXisL0AW8kXPtUF6ztuOksyfUQNFjfsOCXkPM= -cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M= -cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc= +cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA= +cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q= +cloud.google.com/go/auth v0.15.0 h1:Ly0u4aA5vG/fsSsxu98qCQBemXtAtJf+95z9HK+cxps= +cloud.google.com/go/auth v0.15.0/go.mod h1:WJDGqZ1o9E9wKIL+IwStfyn/+s59zl4Bi+1KQNVXLZ8= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= -cloud.google.com/go/iam v1.4.0 h1:ZNfy/TYfn2uh/ukvhp783WhnbVluqf/tzOaqVUPlIPA= -cloud.google.com/go/iam v1.4.0/go.mod h1:gMBgqPaERlriaOV0CUl//XUzDhSfXevn4OEUbg6VRs4= +cloud.google.com/go/iam v1.4.2 h1:4AckGYAYsowXeHzsn/LCKWIwSWLkdb0eGjH8wWkd27Q= +cloud.google.com/go/iam v1.4.2/go.mod h1:REGlrt8vSlh4dfCJfSEcNjLGq75wW75c5aU3FLOYq34= cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc= cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA= -cloud.google.com/go/longrunning v0.6.4 h1:3tyw9rO3E2XVXzSApn1gyEEnH2K9SynNQjMlBi3uHLg= -cloud.google.com/go/longrunning v0.6.4/go.mod h1:ttZpLCe6e7EXvn9OxpBRx7kZEB0efv8yBO6YnVMfhJs= -cloud.google.com/go/monitoring v1.24.0 h1:csSKiCJ+WVRgNkRzzz3BPoGjFhjPY23ZTcaenToJxMM= -cloud.google.com/go/monitoring v1.24.0/go.mod h1:Bd1PRK5bmQBQNnuGwHBfUamAV1ys9049oEPHnn4pcsc= -cloud.google.com/go/storage v1.50.0 h1:3TbVkzTooBvnZsk7WaAQfOsNrdoM8QHusXA1cpk6QJs= -cloud.google.com/go/storage v1.50.0/go.mod h1:l7XeiD//vx5lfqE3RavfmU9yvk5Pp0Zhcv482poyafY= +cloud.google.com/go/longrunning v0.6.5 h1:sD+t8DO8j4HKW4QfouCklg7ZC1qC4uzVZt8iz3uTW+Q= +cloud.google.com/go/longrunning v0.6.5/go.mod h1:Et04XK+0TTLKa5IPYryKf5DkpwImy6TluQ1QTLwlKmY= +cloud.google.com/go/monitoring v1.24.1 h1:vKiypZVFD/5a3BbQMvI4gZdl8445ITzXFh257XBgrS0= +cloud.google.com/go/monitoring v1.24.1/go.mod h1:Z05d1/vn9NaujqY2voG6pVQXoJGbp+r3laV+LySt9K0= +cloud.google.com/go/storage v1.51.0 h1:ZVZ11zCiD7b3k+cH5lQs/qcNaoSz3U9I0jgwVzqDlCw= +cloud.google.com/go/storage v1.51.0/go.mod h1:YEJfu/Ki3i5oHC/7jyTgsGZwdQ8P9hqMqvpi5kRKGgc= cloud.google.com/go/trace v1.11.3 h1:c+I4YFjxRQjvAhRmSsmjpASUKq88chOX854ied0K/pE= cloud.google.com/go/trace v1.11.3/go.mod h1:pt7zCYiDSQjC9Y2oqCsh9jF4GStB/hmjrYLsxRR27q8= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -26,14 +26,14 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.26.0 h1:f2Qw/Ehhimh5uO1fayV0QIW7DShEQqhtUfhYc+cBPlw= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.26.0/go.mod h1:2bIszWvQRlJVmJLiuLhukLImRjKPcYdzzsx6darK02A= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0 h1:5IT7xOdq17MtcdtL/vtl6mGfzhaq4m4vpollPRmlsBQ= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.50.0/go.mod h1:ZV4VOm0/eHR06JLrXWe09068dHpr3TRpY9Uo7T+anuA= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.50.0 h1:nNMpRpnkWDAaqcpxMJvxa/Ud98gjbYwayJY4/9bdjiU= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.50.0/go.mod h1:SZiPHWGOOk3bl8tkevxkoiwPgsIl6CwrWcbwjfHZpdM= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0 h1:ig/FpDD2JofP/NExKQUbn7uOSZzJAQqogfqluZK4ed4= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 h1:ErKg/3iS1AKcTkf3yixlZ54f9U1rljCkQyEXWUnIUxc= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0/go.mod h1:yAZHSGnqScoU556rBOVkwLze6WP5N+U11RHuWaGVxwY= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 h1:fYE9p3esPxA/C0rQ0AHhP0drtPXDRhaWiwg1DPqO7IU= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0/go.mod h1:BnBReJLvVYx2CS/UHOgVz2BXKXD9wsQPxZug20nZhd0= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.51.0 h1:OqVGm6Ei3x5+yZmSJG1Mh2NwHvpVmZ08CB5qJhT9Nuk= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.51.0/go.mod h1:SZiPHWGOOk3bl8tkevxkoiwPgsIl6CwrWcbwjfHZpdM= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0 h1:6/0iUd0xrnX7qt+mLNRwg5c0PGv8wpE8K90ryANQwMI= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.51.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alitto/pond v1.9.2 h1:9Qb75z/scEZVCoSU+osVmQ0I0JOeLfdTDafrbcJ8CLs= @@ -70,11 +70,11 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42 h1:Om6kYQYDUk5wWbT0t0q6pvyM49i9XZAv9dDrkDA7gjk= -github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= -github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI= -github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f h1:C5bqEmzEPLsHm9Mv73lSE9e9bKV23aB1vxOsmZrkl3k= +github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/coreos/go-oidc/v3 v3.13.0 h1:M66zd0pcc5VxvBNM4pB331Wrsanby+QomQYjN8HamW8= +github.com/coreos/go-oidc/v3 v3.13.0/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/crossdock/crossdock-go v0.0.0-20160816171116-049aabb0122b/go.mod h1:v9FBN7gdVTpiD/+LZ7Po0UKvROyT87uLVxTHVky/dlQ= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -122,17 +122,15 @@ github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ4 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= -github.com/go-sql-driver/mysql v1.9.0 h1:Y0zIbQXhQKmQgTp44Y1dp3wTXcn804QoTptLZT1vtvo= -github.com/go-sql-driver/mysql v1.9.0/go.mod h1:pDetrLJeA3oMujJuvXc8RJoasr589B6A9fwzD3QMrqw= +github.com/go-sql-driver/mysql v1.9.1 h1:FrjNGn/BsJQjVRuSa8CBrM5BWA9BWoXXat3KrtSb/iI= +github.com/go-sql-driver/mysql v1.9.1/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gocql/gocql v1.7.0 h1:O+7U7/1gSN7QTEAaMEsJc1Oq2QHXvCWoF3DFK9HDHus= github.com/gocql/gocql v1.7.0/go.mod h1:vnlvXyFZeLBF0Wy+RS8hrOdbn0UWsWtdg07XJnFxZ+4= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= -github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= +github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -145,28 +143,28 @@ github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaW github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomarkdown/markdown v0.0.0-20241105142532-d03b89096d81 h1:5lyLWsV+qCkoYqsKUDuycESh9DEIPVKN6iCFeL7ag50= -github.com/gomarkdown/markdown v0.0.0-20241105142532-d03b89096d81/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomarkdown/markdown v0.0.0-20250311123330-531bef5e742b h1:EY/KpStFl60qA17CptGXhwfZ+k1sFNJIUNR8DdbcuUk= +github.com/gomarkdown/markdown v0.0.0-20250311123330-531bef5e742b/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= -github.com/google/pprof v0.0.0-20250208200701-d0013a598941 h1:43XjGa6toxLpeksjcxs1jIoIyr+vUfOqY2c6HB4bpoc= -github.com/google/pprof v0.0.0-20250208200701-d0013a598941/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= +github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw= -github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= +github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= +github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q= github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= @@ -175,10 +173,12 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -187,8 +187,8 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI= -github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ= +github.com/jackc/pgx/v5 v5.7.4 h1:9wKznZrhWa2QiHL+NjTSPP6yjl3451BX3imWDnokYlg= +github.com/jackc/pgx/v5 v5.7.4/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -217,18 +217,16 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/labstack/echo/v4 v4.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+Y= -github.com/labstack/echo/v4 v4.9.1/go.mod h1:Pop5HLc+xoc4qhTZ1ip6C0RtP7Z+4VzRLWZZFKqbbjo= -github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= -github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= +github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY= +github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g= +github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= +github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -264,15 +262,15 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prashantv/protectmem v0.0.0-20171002184600-e20412882b3a h1:AA9vgIBDjMHPC2McaGPojgV2dcI78ZC0TLNhYCXEKH8= github.com/prashantv/protectmem v0.0.0-20171002184600-e20412882b3a/go.mod h1:lzZQ3Noex5pfAy7mkAeCjcBDteYU85uWWnJ/y6gKU8k= -github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA= -github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= +github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk= +github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= -github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= -github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= +github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= +github.com/prometheus/procfs v0.16.0 h1:xh6oHhKwnOJKMYiYBDWmkHqQPyiY40sny36Cmx2bbsM= +github.com/prometheus/procfs v0.16.0/go.mod h1:8veyXUu3nGP7oaCxhX6yeaM5u4stL2FeMXnCqhDthZg= github.com/rcrowley/go-metrics v0.0.0-20141108142129-dee209f2455f/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -296,9 +294,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sony/gobreaker v1.0.0 h1:feX5fGGXSl3dYd4aHZItw+FpHLvvoaqkawKjVNiFMNQ= github.com/sony/gobreaker v1.0.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -335,44 +332,44 @@ github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVK github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/detectors/gcp v1.34.0 h1:JRxssobiPg23otYU5SbWtQC//snGVIM3Tx6QRzlQBao= -go.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQmF0PRsq8w/lMGzdbCSveBHo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I= -go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= -go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 h1:ajl4QczuJVA2TU9W9AGw++86Xga/RKt//16z/yxPgdk= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0/go.mod h1:Vn3/rlOJ3ntf/Q3zAI0V5lDnTbHGaUsNUeF6nZmm7pA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= -go.opentelemetry.io/otel/exporters/prometheus v0.56.0 h1:GnCIi0QyG0yy2MrJLzVrIM7laaJstj//flf1zEJCG+E= -go.opentelemetry.io/otel/exporters/prometheus v0.56.0/go.mod h1:JQcVZtbIIPM+7SWBB+T6FK+xunlyidwLp++fN0sUaOk= +go.opentelemetry.io/contrib/detectors/gcp v1.35.0 h1:bGvFt68+KTiAKFlacHW6AhA56GF2rS0bdD3aJYEnmzA= +go.opentelemetry.io/contrib/detectors/gcp v1.35.0/go.mod h1:qGWP8/+ILwMRIUf9uIVLloR1uo5ZYAslM4O6OqUi1DA= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0 h1:QcFwRrZLc82r8wODjvyCbP7Ifp3UANaBSmhDSFjnqSc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0/go.mod h1:CXIWhUomyWBG/oY2/r/kLp6K/cmx9e/7DLpBuuGdLCA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo= +go.opentelemetry.io/otel/exporters/prometheus v0.57.0 h1:AHh/lAP1BHrY5gBwk8ncc25FXWm/gmmY3BX258z5nuk= +go.opentelemetry.io/otel/exporters/prometheus v0.57.0/go.mod h1:QpFWz1QxqevfjwzYdbMb4Y1NnlJvqSGwyuU0B4iuc9c= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I= -go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= -go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= -go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= -go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= -go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= -go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= -go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= -go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= +go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= +go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= +go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= -go.temporal.io/api v1.45.0 h1:2FZ3eUoOYjavBaQi3/V93MBl99Nq1ifFRjrRwT3MeC8= -go.temporal.io/api v1.45.0/go.mod h1:iaxoP/9OXMJcQkETTECfwYq4cw/bj4nwov8b3ZLVnXM= +go.temporal.io/api v1.46.0 h1:O1efPDB6O2B8uIeCDIa+3VZC7tZMvYsMZYQapSbHvCg= +go.temporal.io/api v1.46.0/go.mod h1:iaxoP/9OXMJcQkETTECfwYq4cw/bj4nwov8b3ZLVnXM= go.temporal.io/sdk v1.33.0 h1:T91UzeRdlHTiMGgpygsItOH9+VSkg+M/mG85PqNjdog= go.temporal.io/sdk v1.33.0/go.mod h1:WwCmJZLy7zabz3ar5NRAQEygsdP8tgR9sDjISSHuWZw= go.temporal.io/server v1.27.1 h1:0dyBl25Ua7P4IOXifJg0xUXfnoYTNY1IlUFf1RL4OBo= @@ -383,8 +380,8 @@ go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= -go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/dig v1.18.1 h1:rLww6NuajVjeQn+49u5NcezUJEGwd5uXmyoCKW2g5Es= +go.uber.org/dig v1.18.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg= go.uber.org/fx v1.23.0/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= @@ -408,16 +405,16 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= -golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4= -golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= +golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw= +golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -433,8 +430,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= +golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -449,11 +446,11 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE= -golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc= +golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -462,8 +459,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -475,11 +472,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -487,8 +481,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -501,10 +495,10 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= -golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= +golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -523,8 +517,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU= +golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -533,28 +527,28 @@ gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJ gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -google.golang.org/api v0.222.0 h1:Aiewy7BKLCuq6cUCeOUrsAlzjXPqBkEeQ/iwGHVQa/4= -google.golang.org/api v0.222.0/go.mod h1:efZia3nXpWELrwMlN5vyQrD4GmJN1Vw0x68Et3r+a9c= +google.golang.org/api v0.228.0 h1:X2DJ/uoWGnY5obVjewbp8icSL5U4FzuCfy9OjbLSnLs= +google.golang.org/api v0.228.0/go.mod h1:wNvRS1Pbe8r4+IfBIniV8fwCpGwTrYa+kMUDiC5z5a4= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20250218202821-56aae31c358a h1:Xx6e5r1AOINOgm2ZuzvwDueGlOOml4PKBUry8jqyS6U= -google.golang.org/genproto v0.0.0-20250218202821-56aae31c358a/go.mod h1:Cmg1ztsSOnOsWxOiPTOUX8gegyHg5xADRncIHdtec8U= -google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a h1:nwKuGPlUAt+aR+pcrkfFRrTU1BVrSmYyYMxYbUIVHr0= -google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a/go.mod h1:3kWAYMk1I75K4vykHtKt2ycnOgpA6974V7bREqbsenU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ= +google.golang.org/genproto v0.0.0-20250324211829-b45e905df463 h1:qEFnJI6AnfZk0NNe8YTyXQh5i//Zxi4gBHwRgp76qpw= +google.golang.org/genproto v0.0.0-20250324211829-b45e905df463/go.mod h1:SqIx1NV9hcvqdLHo7uNZDS5lrUJybQ3evo3+z/WBfA0= +google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 h1:hE3bRWtU6uceqlh4fhrSnUyjKHMKB9KrTLLG+bc0ddM= +google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463/go.mod h1:U90ffi8eUL9MwPcrJylN5+Mk2v3vuPDptd5yyNUiRR8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 h1:e0AIkUUhxyBKh6ssZNrAMeqhA7RKUj42346d1y02i2g= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= -google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= -google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= +google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -578,26 +572,28 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -modernc.org/cc/v4 v4.24.4 h1:TFkx1s6dCkQpd6dKurBNmpo+G8Zl4Sq/ztJ+2+DEsh0= -modernc.org/cc/v4 v4.24.4/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= -modernc.org/ccgo/v4 v4.23.15 h1:wFDan71KnYqeHz4eF63vmGE6Q6Pc0PUGDpP0PRMYjDc= -modernc.org/ccgo/v4 v4.23.15/go.mod h1:nJX30dks/IWuBOnVa7VRii9Me4/9TZ1SC9GNtmARTy0= +modernc.org/cc/v4 v4.25.2 h1:T2oH7sZdGvTaie0BRNFbIYsabzCxUQg8nLqCdQ2i0ic= +modernc.org/cc/v4 v4.25.2/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= +modernc.org/ccgo/v4 v4.20.4 h1:3pPOlMcblnu5CBU3w1BFtepwBnLezGjPYTH8xBeYZM8= +modernc.org/ccgo/v4 v4.20.4/go.mod h1:meYiLeaGpKQmHBw8roW4DXLkDvusG+MD7LJ/kYyAouU= modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= -modernc.org/gc/v2 v2.6.3 h1:aJVhcqAte49LF+mGveZ5KPlsp4tdGdAOT4sipJXADjw= -modernc.org/gc/v2 v2.6.3/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= -modernc.org/libc v1.61.11 h1:6sZG8uB6EMMG7iTLPTndi8jyTdgAQNIeLGjCFICACZw= -modernc.org/libc v1.61.11/go.mod h1:HHX+srFdn839oaJRd0W8hBM3eg+mieyZCAjWwB08/nM= +modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= +modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= +modernc.org/gc/v3 v3.0.0 h1:JNEAEd0e/lnR1nlJemLPwS44KfBLBp4SAvZEZFaxfYU= +modernc.org/gc/v3 v3.0.0/go.mod h1:LG5UO1Ran4OO0JRKz2oNiXhR5nNrgz0PzH7UKhz0aMU= +modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= +modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w= modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= -modernc.org/memory v1.8.2 h1:cL9L4bcoAObu4NkxOlKWBWtNHIsnnACGF/TbqQ6sbcI= -modernc.org/memory v1.8.2/go.mod h1:ZbjSvMO5NQ1A2i3bWeDiVMxIorXwdClKE/0SZ+BMotU= +modernc.org/memory v1.9.1 h1:V/Z1solwAVmMW1yttq3nDdZPJqV1rM05Ccq6KMSZ34g= +modernc.org/memory v1.9.1/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= -modernc.org/sqlite v1.34.5 h1:Bb6SR13/fjp15jt70CL4f18JIN7p7dnMExd+UFnF15g= -modernc.org/sqlite v1.34.5/go.mod h1:YLuNmX9NKs8wRNK2ko1LW1NGYcc9FkBO69JOt1AR9JE= +modernc.org/sqlite v1.34.1 h1:u3Yi6M0N8t9yKRDwhXcyp1eS5/ErhPTBggxWFuR6Hfk= +modernc.org/sqlite v1.34.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k= modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/temporalcli/sqlite_test.go b/temporalcli/sqlite_test.go new file mode 100644 index 000000000..fc95fd952 --- /dev/null +++ b/temporalcli/sqlite_test.go @@ -0,0 +1,23 @@ +package temporalcli + +import ( + _ "modernc.org/sqlite" + "os" + "strings" + "testing" +) + +// Pinning modernc.org/sqlite to this version until https://gitlab.com/cznic/sqlite/-/issues/196 is resolved +func TestSqliteVersion(t *testing.T) { + content, err := os.ReadFile("../go.mod") + if err != nil { + t.Fatalf("Failed to read go.mod: %v", err) + } + contentStr := string(content) + if !strings.Contains(contentStr, "modernc.org/sqlite v1.34.1") { + t.Errorf("go.mod missing dependency modernc.org/sqlite v1.34.1") + } + if !strings.Contains(contentStr, "modernc.org/libc v1.55.3") { + t.Errorf("go.mod missing dependency modernc.org/libc v1.55.3") + } +} From eabf08108ac8630fd2d312c4b91958d66273c4c8 Mon Sep 17 00:00:00 2001 From: Antonio Lain <135073478+antlai-temporal@users.noreply.github.com> Date: Fri, 28 Mar 2025 18:47:29 -0700 Subject: [PATCH 10/11] Use `require` instead of `assert` in test (#785) --- temporalcli/commands.workflow_test.go | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/temporalcli/commands.workflow_test.go b/temporalcli/commands.workflow_test.go index 02fddb10f..2c3516743 100644 --- a/temporalcli/commands.workflow_test.go +++ b/temporalcli/commands.workflow_test.go @@ -12,6 +12,7 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/temporalio/cli/temporalcli" "go.temporal.io/api/enums/v1" "go.temporal.io/api/workflowservice/v1" @@ -505,6 +506,15 @@ func (s *SharedServerSuite) TestWorkflow_Batch_Update_Options_Versioning_Overrid } }, 30*time.Second, 100*time.Millisecond) + // Wait for all to appear in list + s.Eventually(func() bool { + resp, err := s.Client.ListWorkflow(s.Context, &workflowservice.ListWorkflowExecutionsRequest{ + Query: "CustomKeywordField = '" + searchAttr + "'", + }) + s.NoError(err) + return len(resp.Executions) == len(runs) + }, 3*time.Second, 100*time.Millisecond) + s.CommandHarness.Stdin.WriteString("y\n") res = s.Execute( "workflow", "update-options", @@ -524,15 +534,15 @@ func (s *SharedServerSuite) TestWorkflow_Batch_Update_Options_Versioning_Overrid "-w", run.GetID(), "--output", "json", ) - assert.NoError(t, res.Err) + require.NoError(t, res.Err) var jsonResp workflowservice.DescribeWorkflowExecutionResponse - assert.NoError(t, temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonResp, true)) + require.NoError(t, temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonResp, true)) versioningInfo := jsonResp.GetWorkflowExecutionInfo().GetVersioningInfo() - assert.NotNil(t, versioningInfo) - assert.NotNil(t, versioningInfo.VersioningOverride) - assert.Equal(t, version2, versioningInfo.VersioningOverride.PinnedVersion) + require.NotNil(t, versioningInfo) + require.NotNil(t, versioningInfo.VersioningOverride) + require.Equal(t, version2, versioningInfo.VersioningOverride.PinnedVersion) } }, 30*time.Second, 100*time.Millisecond) } From 63d2bea9dac76883186d2b6aca50aa284530195d Mon Sep 17 00:00:00 2001 From: Andrew Yuan Date: Thu, 17 Apr 2025 09:03:24 -0700 Subject: [PATCH 11/11] Match tags in documentation repo (#791) ## What was changed Added a tags section to match what Documentation side has ## Why? We previously just used keywords, but that could be seen as keyword stuffing. The tags were updated on the docs side a few months ago, changes were never updated on this side. ## Checklist 1. Closes 2. How was this tested: 3. Any docs updates needed? --------- Co-authored-by: Chad Retz --- temporalcli/commands.gen.go | 16 ++++----- temporalcli/commandsgen/commands.yml | 52 ++++++++++++++++++++-------- temporalcli/commandsgen/docs.go | 9 +++-- temporalcli/commandsgen/parse.go | 4 +++ 4 files changed, 53 insertions(+), 28 deletions(-) diff --git a/temporalcli/commands.gen.go b/temporalcli/commands.gen.go index d67c6c433..16e9224e0 100644 --- a/temporalcli/commands.gen.go +++ b/temporalcli/commands.gen.go @@ -2637,9 +2637,9 @@ func NewTemporalWorkerDeploymentDeleteVersionCommand(cctx *CommandContext, paren s.Command.Use = "delete-version [flags]" s.Command.Short = "Delete a Worker Deployment Version" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemove a Worker Deployment Version given its fully-qualified identifier.\nThis is rarely needed during normal operation\nsince unused Versions are eventually garbage collected.\nThe client can delete a Version only when all of the following conditions\nare met:\n - It is not the Current or Ramping Version for this Deployment.\n - It has no active pollers, i.e., none of the task queues in the\n Version have pollers.\n - It is not draining. This requirement can be ignored with the option\n\x1b[1m--skip-drainage\x1b[0m.\n \n\x1b[1mtemporal worker deployment delete-version [options]\x1b[0m\n\nFor example, skipping the drainage restriction:\n\n\x1b[1mtemporal worker deployment delete-version \\\n --version YourDeploymentName.YourBuildID \\\n --skip-drainage \x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemove a Worker Deployment Version given its fully-qualified identifier.\nThis is rarely needed during normal operation\nsince unused Versions are eventually garbage collected.\nThe client can delete a Version only when all of the following conditions\nare met:\n - It is not the Current or Ramping Version for this Deployment.\n - It has no active pollers, i.e., none of the task queues in the\n Version have pollers.\n - It is not draining. This requirement can be ignored with the option\n\x1b[1m--skip-drainage\x1b[0m.\n\n\x1b[1mtemporal worker deployment delete-version [options]\x1b[0m\n\nFor example, skipping the drainage restriction:\n\n\x1b[1mtemporal worker deployment delete-version \\\n --version YourDeploymentName.YourBuildID \\\n --skip-drainage \x1b[0m" } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemove a Worker Deployment Version given its fully-qualified identifier.\nThis is rarely needed during normal operation\nsince unused Versions are eventually garbage collected.\nThe client can delete a Version only when all of the following conditions\nare met:\n - It is not the Current or Ramping Version for this Deployment.\n - It has no active pollers, i.e., none of the task queues in the\n Version have pollers.\n - It is not draining. This requirement can be ignored with the option\n`--skip-drainage`.\n \n```\ntemporal worker deployment delete-version [options]\n```\n\nFor example, skipping the drainage restriction:\n\n```\ntemporal worker deployment delete-version \\\n --version YourDeploymentName.YourBuildID \\\n --skip-drainage \n```" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemove a Worker Deployment Version given its fully-qualified identifier.\nThis is rarely needed during normal operation\nsince unused Versions are eventually garbage collected.\nThe client can delete a Version only when all of the following conditions\nare met:\n - It is not the Current or Ramping Version for this Deployment.\n - It has no active pollers, i.e., none of the task queues in the\n Version have pollers.\n - It is not draining. This requirement can be ignored with the option\n`--skip-drainage`.\n\n```\ntemporal worker deployment delete-version [options]\n```\n\nFor example, skipping the drainage restriction:\n\n```\ntemporal worker deployment delete-version \\\n --version YourDeploymentName.YourBuildID \\\n --skip-drainage \n```" } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") @@ -2749,9 +2749,9 @@ func NewTemporalWorkerDeploymentSetCurrentVersionCommand(cctx *CommandContext, p s.Command.Use = "set-current-version [flags]" s.Command.Short = "Make a Worker Deployment Version Current for a Deployment" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSet the Current Version for a Deployment.\nWhen a Version is current, Workers of that Deployment Version will receive\ntasks from new Workflows, and from existing AutoUpgrade Workflows that\nare running on this Deployment.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Version the request will fail. To override this protection use\n\x1b[1m--ignore-missing-task-queues\x1b[0m. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n\x1b[1mtemporal worker deployment set-current-version [options]\x1b[0m\n\nFor example, to set the Current Version of a deployment\n\x1b[1mYourDeploymentName\x1b[0m, with a version with Build ID \x1b[1mYourBuildID\x1b[0m, and\nin the default namespace:\n\n\x1b[1mtemporal worker deployment set-current-version \\\n --version YourDeploymentName.YourBuildID\x1b[0m\n\nThe target of set-current-version can also be \x1b[1m__unversioned__\x1b[0m, which\nmoves tasks to unversioned workers, but in this case we also need to\nspecify the Deployment Name.\n\n\x1b[1mtemporal worker deployment set-current-version \\\n --version __unversioned__ \\\n --deployment-name YourDeploymentName\x1b[0m " + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSet the Current Version for a Deployment.\nWhen a Version is current, Workers of that Deployment Version will receive\ntasks from new Workflows, and from existing AutoUpgrade Workflows that\nare running on this Deployment.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Version the request will fail. To override this protection use\n\x1b[1m--ignore-missing-task-queues\x1b[0m. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n\x1b[1mtemporal worker deployment set-current-version [options]\x1b[0m\n\nFor example, to set the Current Version of a deployment\n\x1b[1mYourDeploymentName\x1b[0m, with a version with Build ID \x1b[1mYourBuildID\x1b[0m, and\nin the default namespace:\n\n\x1b[1mtemporal worker deployment set-current-version \\\n --version YourDeploymentName.YourBuildID\x1b[0m\n\nThe target of set-current-version can also be \x1b[1m__unversioned__\x1b[0m, which\nmoves tasks to unversioned workers, but in this case we also need to\nspecify the Deployment Name.\n\n\x1b[1mtemporal worker deployment set-current-version \\\n --version __unversioned__ \\\n --deployment-name YourDeploymentName\x1b[0m" } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSet the Current Version for a Deployment.\nWhen a Version is current, Workers of that Deployment Version will receive\ntasks from new Workflows, and from existing AutoUpgrade Workflows that\nare running on this Deployment.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Version the request will fail. To override this protection use\n`--ignore-missing-task-queues`. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n```\ntemporal worker deployment set-current-version [options]\n```\n\nFor example, to set the Current Version of a deployment\n`YourDeploymentName`, with a version with Build ID `YourBuildID`, and\nin the default namespace:\n\n```\ntemporal worker deployment set-current-version \\\n --version YourDeploymentName.YourBuildID\n```\n\nThe target of set-current-version can also be `__unversioned__`, which\nmoves tasks to unversioned workers, but in this case we also need to\nspecify the Deployment Name.\n\n```\ntemporal worker deployment set-current-version \\\n --version __unversioned__ \\\n --deployment-name YourDeploymentName\n``` " + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSet the Current Version for a Deployment.\nWhen a Version is current, Workers of that Deployment Version will receive\ntasks from new Workflows, and from existing AutoUpgrade Workflows that\nare running on this Deployment.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Version the request will fail. To override this protection use\n`--ignore-missing-task-queues`. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n```\ntemporal worker deployment set-current-version [options]\n```\n\nFor example, to set the Current Version of a deployment\n`YourDeploymentName`, with a version with Build ID `YourBuildID`, and\nin the default namespace:\n\n```\ntemporal worker deployment set-current-version \\\n --version YourDeploymentName.YourBuildID\n```\n\nThe target of set-current-version can also be `__unversioned__`, which\nmoves tasks to unversioned workers, but in this case we also need to\nspecify the Deployment Name.\n\n```\ntemporal worker deployment set-current-version \\\n --version __unversioned__ \\\n --deployment-name YourDeploymentName\n```" } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVar(&s.DeploymentName, "deployment-name", "", "Deployment name. Only needed when `--version` is `__unversioned__` or empty.") @@ -2786,9 +2786,9 @@ func NewTemporalWorkerDeploymentSetRampingVersionCommand(cctx *CommandContext, p s.Command.Use = "set-ramping-version [flags]" s.Command.Short = "Change Version Ramping settings for a Worker Deployment" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSet the Ramping Version and Percentage for a Deployment.\n\nThe Ramping Version can be set to a fully-qualified Version of the form\n\x1b[1mYourDeploymentName.YourBuildID\x1b[0m, or set to \"__unversioned__\", a special\nvalue that represents all the unversioned workers.\n\nThe Ramping Percentage is a float with values in the range [0, 100].\nA value of 100 does not make the Ramping Version Current, use\n\x1b[1mset-current-version\x1b[0m instead.\n\nTo remove a Ramping Version use the flag \x1b[1m--delete\x1b[0m.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Ramping Version the request will fail. To override this protection use\n\x1b[1m--ignore-missing-task-queues\x1b[0m. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n\x1b[1mtemporal worker deployment set-ramping-version [options]\x1b[0m\n\nFor example, to set the Ramping Version of a deployment\n\x1b[1mYourDeploymentName\x1b[0m, with a version with Build ID \x1b[1mYourBuildID\x1b[0m, with\n10 percent of tasks redirected to this version, and\nusing the default namespace:\n\n\x1b[1mtemporal worker deployment set-ramping-version \\\n --version YourDeploymentName.YourBuildID\n --percentage 10.0\x1b[0m\n\nAnd to remove that ramping:\n \n\x1b[1mtemporal worker deployment set-ramping-version \\\n --version YourDeploymentName.YourBuildID \\\n --delete\x1b[0m " + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSet the Ramping Version and Percentage for a Deployment.\n\nThe Ramping Version can be set to a fully-qualified Version of the form\n\x1b[1mYourDeploymentName.YourBuildID\x1b[0m, or set to \"__unversioned__\", a special\nvalue that represents all the unversioned workers.\n\nThe Ramping Percentage is a float with values in the range [0, 100].\nA value of 100 does not make the Ramping Version Current, use\n\x1b[1mset-current-version\x1b[0m instead.\n\nTo remove a Ramping Version use the flag \x1b[1m--delete\x1b[0m.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Ramping Version the request will fail. To override this protection use\n\x1b[1m--ignore-missing-task-queues\x1b[0m. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n\x1b[1mtemporal worker deployment set-ramping-version [options]\x1b[0m\n\nFor example, to set the Ramping Version of a deployment\n\x1b[1mYourDeploymentName\x1b[0m, with a version with Build ID \x1b[1mYourBuildID\x1b[0m, with\n10 percent of tasks redirected to this version, and\nusing the default namespace:\n\n\x1b[1mtemporal worker deployment set-ramping-version \\\n --version YourDeploymentName.YourBuildID\n --percentage 10.0\x1b[0m\n\nAnd to remove that ramping:\n\n\x1b[1mtemporal worker deployment set-ramping-version \\\n --version YourDeploymentName.YourBuildID \\\n --delete\x1b[0m" } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSet the Ramping Version and Percentage for a Deployment.\n\nThe Ramping Version can be set to a fully-qualified Version of the form\n`YourDeploymentName.YourBuildID`, or set to \"__unversioned__\", a special\nvalue that represents all the unversioned workers.\n\nThe Ramping Percentage is a float with values in the range [0, 100].\nA value of 100 does not make the Ramping Version Current, use\n`set-current-version` instead.\n\nTo remove a Ramping Version use the flag `--delete`.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Ramping Version the request will fail. To override this protection use\n`--ignore-missing-task-queues`. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n```\ntemporal worker deployment set-ramping-version [options]\n```\n\nFor example, to set the Ramping Version of a deployment\n`YourDeploymentName`, with a version with Build ID `YourBuildID`, with\n10 percent of tasks redirected to this version, and\nusing the default namespace:\n\n```\ntemporal worker deployment set-ramping-version \\\n --version YourDeploymentName.YourBuildID\n --percentage 10.0\n```\n\nAnd to remove that ramping:\n \n```\ntemporal worker deployment set-ramping-version \\\n --version YourDeploymentName.YourBuildID \\\n --delete\n``` " + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSet the Ramping Version and Percentage for a Deployment.\n\nThe Ramping Version can be set to a fully-qualified Version of the form\n`YourDeploymentName.YourBuildID`, or set to \"__unversioned__\", a special\nvalue that represents all the unversioned workers.\n\nThe Ramping Percentage is a float with values in the range [0, 100].\nA value of 100 does not make the Ramping Version Current, use\n`set-current-version` instead.\n\nTo remove a Ramping Version use the flag `--delete`.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Ramping Version the request will fail. To override this protection use\n`--ignore-missing-task-queues`. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n```\ntemporal worker deployment set-ramping-version [options]\n```\n\nFor example, to set the Ramping Version of a deployment\n`YourDeploymentName`, with a version with Build ID `YourBuildID`, with\n10 percent of tasks redirected to this version, and\nusing the default namespace:\n\n```\ntemporal worker deployment set-ramping-version \\\n --version YourDeploymentName.YourBuildID\n --percentage 10.0\n```\n\nAnd to remove that ramping:\n\n```\ntemporal worker deployment set-ramping-version \\\n --version YourDeploymentName.YourBuildID \\\n --delete\n```" } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVar(&s.DeploymentName, "deployment-name", "", "Deployment name. Only needed when `--version` is `__unversioned__`.") @@ -2821,9 +2821,9 @@ func NewTemporalWorkerDeploymentUpdateMetadataVersionCommand(cctx *CommandContex s.Command.Use = "update-metadata-version [flags]" s.Command.Short = "Change user-provided metadata for a Version" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\nUpdate metadata associated with a Worker Deployment Version.\n\nFor example:\n\n\x1b[1m temporal worker deployment update-metadata-version \\\n --version YourDeploymentName.YourBuildID \\\n --metadata bar=1 \\\n --metadata foo=true\x1b[0m\n\nThe current metadata is also returned with \x1b[1mdescribe-version\x1b[0m:\n \n\x1b[1m temporal worker deployment describe-version \\\n --version YourDeploymentName.YourBuildID \\\x1b[0m " + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\nUpdate metadata associated with a Worker Deployment Version.\n\nFor example:\n\n\x1b[1m temporal worker deployment update-metadata-version \\\n --version YourDeploymentName.YourBuildID \\\n --metadata bar=1 \\\n --metadata foo=true\x1b[0m\n\nThe current metadata is also returned with \x1b[1mdescribe-version\x1b[0m:\n\n\x1b[1m temporal worker deployment describe-version \\\n --version YourDeploymentName.YourBuildID \\\x1b[0m" } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\nUpdate metadata associated with a Worker Deployment Version.\n\nFor example:\n\n```\n temporal worker deployment update-metadata-version \\\n --version YourDeploymentName.YourBuildID \\\n --metadata bar=1 \\\n --metadata foo=true\n```\n\nThe current metadata is also returned with `describe-version`:\n \n```\n temporal worker deployment describe-version \\\n --version YourDeploymentName.YourBuildID \\\n``` " + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\nUpdate metadata associated with a Worker Deployment Version.\n\nFor example:\n\n```\n temporal worker deployment update-metadata-version \\\n --version YourDeploymentName.YourBuildID \\\n --metadata bar=1 \\\n --metadata foo=true\n```\n\nThe current metadata is also returned with `describe-version`:\n\n```\n temporal worker deployment describe-version \\\n --version YourDeploymentName.YourBuildID \\\n```" } s.Command.Args = cobra.NoArgs s.Command.Flags().StringArrayVar(&s.Metadata, "metadata", nil, "Set deployment metadata using `KEY=\"VALUE\"` pairs. Keys must be identifiers, and values must be JSON values. For example: 'YourKey={\"your\": \"value\"}'. Can be passed multiple times.") diff --git a/temporalcli/commandsgen/commands.yml b/temporalcli/commandsgen/commands.yml index 2e94dad79..9eb0920dd 100644 --- a/temporalcli/commandsgen/commands.yml +++ b/temporalcli/commandsgen/commands.yml @@ -238,6 +238,9 @@ commands: - cli-feature - command-line-interface-cli - temporal cli + tags: + - Activities + - Temporal CLI - name: temporal activity complete summary: Complete an Activity @@ -447,7 +450,7 @@ commands: --reason YourReasonForTermination ``` - + Specify the Activity ID or Type and Workflow IDs: ``` @@ -593,6 +596,8 @@ commands: - cli-feature - command-line-interface-cli - temporal cli + tags: + - Temporal CLI - name: temporal batch describe summary: Show batch job progress @@ -670,6 +675,8 @@ commands: keywords: - worker - worker deployment + tags: + - Temporal CLI - name: temporal worker deployment summary: Describe, list, and operate on Worker Deployments and Versions @@ -706,7 +713,7 @@ commands: ``` Sets the current Deployment Version for a given Deployment. - + docs: description-header: >- Temporal Deployment commands enable operations on Worker Deployments @@ -780,7 +787,7 @@ commands: - name: identity type: string description: Identity of the user submitting this request. - + - name: temporal worker deployment list summary: Enumerate Worker Deployments in the client's namespace description: | @@ -801,7 +808,7 @@ commands: temporal worker deployment list \ --namespace YourDeploymentNamespace ``` - + - name: temporal worker deployment describe-version summary: Show properties of a Worker Deployment Version description: | @@ -829,7 +836,7 @@ commands: ``` option-sets: - deployment-version - + - name: temporal worker deployment delete-version summary: Delete a Worker Deployment Version description: | @@ -848,7 +855,7 @@ commands: Version have pollers. - It is not draining. This requirement can be ignored with the option `--skip-drainage`. - + ``` temporal worker deployment delete-version [options] ``` @@ -910,7 +917,7 @@ commands: temporal worker deployment set-current-version \ --version __unversioned__ \ --deployment-name YourDeploymentName - ``` + ``` option-sets: - deployment-version options: @@ -972,12 +979,12 @@ commands: ``` And to remove that ramping: - + ``` temporal worker deployment set-ramping-version \ --version YourDeploymentName.YourBuildID \ --delete - ``` + ``` option-sets: - deployment-version options: @@ -1004,7 +1011,7 @@ commands: short: y type: bool description: Don't prompt to confirm set Ramping Version. - + - name: temporal worker deployment update-metadata-version summary: Change user-provided metadata for a Version description: | @@ -1024,11 +1031,11 @@ commands: ``` The current metadata is also returned with `describe-version`: - + ``` temporal worker deployment describe-version \ --version YourDeploymentName.YourBuildID \ - ``` + ``` option-sets: - deployment-version options: @@ -1044,7 +1051,7 @@ commands: description: | Keys of entries to be deleted from metadata. Can be passed multiple times. - + - name: temporal env summary: Manage environments description: | @@ -1081,6 +1088,8 @@ commands: - env set - environment - temporal cli + tags: + - Temporal CLI - name: temporal env delete summary: Delete an environment or environment property @@ -1228,6 +1237,8 @@ commands: - system - temporal cli - update + tags: + - Temporal CLI - name: temporal operator cluster summary: Manage a Temporal Cluster @@ -1810,6 +1821,9 @@ commands: - schedule update - temporal cli - updates + tags: + - Temporal CLI + - Schedules - name: temporal schedule backfill summary: Backfill past actions @@ -2069,6 +2083,9 @@ commands: - server - server start-dev - temporal cli + tags: + - Temporal CLI + - Development Server - name: temporal server start-dev summary: Start Temporal development server @@ -2218,6 +2235,8 @@ commands: - task queue - task queue describe - temporal cli + tags: + - Temporal CLI - name: temporal task-queue describe summary: Show active Workers @@ -2961,6 +2980,9 @@ commands: - workflow terminate - workflow trace - workflow update-options + tags: + - Temporal CLI + - Workflows - name: temporal workflow cancel summary: Send cancellation to Workflow Execution @@ -4042,7 +4064,7 @@ option-sets: Fully-qualified name for a Worker Deployment Version. Use the format `YourDeploymentName.YourBuildID`. required: true - + - name: deployment-reference options: - name: series-name @@ -4187,7 +4209,7 @@ option-sets: - Fail - UseExisting - TerminateExisting - + - name: payload-input options: - name: input diff --git a/temporalcli/commandsgen/docs.go b/temporalcli/commandsgen/docs.go index fd00f2475..d26aa2456 100644 --- a/temporalcli/commandsgen/docs.go +++ b/temporalcli/commandsgen/docs.go @@ -61,8 +61,8 @@ func (w *docWriter) writeCommand(c *Command) { w.fileMap[fileName] = &bytes.Buffer{} w.fileMap[fileName].WriteString("---\n") w.fileMap[fileName].WriteString("id: " + fileName + "\n") - w.fileMap[fileName].WriteString("title: " + c.FullName + "\n") - w.fileMap[fileName].WriteString("sidebar_label: " + c.FullName + "\n") + w.fileMap[fileName].WriteString("title: Temporal CLI " + fileName + " command reference\n") + w.fileMap[fileName].WriteString("sidebar_label: " + fileName + "\n") w.fileMap[fileName].WriteString("description: " + c.Docs.DescriptionHeader + "\n") w.fileMap[fileName].WriteString("toc_max_heading_level: 4\n") @@ -70,10 +70,9 @@ func (w *docWriter) writeCommand(c *Command) { for _, keyword := range c.Docs.Keywords { w.fileMap[fileName].WriteString(" - " + keyword + "\n") } - // tags are the same as Keywords, but with `-` instead of ` ` w.fileMap[fileName].WriteString("tags:\n") - for _, keyword := range c.Docs.Keywords { - w.fileMap[fileName].WriteString(" - " + strings.ReplaceAll(keyword, " ", "-") + "\n") + for _, tag := range c.Docs.Tags { + w.fileMap[fileName].WriteString(" - " + tag + "\n") } w.fileMap[fileName].WriteString("---\n\n") } diff --git a/temporalcli/commandsgen/parse.go b/temporalcli/commandsgen/parse.go index 25cebfa86..670996dec 100644 --- a/temporalcli/commandsgen/parse.go +++ b/temporalcli/commandsgen/parse.go @@ -54,6 +54,7 @@ type ( Docs struct { Keywords []string `yaml:"keywords"` DescriptionHeader string `yaml:"description-header"` + Tags []string `yaml:"tags"` } // OptionSets represents the structure of option sets. @@ -149,6 +150,9 @@ func (c *Command) processSection() error { if c.Docs.DescriptionHeader == "" { return fmt.Errorf("missing description for root command: %s", c.FullName) } + if len(c.Docs.Tags) == 0 { + return fmt.Errorf("missing tags for root command: %s", c.FullName) + } } // Strip trailing newline for description