From efcef0c13b94c09ce6f37f04432f651dfed21d3e Mon Sep 17 00:00:00 2001 From: Sean Kane Date: Thu, 18 Jun 2026 09:16:25 -0600 Subject: [PATCH 1/8] feat: add support for single SAA operator actions --- internal/temporalcli/commands.activity.go | 161 ++++++---- .../temporalcli/commands.activity_test.go | 294 +++++++++++++++++- internal/temporalcli/commands.gen.go | 32 +- internal/temporalcli/commands.yaml | 43 ++- 4 files changed, 447 insertions(+), 83 deletions(-) diff --git a/internal/temporalcli/commands.activity.go b/internal/temporalcli/commands.activity.go index ccaa79519..b0a26ab3b 100644 --- a/internal/temporalcli/commands.activity.go +++ b/internal/temporalcli/commands.activity.go @@ -44,6 +44,23 @@ type ( const activityDeleteWarning = "WARNING: Deleting Standalone Activity Executions in a global Namespace removes them from all replicas. Requests sent to a passive cluster are forwarded to the active cluster by default; to target the passive cluster directly, specify `--grpc-meta xdc-redirection=false`." +// Targeting errors for the activity operate commands. They name every flag a +// caller can use so the failure tells the user exactly how to retarget: +// - a single Activity: --activity-id, optionally with --workflow-id (workflow +// Activity) and/or --run-id (specific run; standalone when no --workflow-id) +// - a batch of workflow Activities: --query +var ( + // errActivityTarget is used by the operations that support batching + // (unpause, reset, update-options). + errActivityTarget = errors.New("must specify --activity-id to target a single Activity " + + "(optionally with --workflow-id and/or --run-id), or --query to target a batch of Activities") + + // errPauseActivityTarget is the pause equivalent; pause has no --query + // (batch) mode. + errPauseActivityTarget = errors.New("must specify --activity-id to pause an Activity " + + "(optionally with --workflow-id and/or --run-id)") +) + func (c *TemporalActivityStartCommand) run(cctx *CommandContext, args []string) error { cl, err := dialClient(cctx, &c.Parent.ClientOptions) if err != nil { @@ -924,28 +941,42 @@ func (c *TemporalActivityUpdateOptionsCommand) run(cctx *CommandContext, args [] Rps: c.Rps, } - exec, batchReq, err := opts.workflowExecOrBatch(cctx, c.Parent.Namespace, cl, singleOrBatchOverrides{}) - if err != nil { - return err + // Target a workflow Activity (--workflow-id), a standalone Activity (no + // --workflow-id; the latest run unless --run-id is set), or a batch of + // workflow Activities (--query). The server routes to standalone-activity + // handling when the workflow ID is empty, so standalone Activities take the + // single-execution path below. + var exec *common.WorkflowExecution + var batchReq *workflowservice.StartBatchOperationRequest + if c.WorkflowId == "" && c.Query == "" { + if c.ActivityId == "" { + return errActivityTarget + } + exec = &common.WorkflowExecution{RunId: c.RunId} + } else { + exec, batchReq, err = opts.workflowExecOrBatch(cctx, c.Parent.Namespace, cl, singleOrBatchOverrides{}) + if err != nil { + return err + } } if exec != nil { if c.ActivityId == "" { - return fmt.Errorf("either --activity-id and --workflow-id, or --query must be set") + return errActivityTarget } - result, err := cl.WorkflowService().UpdateActivityOptions(cctx, &workflowservice.UpdateActivityOptionsRequest{ - Namespace: c.Parent.Namespace, - Execution: &common.WorkflowExecution{ - WorkflowId: c.WorkflowId, - RunId: c.RunId, - }, - Activity: &workflowservice.UpdateActivityOptionsRequest_Id{Id: c.ActivityId}, - ActivityOptions: activityOptions, - UpdateMask: &fieldmaskpb.FieldMask{ - Paths: updatePath, - }, - Identity: c.Parent.Identity, - }) + result, err := cl.WorkflowService().UpdateActivityExecutionOptions( + cctx, + &workflowservice.UpdateActivityExecutionOptionsRequest{ + Namespace: c.Parent.Namespace, + WorkflowId: c.WorkflowId, + RunId: c.RunId, + ActivityId: c.ActivityId, + ActivityOptions: activityOptions, + UpdateMask: &fieldmaskpb.FieldMask{ + Paths: updatePath, + }, + Identity: c.Parent.Identity, + }) if err != nil { return fmt.Errorf("unable to update Activity options: %w", err) } @@ -988,8 +1019,12 @@ func (c *TemporalActivityUpdateOptionsCommand) run(cctx *CommandContext, args [] func (c *TemporalActivityPauseCommand) run(cctx *CommandContext, args []string) error { if c.ActivityId == "" { - return fmt.Errorf("Activity Id must be specified") + return errPauseActivityTarget } + // Set --workflow-id to target a workflow Activity. Omit it to target a + // standalone Activity by --activity-id (and optionally --run-id for a + // specific run); the server routes to standalone-activity handling when the + // workflow ID is empty. cl, err := dialClient(cctx, &c.Parent.ClientOptions) if err != nil { @@ -997,21 +1032,19 @@ func (c *TemporalActivityPauseCommand) run(cctx *CommandContext, args []string) } defer cl.Close() - request := &workflowservice.PauseActivityRequest{ - Namespace: c.Parent.Namespace, - Execution: &common.WorkflowExecution{ - WorkflowId: c.WorkflowId, - RunId: c.RunId, - }, - Identity: c.Identity, - Reason: c.Reason, - Activity: &workflowservice.PauseActivityRequest_Id{Id: c.ActivityId}, + request := &workflowservice.PauseActivityExecutionRequest{ + Namespace: c.Parent.Namespace, + WorkflowId: c.WorkflowId, + ActivityId: c.ActivityId, + RunId: c.RunId, + Identity: c.Identity, + Reason: c.Reason, } if request.Identity == "" { request.Identity = c.Parent.Identity } - _, err = cl.WorkflowService().PauseActivity(cctx, request) + _, err = cl.WorkflowService().PauseActivityExecution(cctx, request) if err != nil { return fmt.Errorf("unable to pause Activity: %w", err) } @@ -1037,30 +1070,42 @@ func (c *TemporalActivityUnpauseCommand) run(cctx *CommandContext, args []string Rps: c.Rps, } - exec, batchReq, err := opts.workflowExecOrBatch(cctx, c.Parent.Namespace, cl, singleOrBatchOverrides{}) - if err != nil { - return err + // Target a workflow Activity (--workflow-id), a standalone Activity (no + // --workflow-id; the latest run unless --run-id is set), or a batch of + // workflow Activities (--query). The server routes to standalone-activity + // handling when the workflow ID is empty, so standalone Activities take the + // single-execution path below. + var exec *common.WorkflowExecution + var batchReq *workflowservice.StartBatchOperationRequest + if c.WorkflowId == "" && c.Query == "" { + if c.ActivityId == "" { + return errActivityTarget + } + exec = &common.WorkflowExecution{RunId: c.RunId} + } else { + exec, batchReq, err = opts.workflowExecOrBatch(cctx, c.Parent.Namespace, cl, singleOrBatchOverrides{}) + if err != nil { + return err + } } if exec != nil { // single workflow operation if c.ActivityId == "" { - return fmt.Errorf("either --activity-id and --workflow-id, or --query must be set") + return errActivityTarget } - request := &workflowservice.UnpauseActivityRequest{ - Namespace: c.Parent.Namespace, - Execution: &common.WorkflowExecution{ - WorkflowId: c.WorkflowId, - RunId: c.RunId, - }, + request := &workflowservice.UnpauseActivityExecutionRequest{ + Namespace: c.Parent.Namespace, + WorkflowId: c.WorkflowId, + ActivityId: c.ActivityId, + RunId: c.RunId, ResetAttempts: c.ResetAttempts, ResetHeartbeat: c.ResetHeartbeats, Jitter: durationpb.New(c.Jitter.Duration()), Identity: c.Parent.Identity, - Activity: &workflowservice.UnpauseActivityRequest_Id{Id: c.ActivityId}, } - _, err = cl.WorkflowService().UnpauseActivity(cctx, request) + _, err = cl.WorkflowService().UnpauseActivityExecution(cctx, request) if err != nil { return fmt.Errorf("unable to unpause an Activity: %w", err) } @@ -1103,29 +1148,41 @@ func (c *TemporalActivityResetCommand) run(cctx *CommandContext, args []string) Rps: c.Rps, } - exec, batchReq, err := opts.workflowExecOrBatch(cctx, c.Parent.Namespace, cl, singleOrBatchOverrides{}) - if err != nil { - return err + // Target a workflow Activity (--workflow-id), a standalone Activity (no + // --workflow-id; the latest run unless --run-id is set), or a batch of + // workflow Activities (--query). The server routes to standalone-activity + // handling when the workflow ID is empty, so standalone Activities take the + // single-execution path below. + var exec *common.WorkflowExecution + var batchReq *workflowservice.StartBatchOperationRequest + if c.WorkflowId == "" && c.Query == "" { + if c.ActivityId == "" { + return errActivityTarget + } + exec = &common.WorkflowExecution{RunId: c.RunId} + } else { + exec, batchReq, err = opts.workflowExecOrBatch(cctx, c.Parent.Namespace, cl, singleOrBatchOverrides{}) + if err != nil { + return err + } } if exec != nil { // single workflow operation if c.ActivityId == "" { - return fmt.Errorf("either --activity-id and --workflow-id, or --query must be set") + return errActivityTarget } - request := &workflowservice.ResetActivityRequest{ - Activity: &workflowservice.ResetActivityRequest_Id{Id: c.ActivityId}, - Namespace: c.Parent.Namespace, - Execution: &common.WorkflowExecution{ - WorkflowId: c.WorkflowId, - RunId: c.RunId, - }, + request := &workflowservice.ResetActivityExecutionRequest{ + Namespace: c.Parent.Namespace, + WorkflowId: c.WorkflowId, + ActivityId: c.ActivityId, + RunId: c.RunId, Identity: c.Parent.Identity, KeepPaused: c.KeepPaused, ResetHeartbeat: c.ResetHeartbeats, } - resp, err := cl.WorkflowService().ResetActivity(cctx, request) + resp, err := cl.WorkflowService().ResetActivityExecution(cctx, request) if err != nil { return fmt.Errorf("unable to reset an Activity: %w", err) } diff --git a/internal/temporalcli/commands.activity_test.go b/internal/temporalcli/commands.activity_test.go index be2bf9c2e..8acb32264 100644 --- a/internal/temporalcli/commands.activity_test.go +++ b/internal/temporalcli/commands.activity_test.go @@ -234,14 +234,18 @@ func (s *SharedServerSuite) TestActivityPauseUnpause() { func (s *SharedServerSuite) TestActivityCommandFailed_NoActivityId() { run := s.waitActivityStarted() - // pause is single-workflow only + // pause is single-operation only; its error names --activity-id (and the + // optional --workflow-id/--run-id) but not --query. res := sendActivityCommand("pause", run, s) - s.ErrorContains(res.Err, "Activity Id must be specified") + s.ErrorContains(res.Err, "must specify --activity-id") + s.NotContains(res.Err.Error(), "--query") - // unpause and reset support both single-workflow and batch modes + // unpause and reset support both single-operation and batch modes, so their + // error names --activity-id and --query. for _, command := range []string{"unpause", "reset"} { res = sendActivityCommand(command, run, s) - s.ErrorContains(res.Err, "either --activity-id and --workflow-id, or --query must be set") + s.ErrorContains(res.Err, "must specify --activity-id") + s.ErrorContains(res.Err, "--query") } } @@ -280,6 +284,288 @@ func (s *SharedServerSuite) TestActivityReset() { s.ErrorAs(res.Err, ¬Found) } +// Standalone (workflow-less) activity tests. These exercise CLI routing to the +// *ActivityExecution APIs: when no --workflow-id is set, the activity is +// targeted by --activity-id and --run-id and the server routes the request to +// standalone-activity handling. + +func newStandaloneActivityID() string { + return "standalone-activity-" + uuid.NewString() +} + +func (s *SharedServerSuite) TestActivityStandalone_Pause() { + handle, stopFailing := s.startStandaloneActivity(newStandaloneActivityID()) + defer stopFailing() + + res := s.Execute( + "activity", "pause", + "--activity-id", handle.GetID(), + "--run-id", handle.GetRunID(), + "--identity", identity, + "--address", s.Address(), + ) + s.NoError(res.Err) + + s.Eventually(func() bool { + return s.standaloneActivityRunState(handle) == enums.PENDING_ACTIVITY_STATE_PAUSED + }, 10*time.Second, 100*time.Millisecond) +} + +func (s *SharedServerSuite) TestActivityStandalone_Unpause() { + handle, stopFailing := s.startStandaloneActivity(newStandaloneActivityID()) + defer stopFailing() + + res := s.Execute( + "activity", "pause", + "--activity-id", handle.GetID(), + "--run-id", handle.GetRunID(), + "--address", s.Address(), + ) + s.NoError(res.Err) + s.Eventually(func() bool { + return s.standaloneActivityRunState(handle) == enums.PENDING_ACTIVITY_STATE_PAUSED + }, 10*time.Second, 100*time.Millisecond) + + res = s.Execute( + "activity", "unpause", + "--activity-id", handle.GetID(), + "--run-id", handle.GetRunID(), + "--reset-attempts", + "--address", s.Address(), + ) + s.NoError(res.Err) + s.Eventually(func() bool { + return s.standaloneActivityRunState(handle) != enums.PENDING_ACTIVITY_STATE_PAUSED + }, 10*time.Second, 100*time.Millisecond) +} + +func (s *SharedServerSuite) TestActivityStandalone_Reset() { + handle, stopFailing := s.startStandaloneActivity(newStandaloneActivityID()) + defer stopFailing() + + res := s.Execute( + "activity", "reset", + "--activity-id", handle.GetID(), + "--run-id", handle.GetRunID(), + "--address", s.Address(), + ) + s.NoError(res.Err) + s.ContainsOnSameLine(res.Stdout.String(), "ServerResponse", "true") + + // Targeting a missing standalone activity surfaces the server's NotFound. + res = s.Execute( + "activity", "reset", + "--activity-id", "fake-standalone-id", + "--run-id", handle.GetRunID(), + "--address", s.Address(), + ) + s.Error(res.Err) + var notFound *serviceerror.NotFound + s.ErrorAs(res.Err, ¬Found) +} + +func (s *SharedServerSuite) TestActivityStandalone_UpdateOptions() { + handle, stopFailing := s.startStandaloneActivity(newStandaloneActivityID()) + defer stopFailing() + + res := s.Execute( + "activity", "update-options", + "--activity-id", handle.GetID(), + "--run-id", handle.GetRunID(), + "--identity", identity, + "--schedule-to-close-timeout", "60s", + "--start-to-close-timeout", "10s", + "--retry-initial-interval", "5s", + "--retry-maximum-attempts", "5", + "--address", s.Address(), + ) + s.NoError(res.Err) + out := res.Stdout.String() + s.ContainsOnSameLine(out, "ScheduleToCloseTimeout", "1m0s") + s.ContainsOnSameLine(out, "StartToCloseTimeout", "10s") + s.ContainsOnSameLine(out, "InitialInterval", "5s") + s.ContainsOnSameLine(out, "MaximumAttempts", "5") +} + +func (s *SharedServerSuite) TestActivityStandalone_PauseByActivityIdOnly() { + handle, stopFailing := s.startStandaloneActivity(newStandaloneActivityID()) + defer stopFailing() + + // Without --run-id, the command targets the latest run of the Activity ID. + res := s.Execute( + "activity", "pause", + "--activity-id", handle.GetID(), + "--address", s.Address(), + ) + s.NoError(res.Err) + + s.Eventually(func() bool { + return s.standaloneActivityRunState(handle) == enums.PENDING_ACTIVITY_STATE_PAUSED + }, 10*time.Second, 100*time.Millisecond) +} + +func (s *SharedServerSuite) TestActivityStandalone_RequiresActivityId() { + // With neither --activity-id nor --query, every operation is an error, and + // the message tells the user how to retarget: it names --activity-id and the + // optional --workflow-id/--run-id, plus --query for the batch-capable + // operations (pause has no --query mode). + for _, command := range []string{"pause", "unpause", "reset", "update-options"} { + res := s.Execute( + "activity", command, + "--address", s.Address(), + ) + s.Error(res.Err, "command %q should require --activity-id", command) + s.ErrorContains(res.Err, "--activity-id") + s.ErrorContains(res.Err, "--workflow-id") + s.ErrorContains(res.Err, "--run-id") + if command == "pause" { + s.NotContains(res.Err.Error(), "--query") + } else { + s.ErrorContains(res.Err, "--query") + } + } +} + +// startStandaloneActivity starts a standalone (workflow-less) activity that +// fails and retries indefinitely, so it stays pending and can be paused, reset, +// or updated cleanly. It waits for the activity to be picked up and returns the +// handle plus a function that lets the activity complete (used for cleanup). +func (s *SharedServerSuite) startStandaloneActivity(actID string) (client.ActivityHandle, func()) { + var failActivity atomic.Bool + failActivity.Store(true) + s.Worker().OnDevActivity(func(ctx context.Context, a any) (any, error) { + if failActivity.Load() { + return nil, fmt.Errorf("standalone activity failing on purpose") + } + return nil, nil + }) + handle, err := s.Client.ExecuteActivity( + s.Context, + client.StartActivityOptions{ + ID: actID, + TaskQueue: s.Worker().Options.TaskQueue, + StartToCloseTimeout: time.Minute, + RetryPolicy: &temporal.RetryPolicy{ + InitialInterval: time.Second, + MaximumInterval: time.Second, + }, + }, + "DevActivity", + "input", + ) + s.NoError(err) + s.Eventually(func() bool { + desc, err := handle.Describe(s.Context, client.DescribeActivityOptions{}) + s.NoError(err) + return desc.Attempt >= 1 + }, 10*time.Second, 100*time.Millisecond) + return handle, func() { failActivity.Store(false) } +} + +func (s *SharedServerSuite) standaloneActivityRunState(handle client.ActivityHandle) enums.PendingActivityState { + desc, err := handle.Describe(s.Context, client.DescribeActivityOptions{}) + s.NoError(err) + return desc.RunState +} + +// TestActivityInvalidTargeting covers every invalid row of the activity +// single-operation targeting matrix, across all of the operations that share +// it. A single operation needs --activity-id plus either --workflow-id or +// --run-id, and --query is mutually exclusive with both --workflow-id and +// --run-id, so each of these combinations is rejected. +// +// reset/unpause/update-options reject the --query combinations as targeting +// errors. pause has no --query flag, so it rejects them as unknown-flag errors; +// either way the combination is rejected, which is the behavior under test. +func (s *SharedServerSuite) TestActivityInvalidTargeting() { + const q = "WorkflowType='DevWorkflow'" + cases := []struct { + name string + activityID string + workflowID string + runID string + query string + }{ + {name: "nothing set"}, + {name: "run-id only", runID: "r-id"}, + {name: "run-id and query", runID: "r-id", query: q}, + {name: "workflow-id only", workflowID: "w-id"}, + {name: "workflow-id and query", workflowID: "w-id", query: q}, + {name: "workflow-id and run-id, no activity-id", workflowID: "w-id", runID: "r-id"}, + {name: "workflow-id, run-id, and query", workflowID: "w-id", runID: "r-id", query: q}, + {name: "activity-id, run-id, and query", activityID: "a-id", runID: "r-id", query: q}, + {name: "activity-id, workflow-id, and query", activityID: "a-id", workflowID: "w-id", query: q}, + {name: "all flags set", activityID: "a-id", workflowID: "w-id", runID: "r-id", query: q}, + } + for _, command := range []string{"pause", "unpause", "reset", "update-options"} { + for _, tc := range cases { + args := []string{"activity", command, "--address", s.Address()} + if tc.activityID != "" { + args = append(args, "--activity-id", tc.activityID) + } + if tc.workflowID != "" { + args = append(args, "--workflow-id", tc.workflowID) + } + if tc.runID != "" { + args = append(args, "--run-id", tc.runID) + } + if tc.query != "" { + args = append(args, "--query", tc.query) + } + res := s.Execute(args...) + s.Error(res.Err, "command %q case %q should be invalid", command, tc.name) + } + } +} + +// TestActivityReset_WorkflowActivityLatestRun covers --activity-id + +// --workflow-id with no --run-id: a specific activity in the workflow's latest +// run. +func (s *SharedServerSuite) TestActivityReset_WorkflowActivityLatestRun() { + run := s.waitActivityStarted() + + res := s.Execute( + "activity", "reset", + "--activity-id", activityId, + "--workflow-id", run.GetID(), + "--address", s.Address(), + ) + s.NoError(res.Err) + s.ContainsOnSameLine(res.Stdout.String(), "ServerResponse", "true") +} + +// TestActivityReset_ActivityIdWithQueryStartsBatch covers --activity-id + +// --query: the activity ID is ignored and a batch over the matching workflows +// is started instead. +func (s *SharedServerSuite) TestActivityReset_ActivityIdWithQueryStartsBatch() { + run := s.waitActivityStarted() + + var startedBatch atomic.Bool + s.CommandHarness.Options.AdditionalClientGRPCDialOptions = append( + s.CommandHarness.Options.AdditionalClientGRPCDialOptions, + grpc.WithChainUnaryInterceptor(func( + ctx context.Context, + method string, req, reply any, + cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption, + ) error { + if _, ok := req.(*workflowservice.StartBatchOperationRequest); ok { + startedBatch.Store(true) + } + return invoker(ctx, method, req, reply, cc, opts...) + }), + ) + + res := s.Execute( + "activity", "reset", + "--activity-id", "ignored-activity-id", + "--query", fmt.Sprintf("WorkflowId = '%s'", run.GetID()), + "--yes", + "--address", s.Address(), + ) + s.NoError(res.Err) + s.True(startedBatch.Load(), "a batch operation should have been started") +} + // Test helpers func (s *SharedServerSuite) waitActivityStarted() client.WorkflowRun { diff --git a/internal/temporalcli/commands.gen.go b/internal/temporalcli/commands.gen.go index f3130a8ae..8a127c84d 100644 --- a/internal/temporalcli/commands.gen.go +++ b/internal/temporalcli/commands.gen.go @@ -826,10 +826,11 @@ func NewTemporalActivityListCommand(cctx *CommandContext, parent *TemporalActivi } type TemporalActivityPauseCommand struct { - Parent *TemporalActivityCommand - Command cobra.Command - WorkflowReferenceOptions + Parent *TemporalActivityCommand + Command cobra.Command ActivityId string + WorkflowId string + RunId string Identity string Reason string } @@ -841,15 +842,16 @@ func NewTemporalActivityPauseCommand(cctx *CommandContext, parent *TemporalActiv s.Command.Use = "pause [flags]" s.Command.Short = "Pause an Activity" if hasHighlighting { - s.Command.Long = "Pause an Activity. Not supported for Standalone Activities.\n\nIf the Activity is not currently running (e.g. because it previously\nfailed), it will not be run again until it is unpaused.\n\nHowever, if the Activity is currently running, it will run until the next\ntime it fails, completes, or times out, at which point the pause will kick in.\n\nPause does not stop or extend the Activity's Schedule-To-Close Timeout.\nA paused Activity can still time out. Use \x1b[1mtemporal activity update-options\x1b[0m\nto extend timeout settings before a long pause.\n\nIf the Activity is on its last retry attempt and fails, the failure will\nbe returned to the caller, just as if the Activity had not been paused.\n\nSpecify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity pause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\x1b[0m\n\nTo later unpause the activity, see unpause. You may also want to\nreset the activity to unpause it while also starting it from the beginning." + s.Command.Long = "Pause an Activity.\n\nIf the Activity is not currently running (e.g. because it previously\nfailed), it will not be run again until it is unpaused.\n\nHowever, if the Activity is currently running, it will run until the next\ntime it fails, completes, or times out, at which point the pause will kick in.\n\nIf the Activity is on its last retry attempt and fails, the failure will\nbe returned to the caller, just as if the Activity had not been paused.\n\nTo target a workflow Activity, specify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity pause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\x1b[0m\n\nTo target a standalone Activity, specify the Activity and Run IDs:\n\n\x1b[1mtemporal activity pause \\\n --activity-id YourActivityId \\\n --run-id YourRunId\x1b[0m\n\nTo later unpause the activity, see unpause. You may also want to\nreset the activity to unpause it while also starting it from the beginning." } else { - s.Command.Long = "Pause an Activity. Not supported for Standalone Activities.\n\nIf the Activity is not currently running (e.g. because it previously\nfailed), it will not be run again until it is unpaused.\n\nHowever, if the Activity is currently running, it will run until the next\ntime it fails, completes, or times out, at which point the pause will kick in.\n\nPause does not stop or extend the Activity's Schedule-To-Close Timeout.\nA paused Activity can still time out. Use `temporal activity update-options`\nto extend timeout settings before a long pause.\n\nIf the Activity is on its last retry attempt and fails, the failure will\nbe returned to the caller, just as if the Activity had not been paused.\n\nSpecify the Activity and Workflow IDs:\n\n```\ntemporal activity pause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n```\n\nTo later unpause the activity, see unpause. You may also want to\nreset the activity to unpause it while also starting it from the beginning." + s.Command.Long = "Pause an Activity.\n\nIf the Activity is not currently running (e.g. because it previously\nfailed), it will not be run again until it is unpaused.\n\nHowever, if the Activity is currently running, it will run until the next\ntime it fails, completes, or times out, at which point the pause will kick in.\n\nIf the Activity is on its last retry attempt and fails, the failure will\nbe returned to the caller, just as if the Activity had not been paused.\n\nTo target a workflow Activity, specify the Activity and Workflow IDs:\n\n```\ntemporal activity pause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n```\n\nTo target a standalone Activity, specify the Activity and Run IDs:\n\n```\ntemporal activity pause \\\n --activity-id YourActivityId \\\n --run-id YourRunId\n```\n\nTo later unpause the activity, see unpause. You may also want to\nreset the activity to unpause it while also starting it from the beginning." } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "The Activity ID to pause. Required.") + s.Command.Flags().StringVarP(&s.WorkflowId, "workflow-id", "w", "", "Workflow ID. Set to target a workflow Activity. Omit to target a standalone Activity.") + s.Command.Flags().StringVarP(&s.RunId, "run-id", "r", "", "Run ID. With --workflow-id, identifies the workflow run. For a standalone Activity (no --workflow-id), targets a specific run; omit to target the latest run.") s.Command.Flags().StringVar(&s.Identity, "identity", "", "The identity of the user or client submitting this request.") s.Command.Flags().StringVar(&s.Reason, "reason", "", "Reason for pausing the Activity.") - s.WorkflowReferenceOptions.BuildFlags(s.Command.Flags()) s.Command.Run = func(c *cobra.Command, args []string) { if err := s.run(cctx, args); err != nil { cctx.Options.Fail(err) @@ -877,12 +879,12 @@ func NewTemporalActivityResetCommand(cctx *CommandContext, parent *TemporalActiv s.Command.Use = "reset [flags]" s.Command.Short = "Reset an Activity" if hasHighlighting { - s.Command.Long = "Reset an activity. Not supported for Standalone Activities.\nThis restarts the activity as if it were first being\nscheduled. That is, it will reset both the number of attempts and the\nactivity timeout, as well as, optionally, the\nheartbeat details.\n\nIf the activity may be executing (i.e. it has not yet timed out), the\nreset will take effect the next time it fails, heartbeats, or times out.\nIf is waiting for a retry (i.e. has failed or timed out), the reset\nwill apply immediately.\n\nIf the activity is already paused, it will be unpaused by default.\nYou can specify \x1b[1mkeep_paused\x1b[0m to prevent this.\n\nIf the activity is paused and the \x1b[1mkeep_paused\x1b[0m flag is not provided,\nit will be unpaused. If the activity is paused and \x1b[1mkeep_paused\x1b[0m flag\nis provided - it will stay paused.\n\nEither \x1b[1m--activity-id\x1b[0m (with \x1b[1m--workflow-id\x1b[0m) or \x1b[1m--query\x1b[0m must be specified.\n\n### Resetting activities that heartbeat {#reset-heartbeats}\n\nActivities that heartbeat will receive a Canceled failure\nthe next time they heartbeat after a reset.\n\nIf, in your Activity, you need to do any cleanup when an Activity is\nreset, handle this error and then re-throw it when you've cleaned up.\n\nIf the \x1b[1mreset_heartbeats\x1b[0m flag is set, the heartbeat details will also be cleared.\n\nSpecify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --keep-paused\n --reset-heartbeats\x1b[0m\n\nActivities can be reset in bulk with a visibility query list filter:\n\n\x1b[1mtemporal activity reset \\\n --query 'WorkflowType=\"YourWorkflow\"'\x1b[0m" + s.Command.Long = "Reset an activity.\nThis restarts the activity as if it were first being\nscheduled. That is, it will reset both the number of attempts and the\nactivity timeout, as well as, optionally, the\nheartbeat details.\n\nIf the activity may be executing (i.e. it has not yet timed out), the\nreset will take effect the next time it fails, heartbeats, or times out.\nIf is waiting for a retry (i.e. has failed or timed out), the reset\nwill apply immediately.\n\nIf the activity is already paused, it will be unpaused by default.\nYou can specify \x1b[1mkeep_paused\x1b[0m to prevent this.\n\nIf the activity is paused and the \x1b[1mkeep_paused\x1b[0m flag is not provided,\nit will be unpaused. If the activity is paused and \x1b[1mkeep_paused\x1b[0m flag\nis provided - it will stay paused.\n\nEither \x1b[1m--activity-id\x1b[0m (with \x1b[1m--workflow-id\x1b[0m for a workflow Activity, or\nalone for a standalone Activity) or \x1b[1m--query\x1b[0m must be specified.\n\n### Resetting activities that heartbeat {#reset-heartbeats}\n\nActivities that heartbeat will receive a Canceled failure\nthe next time they heartbeat after a reset.\n\nIf, in your Activity, you need to do any cleanup when an Activity is\nreset, handle this error and then re-throw it when you've cleaned up.\n\nIf the \x1b[1mreset_heartbeats\x1b[0m flag is set, the heartbeat details will also be cleared.\n\nSpecify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --keep-paused\n --reset-heartbeats\x1b[0m\n\nActivities can be reset in bulk with a visibility query list filter:\n\n\x1b[1mtemporal activity reset \\\n --query 'WorkflowType=\"YourWorkflow\"'\x1b[0m" } else { - s.Command.Long = "Reset an activity. Not supported for Standalone Activities.\nThis restarts the activity as if it were first being\nscheduled. That is, it will reset both the number of attempts and the\nactivity timeout, as well as, optionally, the\nheartbeat details.\n\nIf the activity may be executing (i.e. it has not yet timed out), the\nreset will take effect the next time it fails, heartbeats, or times out.\nIf is waiting for a retry (i.e. has failed or timed out), the reset\nwill apply immediately.\n\nIf the activity is already paused, it will be unpaused by default.\nYou can specify `keep_paused` to prevent this.\n\nIf the activity is paused and the `keep_paused` flag is not provided,\nit will be unpaused. If the activity is paused and `keep_paused` flag\nis provided - it will stay paused.\n\nEither `--activity-id` (with `--workflow-id`) or `--query` must be specified.\n\n### Resetting activities that heartbeat {#reset-heartbeats}\n\nActivities that heartbeat will receive a Canceled failure\nthe next time they heartbeat after a reset.\n\nIf, in your Activity, you need to do any cleanup when an Activity is\nreset, handle this error and then re-throw it when you've cleaned up.\n\nIf the `reset_heartbeats` flag is set, the heartbeat details will also be cleared.\n\nSpecify the Activity and Workflow IDs:\n\n```\ntemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --keep-paused\n --reset-heartbeats\n```\n\nActivities can be reset in bulk with a visibility query list filter:\n\n```\ntemporal activity reset \\\n --query 'WorkflowType=\"YourWorkflow\"'\n```" + s.Command.Long = "Reset an activity.\nThis restarts the activity as if it were first being\nscheduled. That is, it will reset both the number of attempts and the\nactivity timeout, as well as, optionally, the\nheartbeat details.\n\nIf the activity may be executing (i.e. it has not yet timed out), the\nreset will take effect the next time it fails, heartbeats, or times out.\nIf is waiting for a retry (i.e. has failed or timed out), the reset\nwill apply immediately.\n\nIf the activity is already paused, it will be unpaused by default.\nYou can specify `keep_paused` to prevent this.\n\nIf the activity is paused and the `keep_paused` flag is not provided,\nit will be unpaused. If the activity is paused and `keep_paused` flag\nis provided - it will stay paused.\n\nEither `--activity-id` (with `--workflow-id` for a workflow Activity, or\nalone for a standalone Activity) or `--query` must be specified.\n\n### Resetting activities that heartbeat {#reset-heartbeats}\n\nActivities that heartbeat will receive a Canceled failure\nthe next time they heartbeat after a reset.\n\nIf, in your Activity, you need to do any cleanup when an Activity is\nreset, handle this error and then re-throw it when you've cleaned up.\n\nIf the `reset_heartbeats` flag is set, the heartbeat details will also be cleared.\n\nSpecify the Activity and Workflow IDs:\n\n```\ntemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --keep-paused\n --reset-heartbeats\n```\n\nActivities can be reset in bulk with a visibility query list filter:\n\n```\ntemporal activity reset \\\n --query 'WorkflowType=\"YourWorkflow\"'\n```" } s.Command.Args = cobra.NoArgs - s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "The Activity ID to reset. Mutually exclusive with `--query`. Requires `--workflow-id` to be specified.") + s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "The Activity ID to reset. Mutually exclusive with `--query`. Set `--workflow-id` to target a workflow Activity, or omit it to target a standalone Activity (the latest run unless `--run-id` is set).") s.Command.Flags().BoolVar(&s.KeepPaused, "keep-paused", false, "If the activity was paused, it will stay paused.") s.Command.Flags().BoolVar(&s.ResetAttempts, "reset-attempts", false, "Reset the activity attempts.") s.Command.Flags().BoolVar(&s.ResetHeartbeats, "reset-heartbeats", false, "Reset the Activity's heartbeats.") @@ -1002,12 +1004,12 @@ func NewTemporalActivityUnpauseCommand(cctx *CommandContext, parent *TemporalAct s.Command.Use = "unpause [flags]" s.Command.Short = "Unpause an Activity" if hasHighlighting { - s.Command.Long = "Re-schedule a previously-paused Activity for execution.\nNot supported for Standalone Activities.\n\nIf the Activity is not running and is past its retry timeout, it will be\nscheduled immediately. Otherwise, it will be scheduled after its retry\ntimeout expires.\n\nUse \x1b[1m--reset-attempts\x1b[0m to reset the number of previous run attempts to\nzero. For example, if an Activity is near the maximum number of attempts\nN specified in its retry policy, \x1b[1m--reset-attempts\x1b[0m will allow the\nActivity to be retried another N times after unpausing.\n\nUse \x1b[1m--reset-heartbeat\x1b[0m to reset the Activity's heartbeats.\n\nEither \x1b[1m--activity-id\x1b[0m (with \x1b[1m--workflow-id\x1b[0m) or \x1b[1m--query\x1b[0m must be specified.\n\nSpecify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity unpause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --reset-attempts\n --reset-heartbeats\x1b[0m\n\nActivities can be unpaused in bulk via a visibility Query list filter:\n\n\x1b[1mtemporal activity unpause \\\n --query 'TemporalPauseInfo IS NOT NULL'\x1b[0m" + s.Command.Long = "Re-schedule a previously-paused Activity for execution.\n\nIf the Activity is not running and is past its retry timeout, it will be\nscheduled immediately. Otherwise, it will be scheduled after its retry\ntimeout expires.\n\nUse \x1b[1m--reset-attempts\x1b[0m to reset the number of previous run attempts to\nzero. For example, if an Activity is near the maximum number of attempts\nN specified in its retry policy, \x1b[1m--reset-attempts\x1b[0m will allow the\nActivity to be retried another N times after unpausing.\n\nUse \x1b[1m--reset-heartbeat\x1b[0m to reset the Activity's heartbeats.\n\nEither \x1b[1m--activity-id\x1b[0m (with \x1b[1m--workflow-id\x1b[0m for a workflow Activity, or\nalone for a standalone Activity) or \x1b[1m--query\x1b[0m must be specified.\n\nSpecify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity unpause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --reset-attempts\n --reset-heartbeats\x1b[0m\n\nActivities can be unpaused in bulk via a visibility Query list filter:\n\n\x1b[1mtemporal activity unpause \\\n --query 'TemporalPauseInfo IS NOT NULL'\x1b[0m" } else { - s.Command.Long = "Re-schedule a previously-paused Activity for execution.\nNot supported for Standalone Activities.\n\nIf the Activity is not running and is past its retry timeout, it will be\nscheduled immediately. Otherwise, it will be scheduled after its retry\ntimeout expires.\n\nUse `--reset-attempts` to reset the number of previous run attempts to\nzero. For example, if an Activity is near the maximum number of attempts\nN specified in its retry policy, `--reset-attempts` will allow the\nActivity to be retried another N times after unpausing.\n\nUse `--reset-heartbeat` to reset the Activity's heartbeats.\n\nEither `--activity-id` (with `--workflow-id`) or `--query` must be specified.\n\nSpecify the Activity and Workflow IDs:\n\n```\ntemporal activity unpause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --reset-attempts\n --reset-heartbeats\n```\n\nActivities can be unpaused in bulk via a visibility Query list filter:\n\n```\ntemporal activity unpause \\\n --query 'TemporalPauseInfo IS NOT NULL'\n```" + s.Command.Long = "Re-schedule a previously-paused Activity for execution.\n\nIf the Activity is not running and is past its retry timeout, it will be\nscheduled immediately. Otherwise, it will be scheduled after its retry\ntimeout expires.\n\nUse `--reset-attempts` to reset the number of previous run attempts to\nzero. For example, if an Activity is near the maximum number of attempts\nN specified in its retry policy, `--reset-attempts` will allow the\nActivity to be retried another N times after unpausing.\n\nUse `--reset-heartbeat` to reset the Activity's heartbeats.\n\nEither `--activity-id` (with `--workflow-id` for a workflow Activity, or\nalone for a standalone Activity) or `--query` must be specified.\n\nSpecify the Activity and Workflow IDs:\n\n```\ntemporal activity unpause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --reset-attempts\n --reset-heartbeats\n```\n\nActivities can be unpaused in bulk via a visibility Query list filter:\n\n```\ntemporal activity unpause \\\n --query 'TemporalPauseInfo IS NOT NULL'\n```" } s.Command.Args = cobra.NoArgs - s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "The Activity ID to unpause. Mutually exclusive with `--query`. Requires `--workflow-id` to be specified.") + s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "The Activity ID to unpause. Mutually exclusive with `--query`. Set `--workflow-id` to target a workflow Activity, or omit it to target a standalone Activity (the latest run unless `--run-id` is set).") s.Command.Flags().BoolVar(&s.ResetAttempts, "reset-attempts", false, "Reset the activity attempts.") s.Command.Flags().BoolVar(&s.ResetHeartbeats, "reset-heartbeats", false, "Reset the Activity's heartbeats.") s.Jitter = 0 @@ -1045,12 +1047,12 @@ func NewTemporalActivityUpdateOptionsCommand(cctx *CommandContext, parent *Tempo s.Command.Use = "update-options [flags]" s.Command.Short = "Change the values of options affecting a running Activity" if hasHighlighting { - s.Command.Long = "Update the options of a running Activity that were passed into it from\na Workflow. Updates are incremental, only changing the specified options.\nNot supported for Standalone Activities.\n\nFor example:\n\n\x1b[1mtemporal activity update-options \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --task-queue NewTaskQueueName \\\n --schedule-to-close-timeout DURATION \\\n --schedule-to-start-timeout DURATION \\\n --start-to-close-timeout DURATION \\\n --heartbeat-timeout DURATION \\\n --retry-initial-interval DURATION \\\n --retry-maximum-interval DURATION \\\n --retry-backoff-coefficient NewBackoffCoefficient \\\n --retry-maximum-attempts NewMaximumAttempts\x1b[0m\n\nYou may follow this command with \x1b[1mtemporal activity reset\x1b[0m, and the new values will apply after the reset.\n\nEither \x1b[1m--activity-id\x1b[0m or \x1b[1m--query\x1b[0m must be specified.\n\nActivity options can be updated in bulk with a visibility query list filter:\n\n\x1b[1mtemporal activity update-options \\\n --query 'WorkflowType=\"YourWorkflow\"' \\\n --task-queue NewTaskQueueName\x1b[0m" + s.Command.Long = "Update the options of a running Activity that were passed into it from\na Workflow. Updates are incremental, only changing the specified options.\n\nFor example:\n\n\x1b[1mtemporal activity update-options \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --task-queue NewTaskQueueName \\\n --schedule-to-close-timeout DURATION \\\n --schedule-to-start-timeout DURATION \\\n --start-to-close-timeout DURATION \\\n --heartbeat-timeout DURATION \\\n --retry-initial-interval DURATION \\\n --retry-maximum-interval DURATION \\\n --retry-backoff-coefficient NewBackoffCoefficient \\\n --retry-maximum-attempts NewMaximumAttempts\x1b[0m\n\nYou may follow this command with \x1b[1mtemporal activity reset\x1b[0m, and the new values will apply after the reset.\n\nEither \x1b[1m--activity-id\x1b[0m or \x1b[1m--query\x1b[0m must be specified.\n\nActivity options can be updated in bulk with a visibility query list filter:\n\n\x1b[1mtemporal activity update-options \\\n --query 'WorkflowType=\"YourWorkflow\"' \\\n --task-queue NewTaskQueueName\x1b[0m" } else { - s.Command.Long = "Update the options of a running Activity that were passed into it from\na Workflow. Updates are incremental, only changing the specified options.\nNot supported for Standalone Activities.\n\nFor example:\n\n```\ntemporal activity update-options \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --task-queue NewTaskQueueName \\\n --schedule-to-close-timeout DURATION \\\n --schedule-to-start-timeout DURATION \\\n --start-to-close-timeout DURATION \\\n --heartbeat-timeout DURATION \\\n --retry-initial-interval DURATION \\\n --retry-maximum-interval DURATION \\\n --retry-backoff-coefficient NewBackoffCoefficient \\\n --retry-maximum-attempts NewMaximumAttempts\n```\n\nYou may follow this command with `temporal activity reset`, and the new values will apply after the reset.\n\nEither `--activity-id` or `--query` must be specified.\n\nActivity options can be updated in bulk with a visibility query list filter:\n\n```\ntemporal activity update-options \\\n --query 'WorkflowType=\"YourWorkflow\"' \\\n --task-queue NewTaskQueueName\n```" + s.Command.Long = "Update the options of a running Activity that were passed into it from\na Workflow. Updates are incremental, only changing the specified options.\n\nFor example:\n\n```\ntemporal activity update-options \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --task-queue NewTaskQueueName \\\n --schedule-to-close-timeout DURATION \\\n --schedule-to-start-timeout DURATION \\\n --start-to-close-timeout DURATION \\\n --heartbeat-timeout DURATION \\\n --retry-initial-interval DURATION \\\n --retry-maximum-interval DURATION \\\n --retry-backoff-coefficient NewBackoffCoefficient \\\n --retry-maximum-attempts NewMaximumAttempts\n```\n\nYou may follow this command with `temporal activity reset`, and the new values will apply after the reset.\n\nEither `--activity-id` or `--query` must be specified.\n\nActivity options can be updated in bulk with a visibility query list filter:\n\n```\ntemporal activity update-options \\\n --query 'WorkflowType=\"YourWorkflow\"' \\\n --task-queue NewTaskQueueName\n```" } s.Command.Args = cobra.NoArgs - s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "The Activity ID to update options. Mutually exclusive with `--query`. Requires `--workflow-id` to be specified.") + s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "The Activity ID to update options. Mutually exclusive with `--query`. Set `--workflow-id` to target a workflow Activity, or omit it to target a standalone Activity (the latest run unless `--run-id` is set).") s.Command.Flags().StringVar(&s.TaskQueue, "task-queue", "", "Name of the task queue for the Activity.") s.ScheduleToCloseTimeout = 0 s.Command.Flags().Var(&s.ScheduleToCloseTimeout, "schedule-to-close-timeout", "Indicates how long the caller is willing to wait for an activity completion. Limits how long retries will be attempted.") diff --git a/internal/temporalcli/commands.yaml b/internal/temporalcli/commands.yaml index 678a87916..43017df91 100644 --- a/internal/temporalcli/commands.yaml +++ b/internal/temporalcli/commands.yaml @@ -387,7 +387,6 @@ commands: description: | Update the options of a running Activity that were passed into it from a Workflow. Updates are incremental, only changing the specified options. - Not supported for Standalone Activities. For example: @@ -422,7 +421,7 @@ commands: short: a type: string description: | - The Activity ID to update options. Mutually exclusive with `--query`. Requires `--workflow-id` to be specified. + The Activity ID to update options. Mutually exclusive with `--query`. Set `--workflow-id` to target a workflow Activity, or omit it to target a standalone Activity (the latest run unless `--run-id` is set). - name: task-queue type: string description: Name of the task queue for the Activity. @@ -484,7 +483,7 @@ commands: - name: temporal activity pause summary: Pause an Activity description: | - Pause an Activity. Not supported for Standalone Activities. + Pause an Activity. If the Activity is not currently running (e.g. because it previously failed), it will not be run again until it is unpaused. @@ -499,7 +498,7 @@ commands: If the Activity is on its last retry attempt and fails, the failure will be returned to the caller, just as if the Activity had not been paused. - Specify the Activity and Workflow IDs: + To target a workflow Activity, specify the Activity and Workflow IDs: ``` temporal activity pause \ @@ -507,6 +506,14 @@ commands: --workflow-id YourWorkflowId ``` + To target a standalone Activity, specify the Activity and Run IDs: + + ``` + temporal activity pause \ + --activity-id YourActivityId \ + --run-id YourRunId + ``` + To later unpause the activity, see [unpause](#unpause). You may also want to [reset](#reset) the activity to unpause it while also starting it from the beginning. options: @@ -514,20 +521,30 @@ commands: short: a type: string description: The Activity ID to pause. Required. + - name: workflow-id + short: w + type: string + description: | + Workflow ID. Set to target a workflow Activity. Omit to target a + standalone Activity. + - name: run-id + short: r + type: string + description: | + Run ID. With --workflow-id, identifies the workflow run. For a + standalone Activity (no --workflow-id), targets a specific run; + omit to target the latest run. - name: identity type: string description: The identity of the user or client submitting this request. - name: reason type: string description: Reason for pausing the Activity. - option-sets: - - workflow-reference - name: temporal activity unpause summary: Unpause an Activity description: | Re-schedule a previously-paused Activity for execution. - Not supported for Standalone Activities. If the Activity is not running and is past its retry timeout, it will be scheduled immediately. Otherwise, it will be scheduled after its retry @@ -540,7 +557,8 @@ commands: Use `--reset-heartbeat` to reset the Activity's heartbeats. - Either `--activity-id` (with `--workflow-id`) or `--query` must be specified. + Either `--activity-id` (with `--workflow-id` for a workflow Activity, or + alone for a standalone Activity) or `--query` must be specified. Specify the Activity and Workflow IDs: @@ -563,7 +581,7 @@ commands: short: a type: string description: | - The Activity ID to unpause. Mutually exclusive with `--query`. Requires `--workflow-id` to be specified. + The Activity ID to unpause. Mutually exclusive with `--query`. Set `--workflow-id` to target a workflow Activity, or omit it to target a standalone Activity (the latest run unless `--run-id` is set). - name: reset-attempts type: bool description: Reset the activity attempts. @@ -581,7 +599,7 @@ commands: - name: temporal activity reset summary: Reset an Activity description: | - Reset an activity. Not supported for Standalone Activities. + Reset an activity. This restarts the activity as if it were first being scheduled. That is, it will reset both the number of attempts and the activity timeout, as well as, optionally, the @@ -599,7 +617,8 @@ commands: it will be unpaused. If the activity is paused and `keep_paused` flag is provided - it will stay paused. - Either `--activity-id` (with `--workflow-id`) or `--query` must be specified. + Either `--activity-id` (with `--workflow-id` for a workflow Activity, or + alone for a standalone Activity) or `--query` must be specified. ### Resetting activities that heartbeat {#reset-heartbeats} @@ -631,7 +650,7 @@ commands: - name: activity-id short: a type: string - description: The Activity ID to reset. Mutually exclusive with `--query`. Requires `--workflow-id` to be specified. + description: The Activity ID to reset. Mutually exclusive with `--query`. Set `--workflow-id` to target a workflow Activity, or omit it to target a standalone Activity (the latest run unless `--run-id` is set). - name: keep-paused type: bool description: If the activity was paused, it will stay paused. From 95b03aa6c4708efe31220833be6fe011eec544cf Mon Sep 17 00:00:00 2001 From: Sean Kane Date: Thu, 18 Jun 2026 09:56:15 -0600 Subject: [PATCH 2/8] code gen and improved documentation of flags --- internal/temporalcli/commands.gen.go | 42 ++++++++------- internal/temporalcli/commands.yaml | 78 +++++++++++++++++++++------- 2 files changed, 83 insertions(+), 37 deletions(-) diff --git a/internal/temporalcli/commands.gen.go b/internal/temporalcli/commands.gen.go index 8a127c84d..764677e93 100644 --- a/internal/temporalcli/commands.gen.go +++ b/internal/temporalcli/commands.gen.go @@ -555,7 +555,11 @@ func NewTemporalActivityCommand(cctx *CommandContext, parent *TemporalCommand) * s.Parent = parent s.Command.Use = "activity" s.Command.Short = "Operate on Activity Executions" - s.Command.Long = "Perform operations on Activity Executions." + if hasHighlighting { + s.Command.Long = "Perform operations on Activity Executions.\n\n\x1b[1mtemporal activity start \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 5m\x1b[0m\n\nUse a subcommand to start, inspect, or operate on Activity Executions." + } else { + s.Command.Long = "Perform operations on Activity Executions.\n\n```\ntemporal activity start \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 5m\n```\n\nUse a subcommand to start, inspect, or operate on Activity Executions." + } s.Command.Args = cobra.NoArgs s.Command.AddCommand(&NewTemporalActivityCancelCommand(cctx, &s).Command) s.Command.AddCommand(&NewTemporalActivityCompleteCommand(cctx, &s).Command) @@ -623,9 +627,9 @@ func NewTemporalActivityCompleteCommand(cctx *CommandContext, parent *TemporalAc s.Command.Use = "complete [flags]" s.Command.Short = "Mark an activity as completed successfully with a result" if hasHighlighting { - s.Command.Long = "Complete an Activity, marking it as successfully finished. Specify the\nActivity ID and include a JSON result for the returned value:\n\n\x1b[1mtemporal activity complete \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --result '{\"YourResultKey\": \"YourResultVal\"}'\x1b[0m" + s.Command.Long = "Complete an Activity, marking it as successfully finished. Specify the\nActivity ID and include a JSON result for the returned value:\n\n\x1b[1mtemporal activity complete \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --result '{\"YourResultKey\": \"YourResultVal\"}'\x1b[0m\n\nOmit \x1b[1m--workflow-id\x1b[0m to target a Standalone Activity by Activity ID\nand optional Run ID." } else { - s.Command.Long = "Complete an Activity, marking it as successfully finished. Specify the\nActivity ID and include a JSON result for the returned value:\n\n```\ntemporal activity complete \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --result '{\"YourResultKey\": \"YourResultVal\"}'\n```" + s.Command.Long = "Complete an Activity, marking it as successfully finished. Specify the\nActivity ID and include a JSON result for the returned value:\n\n```\ntemporal activity complete \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --result '{\"YourResultKey\": \"YourResultVal\"}'\n```\n\nOmit `--workflow-id` to target a Standalone Activity by Activity ID\nand optional Run ID." } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "Activity ID. This may be the ID of an Activity invoked by a Workflow, or of a Standalone Activity. Required.") @@ -714,9 +718,9 @@ func NewTemporalActivityDescribeCommand(cctx *CommandContext, parent *TemporalAc s.Command.Use = "describe [flags]" s.Command.Short = "Show detailed info for a Standalone Activity (Experimental)" if hasHighlighting { - s.Command.Long = "Display information about a Standalone Activity.\n\n\x1b[1mtemporal activity describe \\\n --activity-id YourActivityId\x1b[0m" + s.Command.Long = "Display information about a Standalone Activity.\n\n\x1b[1mtemporal activity describe \\\n --activity-id YourActivityId\x1b[0m\n\nIf \x1b[1m--run-id\x1b[0m is omitted, the latest Activity run is described." } else { - s.Command.Long = "Display information about a Standalone Activity.\n\n```\ntemporal activity describe \\\n --activity-id YourActivityId\n```" + s.Command.Long = "Display information about a Standalone Activity.\n\n```\ntemporal activity describe \\\n --activity-id YourActivityId\n```\n\nIf `--run-id` is omitted, the latest Activity run is described." } s.Command.Args = cobra.NoArgs s.Command.Flags().BoolVar(&s.Raw, "raw", false, "Print properties without changing their format.") @@ -743,9 +747,9 @@ func NewTemporalActivityExecuteCommand(cctx *CommandContext, parent *TemporalAct s.Command.Use = "execute [flags]" s.Command.Short = "Start a new Standalone Activity and wait for its result (Experimental)" if hasHighlighting { - s.Command.Long = "Start a new Standalone Activity and block until it completes.\nThe result is output to stdout.\n\n\x1b[1mtemporal activity execute \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 30s \\\n --input '{\"some-key\": \"some-value\"}'\x1b[0m" + s.Command.Long = "Start a new Standalone Activity and block until it completes.\nThe result is output to stdout.\n\n\x1b[1mtemporal activity execute \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 30s \\\n --input '{\"YourInputKey\": \"YourInputValue\"}'\x1b[0m\n\nThe command exits after the Activity completes." } else { - s.Command.Long = "Start a new Standalone Activity and block until it completes.\nThe result is output to stdout.\n\n```\ntemporal activity execute \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 30s \\\n --input '{\"some-key\": \"some-value\"}'\n```" + s.Command.Long = "Start a new Standalone Activity and block until it completes.\nThe result is output to stdout.\n\n```\ntemporal activity execute \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 30s \\\n --input '{\"YourInputKey\": \"YourInputValue\"}'\n```\n\nThe command exits after the Activity completes." } s.Command.Args = cobra.NoArgs s.ActivityStartOptions.BuildFlags(s.Command.Flags()) @@ -775,9 +779,9 @@ func NewTemporalActivityFailCommand(cctx *CommandContext, parent *TemporalActivi s.Command.Use = "fail [flags]" s.Command.Short = "Mark an Activity as completed unsuccessfully with an error" if hasHighlighting { - s.Command.Long = "Fail an Activity, marking it as having encountered an error:\n\n\x1b[1mtemporal activity fail \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\x1b[0m" + s.Command.Long = "Fail an Activity, marking it as having encountered an error:\n\n\x1b[1mtemporal activity fail \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\x1b[0m\n\nOmit \x1b[1m--workflow-id\x1b[0m to target a Standalone Activity by Activity ID\nand optional Run ID." } else { - s.Command.Long = "Fail an Activity, marking it as having encountered an error:\n\n```\ntemporal activity fail \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n```" + s.Command.Long = "Fail an Activity, marking it as having encountered an error:\n\n```\ntemporal activity fail \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n```\n\nOmit `--workflow-id` to target a Standalone Activity by Activity ID\nand optional Run ID." } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "Activity ID. This may be the ID of an Activity invoked by a Workflow, or of a Standalone Activity. Required.") @@ -879,9 +883,9 @@ func NewTemporalActivityResetCommand(cctx *CommandContext, parent *TemporalActiv s.Command.Use = "reset [flags]" s.Command.Short = "Reset an Activity" if hasHighlighting { - s.Command.Long = "Reset an activity.\nThis restarts the activity as if it were first being\nscheduled. That is, it will reset both the number of attempts and the\nactivity timeout, as well as, optionally, the\nheartbeat details.\n\nIf the activity may be executing (i.e. it has not yet timed out), the\nreset will take effect the next time it fails, heartbeats, or times out.\nIf is waiting for a retry (i.e. has failed or timed out), the reset\nwill apply immediately.\n\nIf the activity is already paused, it will be unpaused by default.\nYou can specify \x1b[1mkeep_paused\x1b[0m to prevent this.\n\nIf the activity is paused and the \x1b[1mkeep_paused\x1b[0m flag is not provided,\nit will be unpaused. If the activity is paused and \x1b[1mkeep_paused\x1b[0m flag\nis provided - it will stay paused.\n\nEither \x1b[1m--activity-id\x1b[0m (with \x1b[1m--workflow-id\x1b[0m for a workflow Activity, or\nalone for a standalone Activity) or \x1b[1m--query\x1b[0m must be specified.\n\n### Resetting activities that heartbeat {#reset-heartbeats}\n\nActivities that heartbeat will receive a Canceled failure\nthe next time they heartbeat after a reset.\n\nIf, in your Activity, you need to do any cleanup when an Activity is\nreset, handle this error and then re-throw it when you've cleaned up.\n\nIf the \x1b[1mreset_heartbeats\x1b[0m flag is set, the heartbeat details will also be cleared.\n\nSpecify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --keep-paused\n --reset-heartbeats\x1b[0m\n\nActivities can be reset in bulk with a visibility query list filter:\n\n\x1b[1mtemporal activity reset \\\n --query 'WorkflowType=\"YourWorkflow\"'\x1b[0m" + s.Command.Long = "Reset an activity.\nThis restarts the activity as if it were first being\nscheduled. That is, it will reset both the number of attempts and the\nactivity timeout, as well as, optionally, the\nheartbeat details.\n\nIf the activity may be executing (i.e. it has not yet timed out), the\nreset will take effect the next time it fails, heartbeats, or times out.\nIf is waiting for a retry (i.e. has failed or timed out), the reset\nwill apply immediately.\n\nIf the activity is already paused, it will be unpaused by default.\nYou can specify \x1b[1m--keep-paused\x1b[0m to prevent this.\n\nIf the activity is paused and the \x1b[1m--keep-paused\x1b[0m flag is not provided,\nit will be unpaused. If the activity is paused and the \x1b[1m--keep-paused\x1b[0m\nflag is provided, it will stay paused.\n\nEither \x1b[1m--activity-id\x1b[0m (with \x1b[1m--workflow-id\x1b[0m for a workflow Activity, or\nalone for a standalone Activity) or \x1b[1m--query\x1b[0m must be specified.\n\n### Resetting activities that heartbeat {#reset-heartbeats}\n\nActivities that heartbeat will receive a\nCanceled failure the next time\nthey heartbeat after a reset.\n\nIf, in your Activity, you need to do any cleanup when an Activity is\nreset, handle this error and then re-throw it when you've cleaned up.\n\nIf the \x1b[1m--reset-heartbeats\x1b[0m flag is set, the heartbeat details will also be cleared.\n\nSpecify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --keep-paused \\\n --reset-heartbeats\x1b[0m\n\nActivities can be reset in bulk with a visibility query list filter:\n\n\x1b[1mtemporal activity reset \\\n --query 'WorkflowType=\"YourWorkflow\"'\x1b[0m\n\nOmit \x1b[1m--workflow-id\x1b[0m to target a Standalone Activity by Activity ID\nand optional Run ID." } else { - s.Command.Long = "Reset an activity.\nThis restarts the activity as if it were first being\nscheduled. That is, it will reset both the number of attempts and the\nactivity timeout, as well as, optionally, the\nheartbeat details.\n\nIf the activity may be executing (i.e. it has not yet timed out), the\nreset will take effect the next time it fails, heartbeats, or times out.\nIf is waiting for a retry (i.e. has failed or timed out), the reset\nwill apply immediately.\n\nIf the activity is already paused, it will be unpaused by default.\nYou can specify `keep_paused` to prevent this.\n\nIf the activity is paused and the `keep_paused` flag is not provided,\nit will be unpaused. If the activity is paused and `keep_paused` flag\nis provided - it will stay paused.\n\nEither `--activity-id` (with `--workflow-id` for a workflow Activity, or\nalone for a standalone Activity) or `--query` must be specified.\n\n### Resetting activities that heartbeat {#reset-heartbeats}\n\nActivities that heartbeat will receive a Canceled failure\nthe next time they heartbeat after a reset.\n\nIf, in your Activity, you need to do any cleanup when an Activity is\nreset, handle this error and then re-throw it when you've cleaned up.\n\nIf the `reset_heartbeats` flag is set, the heartbeat details will also be cleared.\n\nSpecify the Activity and Workflow IDs:\n\n```\ntemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --keep-paused\n --reset-heartbeats\n```\n\nActivities can be reset in bulk with a visibility query list filter:\n\n```\ntemporal activity reset \\\n --query 'WorkflowType=\"YourWorkflow\"'\n```" + s.Command.Long = "Reset an activity.\nThis restarts the activity as if it were first being\nscheduled. That is, it will reset both the number of attempts and the\nactivity timeout, as well as, optionally, the\nheartbeat details.\n\nIf the activity may be executing (i.e. it has not yet timed out), the\nreset will take effect the next time it fails, heartbeats, or times out.\nIf is waiting for a retry (i.e. has failed or timed out), the reset\nwill apply immediately.\n\nIf the activity is already paused, it will be unpaused by default.\nYou can specify `--keep-paused` to prevent this.\n\nIf the activity is paused and the `--keep-paused` flag is not provided,\nit will be unpaused. If the activity is paused and the `--keep-paused`\nflag is provided, it will stay paused.\n\nEither `--activity-id` (with `--workflow-id` for a workflow Activity, or\nalone for a standalone Activity) or `--query` must be specified.\n\n### Resetting activities that heartbeat {#reset-heartbeats}\n\nActivities that heartbeat will receive a\nCanceled failure the next time\nthey heartbeat after a reset.\n\nIf, in your Activity, you need to do any cleanup when an Activity is\nreset, handle this error and then re-throw it when you've cleaned up.\n\nIf the `--reset-heartbeats` flag is set, the heartbeat details will also be cleared.\n\nSpecify the Activity and Workflow IDs:\n\n```\ntemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --keep-paused \\\n --reset-heartbeats\n```\n\nActivities can be reset in bulk with a visibility query list filter:\n\n```\ntemporal activity reset \\\n --query 'WorkflowType=\"YourWorkflow\"'\n```\n\nOmit `--workflow-id` to target a Standalone Activity by Activity ID\nand optional Run ID." } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "The Activity ID to reset. Mutually exclusive with `--query`. Set `--workflow-id` to target a workflow Activity, or omit it to target a standalone Activity (the latest run unless `--run-id` is set).") @@ -913,9 +917,9 @@ func NewTemporalActivityResultCommand(cctx *CommandContext, parent *TemporalActi s.Command.Use = "result [flags]" s.Command.Short = "Wait for and output the result of a Standalone Activity (Experimental)" if hasHighlighting { - s.Command.Long = "Wait for a Standalone Activity to complete and output the\nresult.\n\n\x1b[1mtemporal activity result \\\n --activity-id YourActivityId\x1b[0m" + s.Command.Long = "Wait for a Standalone Activity to complete and output the\nresult.\n\n\x1b[1mtemporal activity result \\\n --activity-id YourActivityId\x1b[0m\n\nIf \x1b[1m--run-id\x1b[0m is omitted, the latest Activity run is used." } else { - s.Command.Long = "Wait for a Standalone Activity to complete and output the\nresult.\n\n```\ntemporal activity result \\\n --activity-id YourActivityId\n```" + s.Command.Long = "Wait for a Standalone Activity to complete and output the\nresult.\n\n```\ntemporal activity result \\\n --activity-id YourActivityId\n```\n\nIf `--run-id` is omitted, the latest Activity run is used." } s.Command.Args = cobra.NoArgs s.ActivityReferenceOptions.BuildFlags(s.Command.Flags()) @@ -941,9 +945,9 @@ func NewTemporalActivityStartCommand(cctx *CommandContext, parent *TemporalActiv s.Command.Use = "start [flags]" s.Command.Short = "Start a new Standalone Activity (Experimental)" if hasHighlighting { - s.Command.Long = "Start a new Standalone Activity. Outputs the Activity ID and\nRun ID.\n\n\x1b[1mtemporal activity start \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 5m \\\n --input '{\"some-key\": \"some-value\"}'\x1b[0m" + s.Command.Long = "Start a new Standalone Activity. Outputs the Activity ID and\nRun ID.\n\n\x1b[1mtemporal activity start \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 5m \\\n --input '{\"YourInputKey\": \"YourInputValue\"}'\x1b[0m\n\nThe command returns the Activity ID and Run ID." } else { - s.Command.Long = "Start a new Standalone Activity. Outputs the Activity ID and\nRun ID.\n\n```\ntemporal activity start \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 5m \\\n --input '{\"some-key\": \"some-value\"}'\n```" + s.Command.Long = "Start a new Standalone Activity. Outputs the Activity ID and\nRun ID.\n\n```\ntemporal activity start \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 5m \\\n --input '{\"YourInputKey\": \"YourInputValue\"}'\n```\n\nThe command returns the Activity ID and Run ID." } s.Command.Args = cobra.NoArgs s.ActivityStartOptions.BuildFlags(s.Command.Flags()) @@ -1004,9 +1008,9 @@ func NewTemporalActivityUnpauseCommand(cctx *CommandContext, parent *TemporalAct s.Command.Use = "unpause [flags]" s.Command.Short = "Unpause an Activity" if hasHighlighting { - s.Command.Long = "Re-schedule a previously-paused Activity for execution.\n\nIf the Activity is not running and is past its retry timeout, it will be\nscheduled immediately. Otherwise, it will be scheduled after its retry\ntimeout expires.\n\nUse \x1b[1m--reset-attempts\x1b[0m to reset the number of previous run attempts to\nzero. For example, if an Activity is near the maximum number of attempts\nN specified in its retry policy, \x1b[1m--reset-attempts\x1b[0m will allow the\nActivity to be retried another N times after unpausing.\n\nUse \x1b[1m--reset-heartbeat\x1b[0m to reset the Activity's heartbeats.\n\nEither \x1b[1m--activity-id\x1b[0m (with \x1b[1m--workflow-id\x1b[0m for a workflow Activity, or\nalone for a standalone Activity) or \x1b[1m--query\x1b[0m must be specified.\n\nSpecify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity unpause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --reset-attempts\n --reset-heartbeats\x1b[0m\n\nActivities can be unpaused in bulk via a visibility Query list filter:\n\n\x1b[1mtemporal activity unpause \\\n --query 'TemporalPauseInfo IS NOT NULL'\x1b[0m" + s.Command.Long = "Re-schedule a previously-paused Activity for execution.\n\nIf the Activity is not running and is past its retry timeout, it will be\nscheduled immediately. Otherwise, it will be scheduled after its retry\ntimeout expires.\n\nUse \x1b[1m--reset-attempts\x1b[0m to reset the number of previous run attempts to\nzero. For example, if an Activity is near the maximum number of attempts\nN specified in its retry policy, \x1b[1m--reset-attempts\x1b[0m will allow the\nActivity to be retried another N times after unpausing.\n\nUse \x1b[1m--reset-heartbeats\x1b[0m to reset the Activity's heartbeats.\n\nEither \x1b[1m--activity-id\x1b[0m (with \x1b[1m--workflow-id\x1b[0m for a workflow Activity, or\nalone for a standalone Activity) or \x1b[1m--query\x1b[0m must be specified.\n\nSpecify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity unpause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --reset-attempts \\\n --reset-heartbeats\x1b[0m\n\nActivities can be unpaused in bulk via a visibility Query list filter:\n\n\x1b[1mtemporal activity unpause \\\n --query 'TemporalPauseInfo IS NOT NULL'\x1b[0m\n\nOmit \x1b[1m--workflow-id\x1b[0m to target a Standalone Activity by Activity ID\nand optional Run ID." } else { - s.Command.Long = "Re-schedule a previously-paused Activity for execution.\n\nIf the Activity is not running and is past its retry timeout, it will be\nscheduled immediately. Otherwise, it will be scheduled after its retry\ntimeout expires.\n\nUse `--reset-attempts` to reset the number of previous run attempts to\nzero. For example, if an Activity is near the maximum number of attempts\nN specified in its retry policy, `--reset-attempts` will allow the\nActivity to be retried another N times after unpausing.\n\nUse `--reset-heartbeat` to reset the Activity's heartbeats.\n\nEither `--activity-id` (with `--workflow-id` for a workflow Activity, or\nalone for a standalone Activity) or `--query` must be specified.\n\nSpecify the Activity and Workflow IDs:\n\n```\ntemporal activity unpause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n --reset-attempts\n --reset-heartbeats\n```\n\nActivities can be unpaused in bulk via a visibility Query list filter:\n\n```\ntemporal activity unpause \\\n --query 'TemporalPauseInfo IS NOT NULL'\n```" + s.Command.Long = "Re-schedule a previously-paused Activity for execution.\n\nIf the Activity is not running and is past its retry timeout, it will be\nscheduled immediately. Otherwise, it will be scheduled after its retry\ntimeout expires.\n\nUse `--reset-attempts` to reset the number of previous run attempts to\nzero. For example, if an Activity is near the maximum number of attempts\nN specified in its retry policy, `--reset-attempts` will allow the\nActivity to be retried another N times after unpausing.\n\nUse `--reset-heartbeats` to reset the Activity's heartbeats.\n\nEither `--activity-id` (with `--workflow-id` for a workflow Activity, or\nalone for a standalone Activity) or `--query` must be specified.\n\nSpecify the Activity and Workflow IDs:\n\n```\ntemporal activity unpause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --reset-attempts \\\n --reset-heartbeats\n```\n\nActivities can be unpaused in bulk via a visibility Query list filter:\n\n```\ntemporal activity unpause \\\n --query 'TemporalPauseInfo IS NOT NULL'\n```\n\nOmit `--workflow-id` to target a Standalone Activity by Activity ID\nand optional Run ID." } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "The Activity ID to unpause. Mutually exclusive with `--query`. Set `--workflow-id` to target a workflow Activity, or omit it to target a standalone Activity (the latest run unless `--run-id` is set).") @@ -1047,9 +1051,9 @@ func NewTemporalActivityUpdateOptionsCommand(cctx *CommandContext, parent *Tempo s.Command.Use = "update-options [flags]" s.Command.Short = "Change the values of options affecting a running Activity" if hasHighlighting { - s.Command.Long = "Update the options of a running Activity that were passed into it from\na Workflow. Updates are incremental, only changing the specified options.\n\nFor example:\n\n\x1b[1mtemporal activity update-options \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --task-queue NewTaskQueueName \\\n --schedule-to-close-timeout DURATION \\\n --schedule-to-start-timeout DURATION \\\n --start-to-close-timeout DURATION \\\n --heartbeat-timeout DURATION \\\n --retry-initial-interval DURATION \\\n --retry-maximum-interval DURATION \\\n --retry-backoff-coefficient NewBackoffCoefficient \\\n --retry-maximum-attempts NewMaximumAttempts\x1b[0m\n\nYou may follow this command with \x1b[1mtemporal activity reset\x1b[0m, and the new values will apply after the reset.\n\nEither \x1b[1m--activity-id\x1b[0m or \x1b[1m--query\x1b[0m must be specified.\n\nActivity options can be updated in bulk with a visibility query list filter:\n\n\x1b[1mtemporal activity update-options \\\n --query 'WorkflowType=\"YourWorkflow\"' \\\n --task-queue NewTaskQueueName\x1b[0m" + s.Command.Long = "Update the options of a running Activity that were passed into it from\na Workflow. Updates are incremental, only changing the specified options.\n\nFor example:\n\n\x1b[1mtemporal activity update-options \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --task-queue NewTaskQueueName \\\n --schedule-to-close-timeout DURATION \\\n --schedule-to-start-timeout DURATION \\\n --start-to-close-timeout DURATION \\\n --heartbeat-timeout DURATION \\\n --retry-initial-interval DURATION \\\n --retry-maximum-interval DURATION \\\n --retry-backoff-coefficient NewBackoffCoefficient \\\n --retry-maximum-attempts NewMaximumAttempts\x1b[0m\n\nYou may follow this command with \x1b[1mtemporal activity reset\x1b[0m, and the new\nvalues will apply after the reset.\n\nEither \x1b[1m--activity-id\x1b[0m or \x1b[1m--query\x1b[0m must be specified.\n\nActivity options can be updated in bulk with a visibility query list filter:\n\n\x1b[1mtemporal activity update-options \\\n --query 'WorkflowType=\"YourWorkflow\"' \\\n --task-queue NewTaskQueueName\x1b[0m\n\nOmit \x1b[1m--workflow-id\x1b[0m to target a Standalone Activity by Activity ID\nand optional Run ID." } else { - s.Command.Long = "Update the options of a running Activity that were passed into it from\na Workflow. Updates are incremental, only changing the specified options.\n\nFor example:\n\n```\ntemporal activity update-options \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --task-queue NewTaskQueueName \\\n --schedule-to-close-timeout DURATION \\\n --schedule-to-start-timeout DURATION \\\n --start-to-close-timeout DURATION \\\n --heartbeat-timeout DURATION \\\n --retry-initial-interval DURATION \\\n --retry-maximum-interval DURATION \\\n --retry-backoff-coefficient NewBackoffCoefficient \\\n --retry-maximum-attempts NewMaximumAttempts\n```\n\nYou may follow this command with `temporal activity reset`, and the new values will apply after the reset.\n\nEither `--activity-id` or `--query` must be specified.\n\nActivity options can be updated in bulk with a visibility query list filter:\n\n```\ntemporal activity update-options \\\n --query 'WorkflowType=\"YourWorkflow\"' \\\n --task-queue NewTaskQueueName\n```" + s.Command.Long = "Update the options of a running Activity that were passed into it from\na Workflow. Updates are incremental, only changing the specified options.\n\nFor example:\n\n```\ntemporal activity update-options \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --task-queue NewTaskQueueName \\\n --schedule-to-close-timeout DURATION \\\n --schedule-to-start-timeout DURATION \\\n --start-to-close-timeout DURATION \\\n --heartbeat-timeout DURATION \\\n --retry-initial-interval DURATION \\\n --retry-maximum-interval DURATION \\\n --retry-backoff-coefficient NewBackoffCoefficient \\\n --retry-maximum-attempts NewMaximumAttempts\n```\n\nYou may follow this command with `temporal activity reset`, and the new\nvalues will apply after the reset.\n\nEither `--activity-id` or `--query` must be specified.\n\nActivity options can be updated in bulk with a visibility query list filter:\n\n```\ntemporal activity update-options \\\n --query 'WorkflowType=\"YourWorkflow\"' \\\n --task-queue NewTaskQueueName\n```\n\nOmit `--workflow-id` to target a Standalone Activity by Activity ID\nand optional Run ID." } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "The Activity ID to update options. Mutually exclusive with `--query`. Set `--workflow-id` to target a workflow Activity, or omit it to target a standalone Activity (the latest run unless `--run-id` is set).") diff --git a/internal/temporalcli/commands.yaml b/internal/temporalcli/commands.yaml index 43017df91..e81dad9f5 100644 --- a/internal/temporalcli/commands.yaml +++ b/internal/temporalcli/commands.yaml @@ -149,6 +149,16 @@ commands: summary: Operate on Activity Executions description: | Perform operations on Activity Executions. + + ``` + temporal activity start \ + --activity-id YourActivityId \ + --type YourActivity \ + --task-queue YourTaskQueue \ + --start-to-close-timeout 5m + ``` + + Use a subcommand to start, inspect, or operate on Activity Executions. option-sets: - client docs: @@ -233,6 +243,9 @@ commands: --workflow-id YourWorkflowId \ --result '{"YourResultKey": "YourResultVal"}' ``` + + Omit `--workflow-id` to target a Standalone Activity by Activity ID + and optional Run ID. options: - name: activity-id short: a @@ -288,6 +301,8 @@ commands: temporal activity describe \ --activity-id YourActivityId ``` + + If `--run-id` is omitted, the latest Activity run is described. option-sets: - activity-reference options: @@ -307,8 +322,10 @@ commands: --type YourActivity \ --task-queue YourTaskQueue \ --start-to-close-timeout 30s \ - --input '{"some-key": "some-value"}' + --input '{"YourInputKey": "YourInputValue"}' ``` + + The command exits after the Activity completes. option-sets: - activity-start - payload-input @@ -323,6 +340,9 @@ commands: --activity-id YourActivityId \ --workflow-id YourWorkflowId ``` + + Omit `--workflow-id` to target a Standalone Activity by Activity ID + and optional Run ID. options: - name: activity-id short: a @@ -405,7 +425,8 @@ commands: --retry-maximum-attempts NewMaximumAttempts ``` - You may follow this command with `temporal activity reset`, and the new values will apply after the reset. + You may follow this command with `temporal activity reset`, and the new + values will apply after the reset. Either `--activity-id` or `--query` must be specified. @@ -416,12 +437,17 @@ commands: --query 'WorkflowType="YourWorkflow"' \ --task-queue NewTaskQueueName ``` + + Omit `--workflow-id` to target a Standalone Activity by Activity ID + and optional Run ID. options: - name: activity-id short: a type: string description: | - The Activity ID to update options. Mutually exclusive with `--query`. Set `--workflow-id` to target a workflow Activity, or omit it to target a standalone Activity (the latest run unless `--run-id` is set). + The Activity ID to update options. Mutually exclusive with `--query`. + Set `--workflow-id` to target a workflow Activity, or omit it to target + a standalone Activity (the latest run unless `--run-id` is set). - name: task-queue type: string description: Name of the task queue for the Activity. @@ -555,7 +581,7 @@ commands: N specified in its retry policy, `--reset-attempts` will allow the Activity to be retried another N times after unpausing. - Use `--reset-heartbeat` to reset the Activity's heartbeats. + Use `--reset-heartbeats` to reset the Activity's heartbeats. Either `--activity-id` (with `--workflow-id` for a workflow Activity, or alone for a standalone Activity) or `--query` must be specified. @@ -565,8 +591,8 @@ commands: ``` temporal activity unpause \ --activity-id YourActivityId \ - --workflow-id YourWorkflowId - --reset-attempts + --workflow-id YourWorkflowId \ + --reset-attempts \ --reset-heartbeats ``` @@ -576,12 +602,17 @@ commands: temporal activity unpause \ --query 'TemporalPauseInfo IS NOT NULL' ``` + + Omit `--workflow-id` to target a Standalone Activity by Activity ID + and optional Run ID. options: - name: activity-id short: a type: string description: | - The Activity ID to unpause. Mutually exclusive with `--query`. Set `--workflow-id` to target a workflow Activity, or omit it to target a standalone Activity (the latest run unless `--run-id` is set). + The Activity ID to unpause. Mutually exclusive with `--query`. + Set `--workflow-id` to target a workflow Activity, or omit it to target + a standalone Activity (the latest run unless `--run-id` is set). - name: reset-attempts type: bool description: Reset the activity attempts. @@ -611,32 +642,33 @@ commands: will apply immediately. If the activity is already paused, it will be unpaused by default. - You can specify `keep_paused` to prevent this. + You can specify `--keep-paused` to prevent this. - If the activity is paused and the `keep_paused` flag is not provided, - it will be unpaused. If the activity is paused and `keep_paused` flag - is provided - it will stay paused. + If the activity is paused and the `--keep-paused` flag is not provided, + it will be unpaused. If the activity is paused and the `--keep-paused` + flag is provided, it will stay paused. Either `--activity-id` (with `--workflow-id` for a workflow Activity, or alone for a standalone Activity) or `--query` must be specified. ### Resetting activities that heartbeat {#reset-heartbeats} - Activities that heartbeat will receive a [Canceled failure](/references/failures#cancelled-failure) - the next time they heartbeat after a reset. + Activities that heartbeat will receive a + [Canceled failure](/references/failures#cancelled-failure) the next time + they heartbeat after a reset. If, in your Activity, you need to do any cleanup when an Activity is reset, handle this error and then re-throw it when you've cleaned up. - If the `reset_heartbeats` flag is set, the heartbeat details will also be cleared. + If the `--reset-heartbeats` flag is set, the heartbeat details will also be cleared. Specify the Activity and Workflow IDs: ``` temporal activity reset \ --activity-id YourActivityId \ - --workflow-id YourWorkflowId - --keep-paused + --workflow-id YourWorkflowId \ + --keep-paused \ --reset-heartbeats ``` @@ -646,11 +678,17 @@ commands: temporal activity reset \ --query 'WorkflowType="YourWorkflow"' ``` + + Omit `--workflow-id` to target a Standalone Activity by Activity ID + and optional Run ID. options: - name: activity-id short: a type: string - description: The Activity ID to reset. Mutually exclusive with `--query`. Set `--workflow-id` to target a workflow Activity, or omit it to target a standalone Activity (the latest run unless `--run-id` is set). + description: | + The Activity ID to reset. Mutually exclusive with `--query`. + Set `--workflow-id` to target a workflow Activity, or omit it to target + a standalone Activity (the latest run unless `--run-id` is set). - name: keep-paused type: bool description: If the activity was paused, it will stay paused. @@ -682,6 +720,8 @@ commands: temporal activity result \ --activity-id YourActivityId ``` + + If `--run-id` is omitted, the latest Activity run is used. option-sets: - activity-reference @@ -697,8 +737,10 @@ commands: --type YourActivity \ --task-queue YourTaskQueue \ --start-to-close-timeout 5m \ - --input '{"some-key": "some-value"}' + --input '{"YourInputKey": "YourInputValue"}' ``` + + The command returns the Activity ID and Run ID. option-sets: - activity-start - payload-input From ed31767941720791b1ce81d50314a7242fbe5207 Mon Sep 17 00:00:00 2001 From: Sean Kane Date: Thu, 18 Jun 2026 09:59:37 -0600 Subject: [PATCH 3/8] refining --- internal/temporalcli/commands.gen.go | 12 ++++++------ internal/temporalcli/commands.yaml | 6 ++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/internal/temporalcli/commands.gen.go b/internal/temporalcli/commands.gen.go index 764677e93..b7720c295 100644 --- a/internal/temporalcli/commands.gen.go +++ b/internal/temporalcli/commands.gen.go @@ -556,9 +556,9 @@ func NewTemporalActivityCommand(cctx *CommandContext, parent *TemporalCommand) * s.Command.Use = "activity" s.Command.Short = "Operate on Activity Executions" if hasHighlighting { - s.Command.Long = "Perform operations on Activity Executions.\n\n\x1b[1mtemporal activity start \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 5m\x1b[0m\n\nUse a subcommand to start, inspect, or operate on Activity Executions." + s.Command.Long = "Perform operations on Activity Executions.\n\n\x1b[1mtemporal activity start \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 5m\x1b[0m" } else { - s.Command.Long = "Perform operations on Activity Executions.\n\n```\ntemporal activity start \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 5m\n```\n\nUse a subcommand to start, inspect, or operate on Activity Executions." + s.Command.Long = "Perform operations on Activity Executions.\n\n```\ntemporal activity start \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 5m\n```" } s.Command.Args = cobra.NoArgs s.Command.AddCommand(&NewTemporalActivityCancelCommand(cctx, &s).Command) @@ -747,9 +747,9 @@ func NewTemporalActivityExecuteCommand(cctx *CommandContext, parent *TemporalAct s.Command.Use = "execute [flags]" s.Command.Short = "Start a new Standalone Activity and wait for its result (Experimental)" if hasHighlighting { - s.Command.Long = "Start a new Standalone Activity and block until it completes.\nThe result is output to stdout.\n\n\x1b[1mtemporal activity execute \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 30s \\\n --input '{\"YourInputKey\": \"YourInputValue\"}'\x1b[0m\n\nThe command exits after the Activity completes." + s.Command.Long = "Start a new Standalone Activity and block until it completes.\nThe result is output to stdout.\n\n\x1b[1mtemporal activity execute \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 30s \\\n --input '{\"some-key\": \"some-value\"}'\x1b[0m\n\nThe command exits after the Activity completes." } else { - s.Command.Long = "Start a new Standalone Activity and block until it completes.\nThe result is output to stdout.\n\n```\ntemporal activity execute \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 30s \\\n --input '{\"YourInputKey\": \"YourInputValue\"}'\n```\n\nThe command exits after the Activity completes." + s.Command.Long = "Start a new Standalone Activity and block until it completes.\nThe result is output to stdout.\n\n```\ntemporal activity execute \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 30s \\\n --input '{\"some-key\": \"some-value\"}'\n```\n\nThe command exits after the Activity completes." } s.Command.Args = cobra.NoArgs s.ActivityStartOptions.BuildFlags(s.Command.Flags()) @@ -945,9 +945,9 @@ func NewTemporalActivityStartCommand(cctx *CommandContext, parent *TemporalActiv s.Command.Use = "start [flags]" s.Command.Short = "Start a new Standalone Activity (Experimental)" if hasHighlighting { - s.Command.Long = "Start a new Standalone Activity. Outputs the Activity ID and\nRun ID.\n\n\x1b[1mtemporal activity start \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 5m \\\n --input '{\"YourInputKey\": \"YourInputValue\"}'\x1b[0m\n\nThe command returns the Activity ID and Run ID." + s.Command.Long = "Start a new Standalone Activity. Outputs the Activity ID and\nRun ID.\n\n\x1b[1mtemporal activity start \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 5m \\\n --input '{\"some-key\": \"some-value\"}'\x1b[0m\n\nThe command returns the Activity ID and Run ID." } else { - s.Command.Long = "Start a new Standalone Activity. Outputs the Activity ID and\nRun ID.\n\n```\ntemporal activity start \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 5m \\\n --input '{\"YourInputKey\": \"YourInputValue\"}'\n```\n\nThe command returns the Activity ID and Run ID." + s.Command.Long = "Start a new Standalone Activity. Outputs the Activity ID and\nRun ID.\n\n```\ntemporal activity start \\\n --activity-id YourActivityId \\\n --type YourActivity \\\n --task-queue YourTaskQueue \\\n --start-to-close-timeout 5m \\\n --input '{\"some-key\": \"some-value\"}'\n```\n\nThe command returns the Activity ID and Run ID." } s.Command.Args = cobra.NoArgs s.ActivityStartOptions.BuildFlags(s.Command.Flags()) diff --git a/internal/temporalcli/commands.yaml b/internal/temporalcli/commands.yaml index e81dad9f5..3b6819f60 100644 --- a/internal/temporalcli/commands.yaml +++ b/internal/temporalcli/commands.yaml @@ -157,8 +157,6 @@ commands: --task-queue YourTaskQueue \ --start-to-close-timeout 5m ``` - - Use a subcommand to start, inspect, or operate on Activity Executions. option-sets: - client docs: @@ -322,7 +320,7 @@ commands: --type YourActivity \ --task-queue YourTaskQueue \ --start-to-close-timeout 30s \ - --input '{"YourInputKey": "YourInputValue"}' + --input '{"some-key": "some-value"}' ``` The command exits after the Activity completes. @@ -737,7 +735,7 @@ commands: --type YourActivity \ --task-queue YourTaskQueue \ --start-to-close-timeout 5m \ - --input '{"YourInputKey": "YourInputValue"}' + --input '{"some-key": "some-value"}' ``` The command returns the Activity ID and Run ID. From f0142e368bd181382fbfe4250da59f5ac405c923 Mon Sep 17 00:00:00 2001 From: Sean Kane Date: Mon, 20 Jul 2026 16:35:32 -0600 Subject: [PATCH 4/8] remove the reset-heartbeats flag --- internal/temporalcli/commands.activity.go | 5 +---- internal/temporalcli/commands.gen.go | 10 ++++------ internal/temporalcli/commands.yaml | 12 ++++-------- 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/internal/temporalcli/commands.activity.go b/internal/temporalcli/commands.activity.go index b0a26ab3b..f6f9c5efa 100644 --- a/internal/temporalcli/commands.activity.go +++ b/internal/temporalcli/commands.activity.go @@ -1179,7 +1179,6 @@ func (c *TemporalActivityResetCommand) run(cctx *CommandContext, args []string) RunId: c.RunId, Identity: c.Parent.Identity, KeepPaused: c.KeepPaused, - ResetHeartbeat: c.ResetHeartbeats, } resp, err := cl.WorkflowService().ResetActivityExecution(cctx, request) @@ -1189,12 +1188,10 @@ func (c *TemporalActivityResetCommand) run(cctx *CommandContext, args []string) resetResponse := struct { KeepPaused bool `json:"keepPaused"` - ResetHeartbeats bool `json:"resetHeartbeats"` ServerResponse bool `json:"-"` }{ ServerResponse: resp != nil, KeepPaused: c.KeepPaused, - ResetHeartbeats: c.ResetHeartbeats, } _ = cctx.Printer.PrintStructured(resetResponse, printer.StructuredOptions{}) @@ -1202,7 +1199,7 @@ func (c *TemporalActivityResetCommand) run(cctx *CommandContext, args []string) resetActivitiesOperation := &batch.BatchOperationResetActivities{ Identity: c.Parent.Identity, ResetAttempts: c.ResetAttempts, - ResetHeartbeat: c.ResetHeartbeats, + ResetHeartbeat: true, KeepPaused: c.KeepPaused, Jitter: durationpb.New(c.Jitter.Duration()), RestoreOriginalOptions: c.RestoreOriginalOptions, diff --git a/internal/temporalcli/commands.gen.go b/internal/temporalcli/commands.gen.go index b7720c295..a3d1373c0 100644 --- a/internal/temporalcli/commands.gen.go +++ b/internal/temporalcli/commands.gen.go @@ -846,9 +846,9 @@ func NewTemporalActivityPauseCommand(cctx *CommandContext, parent *TemporalActiv s.Command.Use = "pause [flags]" s.Command.Short = "Pause an Activity" if hasHighlighting { - s.Command.Long = "Pause an Activity.\n\nIf the Activity is not currently running (e.g. because it previously\nfailed), it will not be run again until it is unpaused.\n\nHowever, if the Activity is currently running, it will run until the next\ntime it fails, completes, or times out, at which point the pause will kick in.\n\nIf the Activity is on its last retry attempt and fails, the failure will\nbe returned to the caller, just as if the Activity had not been paused.\n\nTo target a workflow Activity, specify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity pause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\x1b[0m\n\nTo target a standalone Activity, specify the Activity and Run IDs:\n\n\x1b[1mtemporal activity pause \\\n --activity-id YourActivityId \\\n --run-id YourRunId\x1b[0m\n\nTo later unpause the activity, see unpause. You may also want to\nreset the activity to unpause it while also starting it from the beginning." + s.Command.Long = "Pause an Activity.\n\nIf the Activity is not currently running (e.g. because it previously\nfailed), it will not be run again until it is unpaused.\n\nHowever, if the Activity is currently running, it will run until the next\ntime it fails, completes, or times out, at which point the pause will kick in.\n\nPause does not stop or extend the Activity's Schedule-To-Close Timeout.\nA paused Activity can still time out. Use \x1b[1mtemporal activity update-options\x1b[0m\nto extend timeout settings before a long pause.\n\nIf the Activity is on its last retry attempt and fails, the failure will\nbe returned to the caller, just as if the Activity had not been paused.\n\nTo target a workflow Activity, specify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity pause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\x1b[0m\n\nTo target a standalone Activity, specify the Activity and Run IDs:\n\n\x1b[1mtemporal activity pause \\\n --activity-id YourActivityId \\\n --run-id YourRunId\x1b[0m\n\nTo later unpause the activity, see unpause. You may also want to\nreset the activity to unpause it while also starting it from the beginning." } else { - s.Command.Long = "Pause an Activity.\n\nIf the Activity is not currently running (e.g. because it previously\nfailed), it will not be run again until it is unpaused.\n\nHowever, if the Activity is currently running, it will run until the next\ntime it fails, completes, or times out, at which point the pause will kick in.\n\nIf the Activity is on its last retry attempt and fails, the failure will\nbe returned to the caller, just as if the Activity had not been paused.\n\nTo target a workflow Activity, specify the Activity and Workflow IDs:\n\n```\ntemporal activity pause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n```\n\nTo target a standalone Activity, specify the Activity and Run IDs:\n\n```\ntemporal activity pause \\\n --activity-id YourActivityId \\\n --run-id YourRunId\n```\n\nTo later unpause the activity, see unpause. You may also want to\nreset the activity to unpause it while also starting it from the beginning." + s.Command.Long = "Pause an Activity.\n\nIf the Activity is not currently running (e.g. because it previously\nfailed), it will not be run again until it is unpaused.\n\nHowever, if the Activity is currently running, it will run until the next\ntime it fails, completes, or times out, at which point the pause will kick in.\n\nPause does not stop or extend the Activity's Schedule-To-Close Timeout.\nA paused Activity can still time out. Use `temporal activity update-options`\nto extend timeout settings before a long pause.\n\nIf the Activity is on its last retry attempt and fails, the failure will\nbe returned to the caller, just as if the Activity had not been paused.\n\nTo target a workflow Activity, specify the Activity and Workflow IDs:\n\n```\ntemporal activity pause \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId\n```\n\nTo target a standalone Activity, specify the Activity and Run IDs:\n\n```\ntemporal activity pause \\\n --activity-id YourActivityId \\\n --run-id YourRunId\n```\n\nTo later unpause the activity, see unpause. You may also want to\nreset the activity to unpause it while also starting it from the beginning." } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "The Activity ID to pause. Required.") @@ -871,7 +871,6 @@ type TemporalActivityResetCommand struct { ActivityId string KeepPaused bool ResetAttempts bool - ResetHeartbeats bool Jitter cliext.FlagDuration RestoreOriginalOptions bool } @@ -883,15 +882,14 @@ func NewTemporalActivityResetCommand(cctx *CommandContext, parent *TemporalActiv s.Command.Use = "reset [flags]" s.Command.Short = "Reset an Activity" if hasHighlighting { - s.Command.Long = "Reset an activity.\nThis restarts the activity as if it were first being\nscheduled. That is, it will reset both the number of attempts and the\nactivity timeout, as well as, optionally, the\nheartbeat details.\n\nIf the activity may be executing (i.e. it has not yet timed out), the\nreset will take effect the next time it fails, heartbeats, or times out.\nIf is waiting for a retry (i.e. has failed or timed out), the reset\nwill apply immediately.\n\nIf the activity is already paused, it will be unpaused by default.\nYou can specify \x1b[1m--keep-paused\x1b[0m to prevent this.\n\nIf the activity is paused and the \x1b[1m--keep-paused\x1b[0m flag is not provided,\nit will be unpaused. If the activity is paused and the \x1b[1m--keep-paused\x1b[0m\nflag is provided, it will stay paused.\n\nEither \x1b[1m--activity-id\x1b[0m (with \x1b[1m--workflow-id\x1b[0m for a workflow Activity, or\nalone for a standalone Activity) or \x1b[1m--query\x1b[0m must be specified.\n\n### Resetting activities that heartbeat {#reset-heartbeats}\n\nActivities that heartbeat will receive a\nCanceled failure the next time\nthey heartbeat after a reset.\n\nIf, in your Activity, you need to do any cleanup when an Activity is\nreset, handle this error and then re-throw it when you've cleaned up.\n\nIf the \x1b[1m--reset-heartbeats\x1b[0m flag is set, the heartbeat details will also be cleared.\n\nSpecify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --keep-paused \\\n --reset-heartbeats\x1b[0m\n\nActivities can be reset in bulk with a visibility query list filter:\n\n\x1b[1mtemporal activity reset \\\n --query 'WorkflowType=\"YourWorkflow\"'\x1b[0m\n\nOmit \x1b[1m--workflow-id\x1b[0m to target a Standalone Activity by Activity ID\nand optional Run ID." + s.Command.Long = "Reset an activity.\nThis restarts the activity as if it were first being\nscheduled. That is, it will reset both the number of attempts and the\nactivity timeout, as well as, optionally, the\nheartbeat details.\n\nIf the activity may be executing (i.e. it has not yet timed out), the\nreset will take effect the next time it fails, heartbeats, or times out.\nIf is waiting for a retry (i.e. has failed or timed out), the reset\nwill apply immediately.\n\nIf the activity is already paused, it will be unpaused by default.\nYou can specify \x1b[1m--keep-paused\x1b[0m to prevent this.\n\nIf the activity is paused and the \x1b[1m--keep-paused\x1b[0m flag is not provided,\nit will be unpaused. If the activity is paused and the \x1b[1m--keep-paused\x1b[0m\nflag is provided, it will stay paused.\n\nEither \x1b[1m--activity-id\x1b[0m (with \x1b[1m--workflow-id\x1b[0m for a workflow Activity, or\nalone for a standalone Activity) or \x1b[1m--query\x1b[0m must be specified.\n\n### Resetting activities that heartbeat {#reset-heartbeats}\n\nActivities that heartbeat will receive a\nCanceled failure the next time\nthey heartbeat after a reset.\n\nIf, in your Activity, you need to do any cleanup when an Activity is\nreset, handle this error and then re-throw it when you've cleaned up.\n\nIf the \x1b[1m--reset-heartbeats\x1b[0m flag is set, the heartbeat details will also be cleared.\n\nSpecify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --keep-paused\x1b[0m\n\nActivities can be reset in bulk with a visibility query list filter:\n\n\x1b[1mtemporal activity reset \\\n --query 'WorkflowType=\"YourWorkflow\"'\x1b[0m\n\nOmit \x1b[1m--workflow-id\x1b[0m to target a Standalone Activity by Activity ID\nand optional Run ID." } else { - s.Command.Long = "Reset an activity.\nThis restarts the activity as if it were first being\nscheduled. That is, it will reset both the number of attempts and the\nactivity timeout, as well as, optionally, the\nheartbeat details.\n\nIf the activity may be executing (i.e. it has not yet timed out), the\nreset will take effect the next time it fails, heartbeats, or times out.\nIf is waiting for a retry (i.e. has failed or timed out), the reset\nwill apply immediately.\n\nIf the activity is already paused, it will be unpaused by default.\nYou can specify `--keep-paused` to prevent this.\n\nIf the activity is paused and the `--keep-paused` flag is not provided,\nit will be unpaused. If the activity is paused and the `--keep-paused`\nflag is provided, it will stay paused.\n\nEither `--activity-id` (with `--workflow-id` for a workflow Activity, or\nalone for a standalone Activity) or `--query` must be specified.\n\n### Resetting activities that heartbeat {#reset-heartbeats}\n\nActivities that heartbeat will receive a\nCanceled failure the next time\nthey heartbeat after a reset.\n\nIf, in your Activity, you need to do any cleanup when an Activity is\nreset, handle this error and then re-throw it when you've cleaned up.\n\nIf the `--reset-heartbeats` flag is set, the heartbeat details will also be cleared.\n\nSpecify the Activity and Workflow IDs:\n\n```\ntemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --keep-paused \\\n --reset-heartbeats\n```\n\nActivities can be reset in bulk with a visibility query list filter:\n\n```\ntemporal activity reset \\\n --query 'WorkflowType=\"YourWorkflow\"'\n```\n\nOmit `--workflow-id` to target a Standalone Activity by Activity ID\nand optional Run ID." + s.Command.Long = "Reset an activity.\nThis restarts the activity as if it were first being\nscheduled. That is, it will reset both the number of attempts and the\nactivity timeout, as well as, optionally, the\nheartbeat details.\n\nIf the activity may be executing (i.e. it has not yet timed out), the\nreset will take effect the next time it fails, heartbeats, or times out.\nIf is waiting for a retry (i.e. has failed or timed out), the reset\nwill apply immediately.\n\nIf the activity is already paused, it will be unpaused by default.\nYou can specify `--keep-paused` to prevent this.\n\nIf the activity is paused and the `--keep-paused` flag is not provided,\nit will be unpaused. If the activity is paused and the `--keep-paused`\nflag is provided, it will stay paused.\n\nEither `--activity-id` (with `--workflow-id` for a workflow Activity, or\nalone for a standalone Activity) or `--query` must be specified.\n\n### Resetting activities that heartbeat {#reset-heartbeats}\n\nActivities that heartbeat will receive a\nCanceled failure the next time\nthey heartbeat after a reset.\n\nIf, in your Activity, you need to do any cleanup when an Activity is\nreset, handle this error and then re-throw it when you've cleaned up.\n\nIf the `--reset-heartbeats` flag is set, the heartbeat details will also be cleared.\n\nSpecify the Activity and Workflow IDs:\n\n```\ntemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --keep-paused\n```\n\nActivities can be reset in bulk with a visibility query list filter:\n\n```\ntemporal activity reset \\\n --query 'WorkflowType=\"YourWorkflow\"'\n```\n\nOmit `--workflow-id` to target a Standalone Activity by Activity ID\nand optional Run ID." } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "The Activity ID to reset. Mutually exclusive with `--query`. Set `--workflow-id` to target a workflow Activity, or omit it to target a standalone Activity (the latest run unless `--run-id` is set).") s.Command.Flags().BoolVar(&s.KeepPaused, "keep-paused", false, "If the activity was paused, it will stay paused.") s.Command.Flags().BoolVar(&s.ResetAttempts, "reset-attempts", false, "Reset the activity attempts.") - s.Command.Flags().BoolVar(&s.ResetHeartbeats, "reset-heartbeats", false, "Reset the Activity's heartbeats.") s.Jitter = 0 s.Command.Flags().Var(&s.Jitter, "jitter", "The activity will reset at random a time within the specified duration. Can only be used with --query.") s.Command.Flags().BoolVar(&s.RestoreOriginalOptions, "restore-original-options", false, "Restore the original options of the activity.") diff --git a/internal/temporalcli/commands.yaml b/internal/temporalcli/commands.yaml index 3b6819f60..c8bf51dd4 100644 --- a/internal/temporalcli/commands.yaml +++ b/internal/temporalcli/commands.yaml @@ -666,8 +666,7 @@ commands: temporal activity reset \ --activity-id YourActivityId \ --workflow-id YourWorkflowId \ - --keep-paused \ - --reset-heartbeats + --keep-paused ``` Activities can be reset in bulk with a visibility query list filter: @@ -693,9 +692,6 @@ commands: - name: reset-attempts type: bool description: Reset the activity attempts. - - name: reset-heartbeats - type: bool - description: Reset the Activity's heartbeats. - name: jitter type: duration description: | @@ -1144,10 +1140,10 @@ commands: deployment create` command allows you to pre-define a Worker Deployment so that calls to `temporal worker deployment create-version` will succeed. - + If a Worker Deployment with the supplied name already exists, this command will return an error. - + Note: This is an experimental feature and may change in the future. option-sets: - deployment-name @@ -1604,7 +1600,7 @@ commands: --deployment-name YourDeploymentName --build-id YourBuildID \ --remove ``` - + If a Worker Deployment Version with the supplied BuildID does not exist, this command will return an error. From 0d2176c11afbe02f806d96dbdec7ddf6e50a3493 Mon Sep 17 00:00:00 2001 From: Sean Kane Date: Mon, 20 Jul 2026 17:04:12 -0600 Subject: [PATCH 5/8] fixing tests --- internal/temporalcli/commands.activity_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/temporalcli/commands.activity_test.go b/internal/temporalcli/commands.activity_test.go index 8acb32264..cba9a0e15 100644 --- a/internal/temporalcli/commands.activity_test.go +++ b/internal/temporalcli/commands.activity_test.go @@ -376,6 +376,7 @@ func (s *SharedServerSuite) TestActivityStandalone_UpdateOptions() { "--schedule-to-close-timeout", "60s", "--start-to-close-timeout", "10s", "--retry-initial-interval", "5s", + "--retry-maximum-interval", "10s", "--retry-maximum-attempts", "5", "--address", s.Address(), ) @@ -384,6 +385,7 @@ func (s *SharedServerSuite) TestActivityStandalone_UpdateOptions() { s.ContainsOnSameLine(out, "ScheduleToCloseTimeout", "1m0s") s.ContainsOnSameLine(out, "StartToCloseTimeout", "10s") s.ContainsOnSameLine(out, "InitialInterval", "5s") + s.ContainsOnSameLine(out, "MaximumInterval", "10s") s.ContainsOnSameLine(out, "MaximumAttempts", "5") } From 9e99c57c589039bfd6553abb91db1e57da49bc1e Mon Sep 17 00:00:00 2001 From: Sean Kane Date: Tue, 21 Jul 2026 10:37:35 -0600 Subject: [PATCH 6/8] wrong name --- internal/temporalcli/commands.activity.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/temporalcli/commands.activity.go b/internal/temporalcli/commands.activity.go index f6f9c5efa..07d51c69e 100644 --- a/internal/temporalcli/commands.activity.go +++ b/internal/temporalcli/commands.activity.go @@ -880,7 +880,7 @@ func (c *TemporalActivityUpdateOptionsCommand) run(cctx *CommandContext, args [] if c.Command.Flags().Changed("task-queue") { activityOptions.TaskQueue = &taskqueuepb.TaskQueue{Name: c.TaskQueue} - updatePath = append(updatePath, "task_queue_name") + updatePath = append(updatePath, "task_queue.name") } if c.Command.Flags().Changed("schedule-to-close-timeout") { From 57ad7a9aa0e34c36bba3f3cac01ea937ce2eca27 Mon Sep 17 00:00:00 2001 From: Sean Kane Date: Wed, 29 Jul 2026 12:56:23 -0600 Subject: [PATCH 7/8] enable saa operator commands by DC --- internal/temporalcli/commands_test.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/internal/temporalcli/commands_test.go b/internal/temporalcli/commands_test.go index 3146206c4..52819e65b 100644 --- a/internal/temporalcli/commands_test.go +++ b/internal/temporalcli/commands_test.go @@ -237,12 +237,13 @@ func (s *SharedServerSuite) SetupSuite() { // Required by TestWorkflow_Show_SystemNexusOperationTransformsTypeNames // to schedule a SignalWithStartWorkflowExecution Nexus operation against // the __temporal_system endpoint from inside a workflow. - "history.enableSignalWithStartFromWorkflow": true, - "activity.enableStandalone": true, - "activity.startDelayEnabled": true, - "activity.longPollTimeout": 2 * time.Second, - "nexusoperation.enableStandalone": true, - "history.enableChasmCallbacks": true, + "history.enableSignalWithStartFromWorkflow": true, + "activity.enableStandalone": true, + "activity.startDelayEnabled": true, + "history.enableStandaloneActivityOperatorCommands": true, + "activity.longPollTimeout": 2 * time.Second, + "nexusoperation.enableStandalone": true, + "history.enableChasmCallbacks": true, // this is overridden since we don't want caching to be enabled // while testing DescribeTaskQueue behaviour related to versioning "matching.TaskQueueInfoByBuildIdTTL": 0 * time.Second, From b72bb14001aa5d074f133ce1d36c6b0edc98e231 Mon Sep 17 00:00:00 2001 From: Sean Kane Date: Wed, 29 Jul 2026 14:17:59 -0600 Subject: [PATCH 8/8] add update-options, correct some documentation strings --- internal/temporalcli/commands.activity.go | 27 ++++++---- .../temporalcli/commands.activity_test.go | 50 +++++++++++++++++++ internal/temporalcli/commands.gen.go | 13 +++-- internal/temporalcli/commands.yaml | 25 +++++++--- 4 files changed, 94 insertions(+), 21 deletions(-) diff --git a/internal/temporalcli/commands.activity.go b/internal/temporalcli/commands.activity.go index 07d51c69e..78e8a41d3 100644 --- a/internal/temporalcli/commands.activity.go +++ b/internal/temporalcli/commands.activity.go @@ -34,6 +34,7 @@ type ( ScheduleToStartTimeout time.Duration StartToCloseTimeout time.Duration HeartbeatTimeout time.Duration + StartDelay time.Duration InitialInterval time.Duration BackoffCoefficient float64 @@ -903,6 +904,11 @@ func (c *TemporalActivityUpdateOptionsCommand) run(cctx *CommandContext, args [] updatePath = append(updatePath, "heartbeat_timeout") } + if c.Command.Flags().Changed("start-delay") { + activityOptions.StartDelay = durationpb.New(c.StartDelay.Duration()) + updatePath = append(updatePath, "start_delay") + } + if c.Command.Flags().Changed("retry-initial-interval") || c.Command.Flags().Changed("retry-maximum-interval") || c.Command.Flags().Changed("retry-backoff-coefficient") || @@ -988,6 +994,7 @@ func (c *TemporalActivityUpdateOptionsCommand) run(cctx *CommandContext, args [] ScheduleToStartTimeout: result.GetActivityOptions().ScheduleToStartTimeout.AsDuration(), StartToCloseTimeout: result.GetActivityOptions().StartToCloseTimeout.AsDuration(), HeartbeatTimeout: result.GetActivityOptions().HeartbeatTimeout.AsDuration(), + StartDelay: result.GetActivityOptions().StartDelay.AsDuration(), InitialInterval: result.GetActivityOptions().RetryPolicy.InitialInterval.AsDuration(), BackoffCoefficient: result.GetActivityOptions().RetryPolicy.BackoffCoefficient, @@ -1173,12 +1180,12 @@ func (c *TemporalActivityResetCommand) run(cctx *CommandContext, args []string) } request := &workflowservice.ResetActivityExecutionRequest{ - Namespace: c.Parent.Namespace, - WorkflowId: c.WorkflowId, - ActivityId: c.ActivityId, - RunId: c.RunId, - Identity: c.Parent.Identity, - KeepPaused: c.KeepPaused, + Namespace: c.Parent.Namespace, + WorkflowId: c.WorkflowId, + ActivityId: c.ActivityId, + RunId: c.RunId, + Identity: c.Parent.Identity, + KeepPaused: c.KeepPaused, } resp, err := cl.WorkflowService().ResetActivityExecution(cctx, request) @@ -1187,11 +1194,11 @@ func (c *TemporalActivityResetCommand) run(cctx *CommandContext, args []string) } resetResponse := struct { - KeepPaused bool `json:"keepPaused"` - ServerResponse bool `json:"-"` + KeepPaused bool `json:"keepPaused"` + ServerResponse bool `json:"-"` }{ - ServerResponse: resp != nil, - KeepPaused: c.KeepPaused, + ServerResponse: resp != nil, + KeepPaused: c.KeepPaused, } _ = cctx.Printer.PrintStructured(resetResponse, printer.StructuredOptions{}) diff --git a/internal/temporalcli/commands.activity_test.go b/internal/temporalcli/commands.activity_test.go index cba9a0e15..dd345c027 100644 --- a/internal/temporalcli/commands.activity_test.go +++ b/internal/temporalcli/commands.activity_test.go @@ -389,6 +389,56 @@ func (s *SharedServerSuite) TestActivityStandalone_UpdateOptions() { s.ContainsOnSameLine(out, "MaximumAttempts", "5") } +func (s *SharedServerSuite) TestActivityStandalone_UpdateOptions_StartDelay() { + var started atomic.Bool + s.Worker().OnDevActivity(func(ctx context.Context, a any) (any, error) { + started.Store(true) + return nil, nil + }) + + handle, err := s.Client.ExecuteActivity( + s.Context, + client.StartActivityOptions{ + ID: newStandaloneActivityID(), + TaskQueue: s.Worker().Options.TaskQueue, + StartToCloseTimeout: time.Minute, + StartDelay: 15 * time.Second, + }, + "DevActivity", + "input", + ) + s.NoError(err) + + res := s.Execute( + "activity", "pause", + "--activity-id", handle.GetID(), + "--run-id", handle.GetRunID(), + "--address", s.Address(), + ) + s.NoError(res.Err) + s.Eventually(func() bool { + return s.standaloneActivityRunState(handle) == enums.PENDING_ACTIVITY_STATE_PAUSED + }, 10*time.Second, 100*time.Millisecond) + + res = s.Execute( + "activity", "update-options", + "--activity-id", handle.GetID(), + "--run-id", handle.GetRunID(), + "--start-delay", "0s", + "--address", s.Address(), + ) + s.NoError(res.Err) + + res = s.Execute( + "activity", "unpause", + "--activity-id", handle.GetID(), + "--run-id", handle.GetRunID(), + "--address", s.Address(), + ) + s.NoError(res.Err) + s.Eventually(started.Load, 2*time.Second, 100*time.Millisecond) +} + func (s *SharedServerSuite) TestActivityStandalone_PauseByActivityIdOnly() { handle, stopFailing := s.startStandaloneActivity(newStandaloneActivityID()) defer stopFailing() diff --git a/internal/temporalcli/commands.gen.go b/internal/temporalcli/commands.gen.go index a3d1373c0..4965caac8 100644 --- a/internal/temporalcli/commands.gen.go +++ b/internal/temporalcli/commands.gen.go @@ -882,9 +882,9 @@ func NewTemporalActivityResetCommand(cctx *CommandContext, parent *TemporalActiv s.Command.Use = "reset [flags]" s.Command.Short = "Reset an Activity" if hasHighlighting { - s.Command.Long = "Reset an activity.\nThis restarts the activity as if it were first being\nscheduled. That is, it will reset both the number of attempts and the\nactivity timeout, as well as, optionally, the\nheartbeat details.\n\nIf the activity may be executing (i.e. it has not yet timed out), the\nreset will take effect the next time it fails, heartbeats, or times out.\nIf is waiting for a retry (i.e. has failed or timed out), the reset\nwill apply immediately.\n\nIf the activity is already paused, it will be unpaused by default.\nYou can specify \x1b[1m--keep-paused\x1b[0m to prevent this.\n\nIf the activity is paused and the \x1b[1m--keep-paused\x1b[0m flag is not provided,\nit will be unpaused. If the activity is paused and the \x1b[1m--keep-paused\x1b[0m\nflag is provided, it will stay paused.\n\nEither \x1b[1m--activity-id\x1b[0m (with \x1b[1m--workflow-id\x1b[0m for a workflow Activity, or\nalone for a standalone Activity) or \x1b[1m--query\x1b[0m must be specified.\n\n### Resetting activities that heartbeat {#reset-heartbeats}\n\nActivities that heartbeat will receive a\nCanceled failure the next time\nthey heartbeat after a reset.\n\nIf, in your Activity, you need to do any cleanup when an Activity is\nreset, handle this error and then re-throw it when you've cleaned up.\n\nIf the \x1b[1m--reset-heartbeats\x1b[0m flag is set, the heartbeat details will also be cleared.\n\nSpecify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --keep-paused\x1b[0m\n\nActivities can be reset in bulk with a visibility query list filter:\n\n\x1b[1mtemporal activity reset \\\n --query 'WorkflowType=\"YourWorkflow\"'\x1b[0m\n\nOmit \x1b[1m--workflow-id\x1b[0m to target a Standalone Activity by Activity ID\nand optional Run ID." + s.Command.Long = "Reset an activity.\nThis restarts the activity as if it were first being\nscheduled. That is, it will reset both the number of attempts and the\nactivity timeout, as well as the heartbeat details.\n\nIf the activity may be executing (i.e. it has not yet timed out), the\nreset will take effect the next time it fails, heartbeats, or times out.\nIf is waiting for a retry (i.e. has failed or timed out), the reset\nwill apply immediately.\n\nIf the activity is already paused, it will be unpaused by default.\nYou can specify \x1b[1m--keep-paused\x1b[0m to prevent this.\n\nIf the activity is paused and the \x1b[1m--keep-paused\x1b[0m flag is not provided,\nit will be unpaused. If the activity is paused and the \x1b[1m--keep-paused\x1b[0m\nflag is provided, it will stay paused.\n\nEither \x1b[1m--activity-id\x1b[0m (with \x1b[1m--workflow-id\x1b[0m for a workflow Activity, or\nalone for a standalone Activity) or \x1b[1m--query\x1b[0m must be specified.\n\n### Resetting activities that heartbeat {#reset-heartbeats}\n\nActivities that heartbeat will receive a\nCanceled failure the next time\nthey heartbeat after a reset.\n\nIf, in your Activity, you need to do any cleanup when an Activity is\nreset, handle this error and then re-throw it when you've cleaned up.\n\nReset always clears the heartbeat details.\n\nSpecify the Activity and Workflow IDs:\n\n\x1b[1mtemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --keep-paused\x1b[0m\n\nActivities can be reset in bulk with a visibility query list filter:\n\n\x1b[1mtemporal activity reset \\\n --query 'WorkflowType=\"YourWorkflow\"'\x1b[0m\n\nOmit \x1b[1m--workflow-id\x1b[0m to target a Standalone Activity by Activity ID\nand optional Run ID." } else { - s.Command.Long = "Reset an activity.\nThis restarts the activity as if it were first being\nscheduled. That is, it will reset both the number of attempts and the\nactivity timeout, as well as, optionally, the\nheartbeat details.\n\nIf the activity may be executing (i.e. it has not yet timed out), the\nreset will take effect the next time it fails, heartbeats, or times out.\nIf is waiting for a retry (i.e. has failed or timed out), the reset\nwill apply immediately.\n\nIf the activity is already paused, it will be unpaused by default.\nYou can specify `--keep-paused` to prevent this.\n\nIf the activity is paused and the `--keep-paused` flag is not provided,\nit will be unpaused. If the activity is paused and the `--keep-paused`\nflag is provided, it will stay paused.\n\nEither `--activity-id` (with `--workflow-id` for a workflow Activity, or\nalone for a standalone Activity) or `--query` must be specified.\n\n### Resetting activities that heartbeat {#reset-heartbeats}\n\nActivities that heartbeat will receive a\nCanceled failure the next time\nthey heartbeat after a reset.\n\nIf, in your Activity, you need to do any cleanup when an Activity is\nreset, handle this error and then re-throw it when you've cleaned up.\n\nIf the `--reset-heartbeats` flag is set, the heartbeat details will also be cleared.\n\nSpecify the Activity and Workflow IDs:\n\n```\ntemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --keep-paused\n```\n\nActivities can be reset in bulk with a visibility query list filter:\n\n```\ntemporal activity reset \\\n --query 'WorkflowType=\"YourWorkflow\"'\n```\n\nOmit `--workflow-id` to target a Standalone Activity by Activity ID\nand optional Run ID." + s.Command.Long = "Reset an activity.\nThis restarts the activity as if it were first being\nscheduled. That is, it will reset both the number of attempts and the\nactivity timeout, as well as the heartbeat details.\n\nIf the activity may be executing (i.e. it has not yet timed out), the\nreset will take effect the next time it fails, heartbeats, or times out.\nIf is waiting for a retry (i.e. has failed or timed out), the reset\nwill apply immediately.\n\nIf the activity is already paused, it will be unpaused by default.\nYou can specify `--keep-paused` to prevent this.\n\nIf the activity is paused and the `--keep-paused` flag is not provided,\nit will be unpaused. If the activity is paused and the `--keep-paused`\nflag is provided, it will stay paused.\n\nEither `--activity-id` (with `--workflow-id` for a workflow Activity, or\nalone for a standalone Activity) or `--query` must be specified.\n\n### Resetting activities that heartbeat {#reset-heartbeats}\n\nActivities that heartbeat will receive a\nCanceled failure the next time\nthey heartbeat after a reset.\n\nIf, in your Activity, you need to do any cleanup when an Activity is\nreset, handle this error and then re-throw it when you've cleaned up.\n\nReset always clears the heartbeat details.\n\nSpecify the Activity and Workflow IDs:\n\n```\ntemporal activity reset \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --keep-paused\n```\n\nActivities can be reset in bulk with a visibility query list filter:\n\n```\ntemporal activity reset \\\n --query 'WorkflowType=\"YourWorkflow\"'\n```\n\nOmit `--workflow-id` to target a Standalone Activity by Activity ID\nand optional Run ID." } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "The Activity ID to reset. Mutually exclusive with `--query`. Set `--workflow-id` to target a workflow Activity, or omit it to target a standalone Activity (the latest run unless `--run-id` is set).") @@ -1035,6 +1035,7 @@ type TemporalActivityUpdateOptionsCommand struct { ScheduleToStartTimeout cliext.FlagDuration StartToCloseTimeout cliext.FlagDuration HeartbeatTimeout cliext.FlagDuration + StartDelay cliext.FlagDuration RetryInitialInterval cliext.FlagDuration RetryMaximumInterval cliext.FlagDuration RetryBackoffCoefficient float32 @@ -1047,11 +1048,11 @@ func NewTemporalActivityUpdateOptionsCommand(cctx *CommandContext, parent *Tempo s.Parent = parent s.Command.DisableFlagsInUseLine = true s.Command.Use = "update-options [flags]" - s.Command.Short = "Change the values of options affecting a running Activity" + s.Command.Short = "Change the values of options affecting an Activity" if hasHighlighting { - s.Command.Long = "Update the options of a running Activity that were passed into it from\na Workflow. Updates are incremental, only changing the specified options.\n\nFor example:\n\n\x1b[1mtemporal activity update-options \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --task-queue NewTaskQueueName \\\n --schedule-to-close-timeout DURATION \\\n --schedule-to-start-timeout DURATION \\\n --start-to-close-timeout DURATION \\\n --heartbeat-timeout DURATION \\\n --retry-initial-interval DURATION \\\n --retry-maximum-interval DURATION \\\n --retry-backoff-coefficient NewBackoffCoefficient \\\n --retry-maximum-attempts NewMaximumAttempts\x1b[0m\n\nYou may follow this command with \x1b[1mtemporal activity reset\x1b[0m, and the new\nvalues will apply after the reset.\n\nEither \x1b[1m--activity-id\x1b[0m or \x1b[1m--query\x1b[0m must be specified.\n\nActivity options can be updated in bulk with a visibility query list filter:\n\n\x1b[1mtemporal activity update-options \\\n --query 'WorkflowType=\"YourWorkflow\"' \\\n --task-queue NewTaskQueueName\x1b[0m\n\nOmit \x1b[1m--workflow-id\x1b[0m to target a Standalone Activity by Activity ID\nand optional Run ID." + s.Command.Long = "Update an Activity's options. Updates are incremental, only changing the\nspecified options.\n\nFor example:\n\n\x1b[1mtemporal activity update-options \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --task-queue NewTaskQueueName \\\n --schedule-to-close-timeout DURATION \\\n --schedule-to-start-timeout DURATION \\\n --start-to-close-timeout DURATION \\\n --heartbeat-timeout DURATION \\\n --retry-initial-interval DURATION \\\n --retry-maximum-interval DURATION \\\n --retry-backoff-coefficient NewBackoffCoefficient \\\n --retry-maximum-attempts NewMaximumAttempts\x1b[0m\n\nYou may follow this command with \x1b[1mtemporal activity reset\x1b[0m, and the new\nvalues will apply after the reset.\n\nFor a Standalone Activity before its first dispatch, use \x1b[1m--start-delay\x1b[0m\nto change when the first Activity Task becomes available. The duration is\nmeasured from the Activity's original schedule time, and \x1b[1m0s\x1b[0m makes it\navailable immediately. \x1b[1m--start-delay\x1b[0m cannot be changed after the first\nActivity Task has been dispatched and is not supported for workflow\nActivities.\n\nEither \x1b[1m--activity-id\x1b[0m or \x1b[1m--query\x1b[0m must be specified.\n\nActivity options can be updated in bulk with a visibility query list filter:\n\n\x1b[1mtemporal activity update-options \\\n --query 'WorkflowType=\"YourWorkflow\"' \\\n --task-queue NewTaskQueueName\x1b[0m\n\nOmit \x1b[1m--workflow-id\x1b[0m to target a Standalone Activity by Activity ID\nand optional Run ID." } else { - s.Command.Long = "Update the options of a running Activity that were passed into it from\na Workflow. Updates are incremental, only changing the specified options.\n\nFor example:\n\n```\ntemporal activity update-options \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --task-queue NewTaskQueueName \\\n --schedule-to-close-timeout DURATION \\\n --schedule-to-start-timeout DURATION \\\n --start-to-close-timeout DURATION \\\n --heartbeat-timeout DURATION \\\n --retry-initial-interval DURATION \\\n --retry-maximum-interval DURATION \\\n --retry-backoff-coefficient NewBackoffCoefficient \\\n --retry-maximum-attempts NewMaximumAttempts\n```\n\nYou may follow this command with `temporal activity reset`, and the new\nvalues will apply after the reset.\n\nEither `--activity-id` or `--query` must be specified.\n\nActivity options can be updated in bulk with a visibility query list filter:\n\n```\ntemporal activity update-options \\\n --query 'WorkflowType=\"YourWorkflow\"' \\\n --task-queue NewTaskQueueName\n```\n\nOmit `--workflow-id` to target a Standalone Activity by Activity ID\nand optional Run ID." + s.Command.Long = "Update an Activity's options. Updates are incremental, only changing the\nspecified options.\n\nFor example:\n\n```\ntemporal activity update-options \\\n --activity-id YourActivityId \\\n --workflow-id YourWorkflowId \\\n --task-queue NewTaskQueueName \\\n --schedule-to-close-timeout DURATION \\\n --schedule-to-start-timeout DURATION \\\n --start-to-close-timeout DURATION \\\n --heartbeat-timeout DURATION \\\n --retry-initial-interval DURATION \\\n --retry-maximum-interval DURATION \\\n --retry-backoff-coefficient NewBackoffCoefficient \\\n --retry-maximum-attempts NewMaximumAttempts\n```\n\nYou may follow this command with `temporal activity reset`, and the new\nvalues will apply after the reset.\n\nFor a Standalone Activity before its first dispatch, use `--start-delay`\nto change when the first Activity Task becomes available. The duration is\nmeasured from the Activity's original schedule time, and `0s` makes it\navailable immediately. `--start-delay` cannot be changed after the first\nActivity Task has been dispatched and is not supported for workflow\nActivities.\n\nEither `--activity-id` or `--query` must be specified.\n\nActivity options can be updated in bulk with a visibility query list filter:\n\n```\ntemporal activity update-options \\\n --query 'WorkflowType=\"YourWorkflow\"' \\\n --task-queue NewTaskQueueName\n```\n\nOmit `--workflow-id` to target a Standalone Activity by Activity ID\nand optional Run ID." } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVarP(&s.ActivityId, "activity-id", "a", "", "The Activity ID to update options. Mutually exclusive with `--query`. Set `--workflow-id` to target a workflow Activity, or omit it to target a standalone Activity (the latest run unless `--run-id` is set).") @@ -1064,6 +1065,8 @@ func NewTemporalActivityUpdateOptionsCommand(cctx *CommandContext, parent *Tempo s.Command.Flags().Var(&s.StartToCloseTimeout, "start-to-close-timeout", "Maximum time an activity is allowed to execute after being picked up by a worker. This timeout is always retryable.") s.HeartbeatTimeout = 0 s.Command.Flags().Var(&s.HeartbeatTimeout, "heartbeat-timeout", "Maximum permitted time between successful worker heartbeats.") + s.StartDelay = 0 + s.Command.Flags().Var(&s.StartDelay, "start-delay", "For a Standalone Activity before its first Activity Task is dispatched, changes when that task becomes available. The duration is measured from the Activity's original schedule time. Set to `0s` to make the task available immediately.") s.RetryInitialInterval = 0 s.Command.Flags().Var(&s.RetryInitialInterval, "retry-initial-interval", "Interval of the first retry. If retryBackoffCoefficient is 1.0 then it is used for all retries.") s.RetryMaximumInterval = 0 diff --git a/internal/temporalcli/commands.yaml b/internal/temporalcli/commands.yaml index c8bf51dd4..ea284cfe1 100644 --- a/internal/temporalcli/commands.yaml +++ b/internal/temporalcli/commands.yaml @@ -401,10 +401,10 @@ commands: at a time from the server. - name: temporal activity update-options - summary: Change the values of options affecting a running Activity + summary: Change the values of options affecting an Activity description: | - Update the options of a running Activity that were passed into it from - a Workflow. Updates are incremental, only changing the specified options. + Update an Activity's options. Updates are incremental, only changing the + specified options. For example: @@ -426,6 +426,13 @@ commands: You may follow this command with `temporal activity reset`, and the new values will apply after the reset. + For a Standalone Activity before its first dispatch, use `--start-delay` + to change when the first Activity Task becomes available. The duration is + measured from the Activity's original schedule time, and `0s` makes it + available immediately. `--start-delay` cannot be changed after the first + Activity Task has been dispatched and is not supported for workflow + Activities. + Either `--activity-id` or `--query` must be specified. Activity options can be updated in bulk with a visibility query list filter: @@ -473,6 +480,13 @@ commands: type: duration description: | Maximum permitted time between successful worker heartbeats. + - name: start-delay + type: duration + description: | + For a Standalone Activity before its first Activity Task is dispatched, + changes when that task becomes available. The duration is measured from + the Activity's original schedule time. Set to `0s` to make the task + available immediately. - name: retry-initial-interval type: duration description: | @@ -631,8 +645,7 @@ commands: Reset an activity. This restarts the activity as if it were first being scheduled. That is, it will reset both the number of attempts and the - activity timeout, as well as, optionally, the - [heartbeat details](#reset-heartbeats). + activity timeout, as well as the [heartbeat details](#reset-heartbeats). If the activity may be executing (i.e. it has not yet timed out), the reset will take effect the next time it fails, heartbeats, or times out. @@ -658,7 +671,7 @@ commands: If, in your Activity, you need to do any cleanup when an Activity is reset, handle this error and then re-throw it when you've cleaned up. - If the `--reset-heartbeats` flag is set, the heartbeat details will also be cleared. + Reset always clears the heartbeat details. Specify the Activity and Workflow IDs: