From 1b7f726ca7fa57d47c9b01fe90e92edf824a3812 Mon Sep 17 00:00:00 2001 From: Antonio Lain Date: Thu, 20 Feb 2025 01:00:42 -0800 Subject: [PATCH 1/2] First implementation without tests --- go.mod | 2 +- go.sum | 2 + temporalcli/commands.gen.go | 226 +++++++++-- temporalcli/commands.worker.deployment.go | 368 ++++++------------ .../commands.worker.deployment.version.go | 352 +++++++++++++++++ .../commands.worker.deployment_test.go | 6 +- temporalcli/commands.workflow_test.go | 320 ++++++++------- temporalcli/commands.workflow_view_test.go | 139 ++++--- temporalcli/commandsgen/commands.yml | 322 ++++++++++++--- 9 files changed, 1162 insertions(+), 575 deletions(-) create mode 100644 temporalcli/commands.worker.deployment.version.go diff --git a/go.mod b/go.mod index 02684e571..51da57606 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/stretchr/testify v1.10.0 github.com/temporalio/ui-server/v2 v2.35.0 go.temporal.io/api v1.44.1 - go.temporal.io/sdk v1.32.1 + go.temporal.io/sdk v1.32.2-0.20250219024739-0c6b17c4eef4 go.temporal.io/server v1.27.0-128.4 google.golang.org/grpc v1.70.0 google.golang.org/protobuf v1.36.5 diff --git a/go.sum b/go.sum index 4152bc815..5c9f471e7 100644 --- a/go.sum +++ b/go.sum @@ -374,6 +374,8 @@ go.temporal.io/api v1.44.1 h1:sb5Hq08AB0WtYvfLJMiWmHzxjqs2b+6Jmzg4c8IOeng= go.temporal.io/api v1.44.1/go.mod h1:1WwYUMo6lao8yl0371xWUm13paHExN5ATYT/B7QtFis= go.temporal.io/sdk v1.32.1 h1:slA8prhdFr4lxpsTcRusWVitD/cGjELfKUh0mBj73SU= go.temporal.io/sdk v1.32.1/go.mod h1:8U8H7rF9u4Hyb4Ry9yiEls5716DHPNvVITPNkgWUwE8= +go.temporal.io/sdk v1.32.2-0.20250219024739-0c6b17c4eef4 h1:3IIf8PkvJTLdTG4KHhUGHOlXANny9DyJbw58AQAeIxo= +go.temporal.io/sdk v1.32.2-0.20250219024739-0c6b17c4eef4/go.mod h1:XC1GMz3ETAROeV4BrFBXeCJEOEujfRb29xNB2uhXbZY= go.temporal.io/server v1.27.0-128.4 h1:K3N4AMhEot0/E4eXA7hnYu+D/vC4UTF2cilVbxKqd8o= go.temporal.io/server v1.27.0-128.4/go.mod h1:YgN/yuBArvm7q5VEk2SXY+cGTTvDbt5AyH34DvEd3so= go.temporal.io/version v0.3.0 h1:dMrei9l9NyHt8nG6EB8vAwDLLTwx2SvRyucCSumAiig= diff --git a/temporalcli/commands.gen.go b/temporalcli/commands.gen.go index 12a724051..a7061dd9d 100644 --- a/temporalcli/commands.gen.go +++ b/temporalcli/commands.gen.go @@ -131,6 +131,24 @@ func (v *WorkflowReferenceOptions) buildFlags(cctx *CommandContext, f *pflag.Fla f.StringVarP(&v.RunId, "run-id", "r", "", "Run ID.") } +type DeploymentNameOptions struct { + Name string +} + +func (v *DeploymentNameOptions) buildFlags(cctx *CommandContext, f *pflag.FlagSet) { + f.StringVarP(&v.Name, "name", "d", "", "Name for a Worker Deployment. Required.") + _ = cobra.MarkFlagRequired(f, "name") +} + +type DeploymentVersionOptions struct { + Version string +} + +func (v *DeploymentVersionOptions) buildFlags(cctx *CommandContext, f *pflag.FlagSet) { + f.StringVarP(&v.Version, "version", "v", "", "Fully-qualified name for a Worker Deployment Version. Use the format `YourDeploymentName.YourBuildID`. Required.") + _ = cobra.MarkFlagRequired(f, "version") +} + type DeploymentReferenceOptions struct { SeriesName string BuildId string @@ -2551,41 +2569,41 @@ func NewTemporalWorkerDeploymentCommand(cctx *CommandContext, parent *TemporalWo var s TemporalWorkerDeploymentCommand s.Parent = parent s.Command.Use = "deployment" - s.Command.Short = "Describe, list, and operate on Worker Deployments" + s.Command.Short = "Describe, list, and operate on Worker Deployments and Versions" if hasHighlighting { s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDeployment commands perform operations on Worker Deployments:\n\n\x1b[1mtemporal worker deployment [command] [options]\x1b[0m\n\nFor example:\n\n\x1b[1mtemporal worker deployment list\x1b[0m" } else { s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDeployment commands perform operations on Worker Deployments:\n\n```\ntemporal worker deployment [command] [options]\n```\n\nFor example:\n\n```\ntemporal worker deployment list\n```" } s.Command.Args = cobra.NoArgs + s.Command.AddCommand(&NewTemporalWorkerDeploymentDeleteCommand(cctx, &s).Command) s.Command.AddCommand(&NewTemporalWorkerDeploymentDescribeCommand(cctx, &s).Command) - s.Command.AddCommand(&NewTemporalWorkerDeploymentGetCurrentCommand(cctx, &s).Command) s.Command.AddCommand(&NewTemporalWorkerDeploymentListCommand(cctx, &s).Command) - s.Command.AddCommand(&NewTemporalWorkerDeploymentSetCurrentCommand(cctx, &s).Command) + s.Command.AddCommand(&NewTemporalWorkerDeploymentVersionCommand(cctx, &s).Command) return &s } -type TemporalWorkerDeploymentDescribeCommand struct { +type TemporalWorkerDeploymentDeleteCommand struct { Parent *TemporalWorkerDeploymentCommand Command cobra.Command - DeploymentReferenceOptions - ReportReachability bool + DeploymentNameOptions + Identity string } -func NewTemporalWorkerDeploymentDescribeCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentDescribeCommand { - var s TemporalWorkerDeploymentDescribeCommand +func NewTemporalWorkerDeploymentDeleteCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentDeleteCommand { + var s TemporalWorkerDeploymentDeleteCommand s.Parent = parent s.Command.DisableFlagsInUseLine = true - s.Command.Use = "describe [flags]" - s.Command.Short = "Show properties of a Worker Deployment" + s.Command.Use = "delete [flags]" + s.Command.Short = "Deletes a Worker Deployment" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribes properties of a Worker Deployment, such as whether it is\ncurrent, the non-empty list of its task queues, custom metadata if\npresent, and reachability status when requested.\n\n\x1b[1mtemporal worker deployment describe [options]\x1b[0m\n\nFor example, to also include reachability information:\n\n\x1b[1mtemporal worker deployment describe \\\n --series-name YourDeploymentSeriesName \\\n --build-id YourDeploymentBuildId \\\n --report-reachability\x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemoves a Worker Deployment given its Deployment Name.\nA Deployment can only be deleted if it has no Version in it.\n\n\x1b[1mtemporal worker deployment delete [options]\x1b[0m\n\nFor example, setting the user identity that removed the deployment:\n\n\x1b[1mtemporal worker deployment delete \\\n --name YourDeploymentName \\\n --identity YourIdentity\x1b[0m" } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribes properties of a Worker Deployment, such as whether it is\ncurrent, the non-empty list of its task queues, custom metadata if\npresent, and reachability status when requested.\n\n```\ntemporal worker deployment describe [options]\n```\n\nFor example, to also include reachability information:\n\n```\ntemporal worker deployment describe \\\n --series-name YourDeploymentSeriesName \\\n --build-id YourDeploymentBuildId \\\n --report-reachability\n```" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemoves a Worker Deployment given its Deployment Name.\nA Deployment can only be deleted if it has no Version in it.\n\n```\ntemporal worker deployment delete [options]\n```\n\nFor example, setting the user identity that removed the deployment:\n\n```\ntemporal worker deployment delete \\\n --name YourDeploymentName \\\n --identity YourIdentity\n\n```" } s.Command.Args = cobra.NoArgs - s.Command.Flags().BoolVar(&s.ReportReachability, "report-reachability", false, "Include reachability information of a Worker Deployment.") - s.DeploymentReferenceOptions.buildFlags(cctx, s.Command.Flags()) + s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") + s.DeploymentNameOptions.buildFlags(cctx, s.Command.Flags()) s.Command.Run = func(c *cobra.Command, args []string) { if err := s.run(cctx, args); err != nil { cctx.Options.Fail(err) @@ -2594,26 +2612,25 @@ func NewTemporalWorkerDeploymentDescribeCommand(cctx *CommandContext, parent *Te return &s } -type TemporalWorkerDeploymentGetCurrentCommand struct { - Parent *TemporalWorkerDeploymentCommand - Command cobra.Command - SeriesName string +type TemporalWorkerDeploymentDescribeCommand struct { + Parent *TemporalWorkerDeploymentCommand + Command cobra.Command + DeploymentNameOptions } -func NewTemporalWorkerDeploymentGetCurrentCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentGetCurrentCommand { - var s TemporalWorkerDeploymentGetCurrentCommand +func NewTemporalWorkerDeploymentDescribeCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentDescribeCommand { + var s TemporalWorkerDeploymentDescribeCommand s.Parent = parent s.Command.DisableFlagsInUseLine = true - s.Command.Use = "get-current [flags]" - s.Command.Short = "Show the current Worker Deployment" + s.Command.Use = "describe [flags]" + s.Command.Short = "Show properties of a Worker Deployment" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nGets the current Worker Deployment for a Deployment Series Name.\nWhen a Deployment is current, Workers of that Deployment will receive\ntasks from new Workflows and from existing AutoUpgrade Workflows that\nare running on this Deployment Series.\n\n\x1b[1mtemporal worker deployment get-current [options]\x1b[0m\n\nFor example:\n\n\x1b[1mtemporal worker deployment get-current \\\n --series-name YourDeploymentSeriesName\x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribes properties of a Worker Deployment, such as the versions\nassociated with it, routing information of new or existing tasks\nexecuted by this deployment, or its creation time.\n\n\x1b[1mtemporal worker deployment describe [options]\x1b[0m\n\nFor example, to describe a deployment \x1b[1mYourDeploymentName\x1b[0m in the default\nnamespace:\n\n\x1b[1mtemporal worker deployment describe \\\n --name YourDeploymentName\x1b[0m" } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nGets the current Worker Deployment for a Deployment Series Name.\nWhen a Deployment is current, Workers of that Deployment will receive\ntasks from new Workflows and from existing AutoUpgrade Workflows that\nare running on this Deployment Series.\n\n```\ntemporal worker deployment get-current [options]\n```\n\nFor example:\n\n```\ntemporal worker deployment get-current \\\n --series-name YourDeploymentSeriesName\n```" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribes properties of a Worker Deployment, such as the versions\nassociated with it, routing information of new or existing tasks\nexecuted by this deployment, or its creation time.\n\n```\ntemporal worker deployment describe [options]\n```\n\nFor example, to describe a deployment `YourDeploymentName` in the default\nnamespace:\n\n```\ntemporal worker deployment describe \\\n --name YourDeploymentName\n```" } s.Command.Args = cobra.NoArgs - s.Command.Flags().StringVar(&s.SeriesName, "series-name", "", "Series Name for the current Worker Deployment. Required.") - _ = cobra.MarkFlagRequired(s.Command.Flags(), "series-name") + s.DeploymentNameOptions.buildFlags(cctx, s.Command.Flags()) s.Command.Run = func(c *cobra.Command, args []string) { if err := s.run(cctx, args); err != nil { cctx.Options.Fail(err) @@ -2623,9 +2640,8 @@ func NewTemporalWorkerDeploymentGetCurrentCommand(cctx *CommandContext, parent * } type TemporalWorkerDeploymentListCommand struct { - Parent *TemporalWorkerDeploymentCommand - Command cobra.Command - SeriesName string + Parent *TemporalWorkerDeploymentCommand + Command cobra.Command } func NewTemporalWorkerDeploymentListCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentListCommand { @@ -2635,12 +2651,11 @@ func NewTemporalWorkerDeploymentListCommand(cctx *CommandContext, parent *Tempor s.Command.Use = "list [flags]" s.Command.Short = "Enumerate Worker Deployments in the client's namespace" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nList existing Worker Deployments in the client's namespace, optionally\nfiltering them by Deployment Series Name.\n\n\n\x1b[1mtemporal worker deployment list [options]\x1b[0m\n\nFor example, adding an optional filter:\n\n\x1b[1mtemporal worker deployment list \\\n --series-name YourDeploymentSeriesName\x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nList existing Worker Deployments in the client's namespace.\n\n\x1b[1mtemporal worker deployment list [options]\x1b[0m\n\nFor example, listing Deployments in YourDeploymentNamespace:\n\n\x1b[1mtemporal worker deployment list \\\n --namespace YourDeploymentNamespace\x1b[0m" } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nList existing Worker Deployments in the client's namespace, optionally\nfiltering them by Deployment Series Name.\n\n\n```\ntemporal worker deployment list [options]\n```\n\nFor example, adding an optional filter:\n\n```\ntemporal worker deployment list \\\n --series-name YourDeploymentSeriesName\n```" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nList existing Worker Deployments in the client's namespace.\n\n```\ntemporal worker deployment list [options]\n```\n\nFor example, listing Deployments in YourDeploymentNamespace:\n\n```\ntemporal worker deployment list \\\n --namespace YourDeploymentNamespace\n```" } s.Command.Args = cobra.NoArgs - s.Command.Flags().StringVar(&s.SeriesName, "series-name", "", "Series Name to filter Worker Deployments.") s.Command.Run = func(c *cobra.Command, args []string) { if err := s.run(cctx, args); err != nil { cctx.Options.Fail(err) @@ -2649,27 +2664,154 @@ func NewTemporalWorkerDeploymentListCommand(cctx *CommandContext, parent *Tempor return &s } -type TemporalWorkerDeploymentSetCurrentCommand struct { +type TemporalWorkerDeploymentVersionCommand struct { Parent *TemporalWorkerDeploymentCommand Command cobra.Command - DeploymentReferenceOptions - Metadata []string } -func NewTemporalWorkerDeploymentSetCurrentCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentSetCurrentCommand { - var s TemporalWorkerDeploymentSetCurrentCommand +func NewTemporalWorkerDeploymentVersionCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentVersionCommand { + var s TemporalWorkerDeploymentVersionCommand + s.Parent = parent + s.Command.Use = "version" + s.Command.Short = "Describe, delete, setCurrent, or setRamping, a Deployment Version" + if hasHighlighting { + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDeployment commands to operate on Worker Deployment Versions:\n \n\x1b[1mtemporal worker deployment version [command] [options]\x1b[0m\n\nFor example, using a fully qualified Version identifier that\nconcatenates the Deployment Name with the Build ID using the\nreserved separator \".\":\n\n\x1b[1mtemporal worker deployment version setCurrent \\\n --version YourDeploymentName.YourBuildID\x1b[0m \nSets the current Deployment Version for a given Deployment.\nWhen a Version is current, Workers of that Deployment Version will receive\ntasks from new Workflows and from existing AutoUpgrade Workflows that\nare running on this Deployment." + } else { + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDeployment commands to operate on Worker Deployment Versions:\n \n```\ntemporal worker deployment version [command] [options]\n```\n\nFor example, using a fully qualified Version identifier that\nconcatenates the Deployment Name with the Build ID using the\nreserved separator \".\":\n\n```\ntemporal worker deployment version setCurrent \\\n --version YourDeploymentName.YourBuildID\n``` \nSets the current Deployment Version for a given Deployment.\nWhen a Version is current, Workers of that Deployment Version will receive\ntasks from new Workflows and from existing AutoUpgrade Workflows that\nare running on this Deployment." + } + s.Command.Args = cobra.NoArgs + s.Command.AddCommand(&NewTemporalWorkerDeploymentVersionDeleteCommand(cctx, &s).Command) + s.Command.AddCommand(&NewTemporalWorkerDeploymentVersionDescribeCommand(cctx, &s).Command) + s.Command.AddCommand(&NewTemporalWorkerDeploymentVersionSetCurrentCommand(cctx, &s).Command) + s.Command.AddCommand(&NewTemporalWorkerDeploymentVersionSetRampingCommand(cctx, &s).Command) + return &s +} + +type TemporalWorkerDeploymentVersionDeleteCommand struct { + Parent *TemporalWorkerDeploymentVersionCommand + Command cobra.Command + DeploymentVersionOptions + Identity string + SkipDrainage bool +} + +func NewTemporalWorkerDeploymentVersionDeleteCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentVersionCommand) *TemporalWorkerDeploymentVersionDeleteCommand { + var s TemporalWorkerDeploymentVersionDeleteCommand + s.Parent = parent + s.Command.DisableFlagsInUseLine = true + s.Command.Use = "delete [flags]" + s.Command.Short = "Deletes a Worker Deployment Version" + if hasHighlighting { + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemoves a Worker Deployment Version given its fully-qualified identifier.\nThis is rarely needed during normal operation\nsince unused Versions are eventually garbage collected.\nThe client can delete a Version only when all of the following conditions\nare met:\n - It is not the Current or Ramping Version for this Deployment.\n - It has no active pollers, i.e., none of the task queues in the\n Version have pollers.\n - It is not draining. This requirement can be ignored with the option\n --skip-drainage.\n \n\x1b[1mtemporal worker deployment version delete [options]\x1b[0m\n\nFor example, forcing to skip the drainage restriction:\n\n\x1b[1mtemporal worker deployment version delete \\\n --version YourDeploymentName.YourBuildID \\\n --skip-drainage \x1b[0m" + } else { + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemoves a Worker Deployment Version given its fully-qualified identifier.\nThis is rarely needed during normal operation\nsince unused Versions are eventually garbage collected.\nThe client can delete a Version only when all of the following conditions\nare met:\n - It is not the Current or Ramping Version for this Deployment.\n - It has no active pollers, i.e., none of the task queues in the\n Version have pollers.\n - It is not draining. This requirement can be ignored with the option\n --skip-drainage.\n \n```\ntemporal worker deployment version delete [options]\n```\n\nFor example, forcing to skip the drainage restriction:\n\n```\ntemporal worker deployment version delete \\\n --version YourDeploymentName.YourBuildID \\\n --skip-drainage \n```" + } + s.Command.Args = cobra.NoArgs + s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") + s.Command.Flags().BoolVar(&s.SkipDrainage, "skip-drainage", false, "Ignore the deletion requirement of not draining.") + s.DeploymentVersionOptions.buildFlags(cctx, s.Command.Flags()) + s.Command.Run = func(c *cobra.Command, args []string) { + if err := s.run(cctx, args); err != nil { + cctx.Options.Fail(err) + } + } + return &s +} + +type TemporalWorkerDeploymentVersionDescribeCommand struct { + Parent *TemporalWorkerDeploymentVersionCommand + Command cobra.Command + DeploymentVersionOptions +} + +func NewTemporalWorkerDeploymentVersionDescribeCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentVersionCommand) *TemporalWorkerDeploymentVersionDescribeCommand { + var s TemporalWorkerDeploymentVersionDescribeCommand + s.Parent = parent + s.Command.DisableFlagsInUseLine = true + s.Command.Use = "describe [flags]" + s.Command.Short = "Show properties of a Worker Deployment Version" + if hasHighlighting { + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribes properties of a Worker Deployment Version, such as the task \nqueues polled by workers in this Deployment Version, or drainage\ninformation required to safely decommission workers, or user-provided\nmetadata, or its creation/modification time.\n\n\x1b[1mtemporal worker deployment version describe [options]\x1b[0m\n\nFor example, to describe a deployment version in a deployment\n\x1b[1mYourDeploymentName\x1b[0m, with Build ID \x1b[1mYourBuildID\x1b[0m, and in the default\nnamespace:\n\n\x1b[1mtemporal worker deployment version describe \\\n --version YourDeploymentName.YourBuildID\x1b[0m" + } else { + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribes properties of a Worker Deployment Version, such as the task \nqueues polled by workers in this Deployment Version, or drainage\ninformation required to safely decommission workers, or user-provided\nmetadata, or its creation/modification time.\n\n```\ntemporal worker deployment version describe [options]\n```\n\nFor example, to describe a deployment version in a deployment\n`YourDeploymentName`, with Build ID `YourBuildID`, and in the default\nnamespace:\n\n```\ntemporal worker deployment version describe \\\n --version YourDeploymentName.YourBuildID\n```" + } + s.Command.Args = cobra.NoArgs + s.DeploymentVersionOptions.buildFlags(cctx, s.Command.Flags()) + s.Command.Run = func(c *cobra.Command, args []string) { + if err := s.run(cctx, args); err != nil { + cctx.Options.Fail(err) + } + } + return &s +} + +type TemporalWorkerDeploymentVersionSetCurrentCommand struct { + Parent *TemporalWorkerDeploymentVersionCommand + Command cobra.Command + DeploymentVersionOptions + DeploymentName string + Identity string + IgnoreMissingTaskQueues bool + Yes bool +} + +func NewTemporalWorkerDeploymentVersionSetCurrentCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentVersionCommand) *TemporalWorkerDeploymentVersionSetCurrentCommand { + var s TemporalWorkerDeploymentVersionSetCurrentCommand s.Parent = parent s.Command.DisableFlagsInUseLine = true s.Command.Use = "set-current [flags]" - s.Command.Short = "Change the current Worker Deployment" + s.Command.Short = "Make a Worker Deployment Version Current for a Deployment" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSets the current Deployment for a given Deployment Series.\nWhen a Deployment is current, Workers of that Deployment will receive\ntasks from new Workflows and from existing AutoUpgrade Workflows that\nare running on this Deployment Series.\n\n\x1b[1mtemporal worker deployment set-current [options]\x1b[0m\n\nFor example:\n\n\x1b[1mtemporal worker deployment set-current \\\n --series-name YourDeploymentSeriesName \\\n --build-id YourDeploymentBuildId\x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSets the Current Version for a Deployment.\nWhen a Version is current, Workers of that Deployment Version will receive\ntasks from new Workflows and from existing AutoUpgrade Workflows that\nare running on this Deployment.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Version the request will fail. To override this protection use\n\x1b[1m--ignore-missing-task-queues\x1b[0m. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n\x1b[1mtemporal worker deployment version set-current [options]\x1b[0m\n\nFor example, to set the Current Version of a deployment\n\x1b[1mYourDeploymentName\x1b[0m, with a version with Build ID \x1b[1mYourBuildID\x1b[0m, and\nin the default namespace:\n\n\x1b[1mtemporal worker deployment version set-current \\\n --version YourDeploymentName.YourBuildID\x1b[0m" } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSets the current Deployment for a given Deployment Series.\nWhen a Deployment is current, Workers of that Deployment will receive\ntasks from new Workflows and from existing AutoUpgrade Workflows that\nare running on this Deployment Series.\n\n```\ntemporal worker deployment set-current [options]\n```\n\nFor example:\n\n```\ntemporal worker deployment set-current \\\n --series-name YourDeploymentSeriesName \\\n --build-id YourDeploymentBuildId\n```" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSets the Current Version for a Deployment.\nWhen a Version is current, Workers of that Deployment Version will receive\ntasks from new Workflows and from existing AutoUpgrade Workflows that\nare running on this Deployment.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Version the request will fail. To override this protection use\n`--ignore-missing-task-queues`. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n```\ntemporal worker deployment version set-current [options]\n```\n\nFor example, to set the Current Version of a deployment\n`YourDeploymentName`, with a version with Build ID `YourBuildID`, and\nin the default namespace:\n\n```\ntemporal worker deployment version set-current \\\n --version YourDeploymentName.YourBuildID\n```" } s.Command.Args = cobra.NoArgs - s.Command.Flags().StringArrayVar(&s.Metadata, "metadata", nil, "Set deployment metadata using `KEY=\"VALUE\"` pairs. Keys must be identifiers, and values must be JSON values. For example: 'YourKey={\"your\": \"value\"}'. Can be passed multiple times.") - s.DeploymentReferenceOptions.buildFlags(cctx, s.Command.Flags()) + s.Command.Flags().StringVar(&s.DeploymentName, "deployment-name", "", "Deployment name. Only needed when `--version` is `__unversioned__` or empty.") + s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") + s.Command.Flags().BoolVar(&s.IgnoreMissingTaskQueues, "ignore-missing-task-queues", false, "Override protection to accidentally remove task queues.") + s.Command.Flags().BoolVarP(&s.Yes, "yes", "y", false, "Don't prompt to confirm set Current Version.") + s.DeploymentVersionOptions.buildFlags(cctx, s.Command.Flags()) + s.Command.Run = func(c *cobra.Command, args []string) { + if err := s.run(cctx, args); err != nil { + cctx.Options.Fail(err) + } + } + return &s +} + +type TemporalWorkerDeploymentVersionSetRampingCommand struct { + Parent *TemporalWorkerDeploymentVersionCommand + Command cobra.Command + DeploymentVersionOptions + DeploymentName string + Percentage float32 + Delete bool + Identity string + IgnoreMissingTaskQueues bool + Yes bool +} + +func NewTemporalWorkerDeploymentVersionSetRampingCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentVersionCommand) *TemporalWorkerDeploymentVersionSetRampingCommand { + var s TemporalWorkerDeploymentVersionSetRampingCommand + s.Parent = parent + s.Command.DisableFlagsInUseLine = true + s.Command.Use = "set-ramping [flags]" + s.Command.Short = "Change Version Ramping settings for a Worker Deployment" + if hasHighlighting { + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSets the Ramping Version and Percentage for a Deployment.\n\nThe Ramping Version can be set to a fully-qualified Version of the form\n\x1b[1mYourDeploymentName.YourBuildID\x1b[0m, or set to \"__unversioned__\", a special\nvalue, which represents all the unversioned workers.\n\nThe Ramping Percentage is a float with values in the range [0, 100].\nA value of 100 does not make the Ramping Version Current, use\n\x1b[1mset-current\x1b[0m instead.\n\nTo remove a Ramping Version use the flag \x1b[1m--delete\x1b[0m and set Percentage\nto 0.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Ramping Version the request will fail. To override this protection use\n\x1b[1m--ignore-missing-task-queues\x1b[0m. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n\x1b[1mtemporal worker deployment version set-ramping [options]\x1b[0m\n\nFor example, to set the Ramping Version of a deployment\n\x1b[1mYourDeploymentName\x1b[0m, with a version with Build ID \x1b[1mYourBuildID\x1b[0m, with\n10 percent of tasks redirected to this version, and\nusing the default namespace:\n\n\x1b[1mtemporal worker deployment version set-ramping \\\n --version YourDeploymentName.YourBuildID\n --percentage 10.0\x1b[0m\n\nAnd to remove that ramping:\n \n\x1b[1mtemporal worker deployment version set-ramping \\\n --version YourDeploymentName.YourBuildID \\\n --percentage 0.0 \\\n --delete\x1b[0m " + } else { + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSets the Ramping Version and Percentage for a Deployment.\n\nThe Ramping Version can be set to a fully-qualified Version of the form\n`YourDeploymentName.YourBuildID`, or set to \"__unversioned__\", a special\nvalue, which represents all the unversioned workers.\n\nThe Ramping Percentage is a float with values in the range [0, 100].\nA value of 100 does not make the Ramping Version Current, use\n`set-current` instead.\n\nTo remove a Ramping Version use the flag `--delete` and set Percentage\nto 0.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Ramping Version the request will fail. To override this protection use\n`--ignore-missing-task-queues`. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n```\ntemporal worker deployment version set-ramping [options]\n```\n\nFor example, to set the Ramping Version of a deployment\n`YourDeploymentName`, with a version with Build ID `YourBuildID`, with\n10 percent of tasks redirected to this version, and\nusing the default namespace:\n\n```\ntemporal worker deployment version set-ramping \\\n --version YourDeploymentName.YourBuildID\n --percentage 10.0\n```\n\nAnd to remove that ramping:\n \n```\ntemporal worker deployment version set-ramping \\\n --version YourDeploymentName.YourBuildID \\\n --percentage 0.0 \\\n --delete\n``` " + } + s.Command.Args = cobra.NoArgs + s.Command.Flags().StringVar(&s.DeploymentName, "deployment-name", "", "Deployment name. Only needed when `--version` is `__unversioned__` or empty.") + s.Command.Flags().Float32Var(&s.Percentage, "percentage", 0, "Percentage of tasks redirected to the Ramping Version. Valid range [0,100]. Required.") + _ = cobra.MarkFlagRequired(s.Command.Flags(), "percentage") + s.Command.Flags().BoolVar(&s.Delete, "delete", false, "Delete the Ramping Version.") + s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") + s.Command.Flags().BoolVar(&s.IgnoreMissingTaskQueues, "ignore-missing-task-queues", false, "Override protection to accidentally remove task queues.") + s.Command.Flags().BoolVarP(&s.Yes, "yes", "y", false, "Don't prompt to confirm set Ramping Version.") + s.DeploymentVersionOptions.buildFlags(cctx, s.Command.Flags()) s.Command.Run = func(c *cobra.Command, args []string) { if err := s.run(cctx, args); err != nil { cctx.Options.Fail(err) diff --git a/temporalcli/commands.worker.deployment.go b/temporalcli/commands.worker.deployment.go index 45a44ec04..87476b110 100644 --- a/temporalcli/commands.worker.deployment.go +++ b/temporalcli/commands.worker.deployment.go @@ -6,84 +6,106 @@ import ( "github.com/fatih/color" "github.com/temporalio/cli/temporalcli/internal/printer" - "go.temporal.io/api/common/v1" "go.temporal.io/sdk/client" ) -type taskQueuesInfosRowType struct { - Name string `json:"name"` - Type string `json:"type"` - FirstPollerTime time.Time `json:"firstPollerTime"` +type versionSummariesRowType struct { + Version string `json:"version"` + DrainageStatus string `json:"drainageStatus"` + CreateTime time.Time `json:"createTime"` } -type deploymentType struct { - SeriesName string `json:"seriesName"` - BuildID string `json:"buildId"` +type formattedRoutingConfigType struct { + CurrentVersion string `json:"currentVersion"` + RampingVersion string `json:"rampingVersion"` + RampingVersionPercentage float32 `json:"rampingVersionPercentage"` + CurrentVersionChangedTime time.Time `json:"currentVersionChangedTime"` + RampingVersionChangedTime time.Time `json:"rampingVersionChangedTime"` + RampingVersionPercentageChangedTime time.Time `json:"rampingVersionPercentageChangedTime"` } -type formattedDeploymentInfoType struct { - Deployment deploymentType `json:"deployment"` - CreateTime time.Time `json:"createTime"` - IsCurrent bool `json:"isCurrent"` - TaskQueuesInfos []taskQueuesInfosRowType `json:"taskQueuesInfos,omitempty"` - Metadata map[string]*common.Payload `json:"metadata,omitempty"` +type formattedWorkerDeploymentInfoType struct { + Name string `json:"name"` + CreateTime time.Time `json:"createTime"` + LastModifierIdentity string `json:"lastModifierIdentity"` + RoutingConfig formattedRoutingConfigType `json:"routingConfig,omitempty"` + VersionSummaries []versionSummariesRowType `json:"versionSummaries,omitempty"` } -type formattedDeploymentReachabilityInfoType struct { - DeploymentInfo formattedDeploymentInfoType `json:"deploymentInfo"` - Reachability string `json:"reachability"` - LastUpdateTime time.Time `json:"lastUpdateTime"` +type formattedWorkerDeploymentListEntryType struct { + Name string + CreateTime time.Time + CurrentVersion string `cli:",cardOmitEmpty"` + RampingVersion string `cli:",cardOmitEmpty"` + RampingVersionPercentage float32 `cli:",cardOmitEmpty"` + CurrentVersionChangedTime time.Time `cli:",cardOmitEmpty"` + RampingVersionChangedTime time.Time `cli:",cardOmitEmpty"` + RampingVersionPercentageChangedTime time.Time `cli:",cardOmitEmpty"` } -type formattedDeploymentListEntryType struct { - SeriesName string - BuildID string - CreateTime time.Time - IsCurrent bool -} - -type formattedDualDeploymentInfoType struct { - Previous formattedDeploymentInfoType `json:"previous"` - Current formattedDeploymentInfoType `json:"current"` +func drainageStatusToStr(drainage client.WorkerDeploymentVersionDrainageStatus) (string, error) { + switch drainage { + case client.WorkerDeploymentVersionDrainageStatusUnspecified: + return "unspecified", nil + case client.WorkerDeploymentVersionDrainageStatusDraining: + return "draining", nil + case client.WorkerDeploymentVersionDrainageStatusDrained: + return "drained", nil + default: + return "", fmt.Errorf("unrecognized drainage status: %d", drainage) + } } -func formatTaskQueuesInfos(tqis []client.DeploymentTaskQueueInfo) ([]taskQueuesInfosRowType, error) { - var tqiRows []taskQueuesInfosRowType - for _, tqi := range tqis { - tqTypeStr, err := taskQueueTypeToStr(tqi.Type) +func formatVersionSummaries(vss []client.WorkerDeploymentVersionSummary) ([]versionSummariesRowType, error) { + var vsRows []versionSummariesRowType + for _, vs := range vss { + drainageStr, err := drainageStatusToStr(vs.DrainageStatus) if err != nil { - return tqiRows, err + return vsRows, err } - tqiRows = append(tqiRows, taskQueuesInfosRowType{ - Name: tqi.Name, - Type: tqTypeStr, - FirstPollerTime: tqi.FirstPollerTime, + vsRows = append(vsRows, versionSummariesRowType{ + Version: vs.Version, + CreateTime: vs.CreateTime, + DrainageStatus: drainageStr, }) } - return tqiRows, nil + return vsRows, nil } -func deploymentInfoToRows(deploymentInfo client.DeploymentInfo) (formattedDeploymentInfoType, error) { - tqi, err := formatTaskQueuesInfos(deploymentInfo.TaskQueuesInfos) +func formatRoutingConfig(rc client.WorkerDeploymentRoutingConfig) (formattedRoutingConfigType, error) { + return formattedRoutingConfigType{ + CurrentVersion: rc.CurrentVersion, + RampingVersion: rc.RampingVersion, + RampingVersionPercentage: rc.RampingVersionPercentage, + CurrentVersionChangedTime: rc.CurrentVersionChangedTime, + RampingVersionChangedTime: rc.RampingVersionChangedTime, + RampingVersionPercentageChangedTime: rc.RampingVersionPercentageChangedTime, + }, nil +} + +func workerDeploymentInfoToRows(deploymentInfo client.WorkerDeploymentInfo) (formattedWorkerDeploymentInfoType, error) { + vs, err := formatVersionSummaries(deploymentInfo.VersionSummaries) + if err != nil { + return formattedWorkerDeploymentInfoType{}, err + } + + rc, err := formatRoutingConfig(deploymentInfo.RoutingConfig) if err != nil { - return formattedDeploymentInfoType{}, err + return formattedWorkerDeploymentInfoType{}, err } - return formattedDeploymentInfoType{ - Deployment: deploymentType{ - SeriesName: deploymentInfo.Deployment.SeriesName, - BuildID: deploymentInfo.Deployment.BuildID, - }, - CreateTime: deploymentInfo.CreateTime, - IsCurrent: deploymentInfo.IsCurrent, - TaskQueuesInfos: tqi, - Metadata: deploymentInfo.Metadata, + return formattedWorkerDeploymentInfoType{ + Name: deploymentInfo.Name, + LastModifierIdentity: deploymentInfo.LastModifierIdentity, + CreateTime: deploymentInfo.CreateTime, + RoutingConfig: rc, + VersionSummaries: vs, }, nil } -func printDeploymentInfo(cctx *CommandContext, deploymentInfo client.DeploymentInfo, msg string) error { +func printWorkerDeploymentInfo(cctx *CommandContext, deploymentInfo client.WorkerDeploymentInfo, msg string) error { - fDeploymentInfo, err := deploymentInfoToRows(deploymentInfo) + fDeploymentInfo, err := workerDeploymentInfoToRows(deploymentInfo) if err != nil { return err } @@ -91,32 +113,40 @@ func printDeploymentInfo(cctx *CommandContext, deploymentInfo client.DeploymentI if !cctx.JSONOutput { cctx.Printer.Println(color.MagentaString(msg)) printMe := struct { - SeriesName string - BuildID string - CreateTime time.Time - IsCurrent bool - Metadata map[string]*common.Payload `cli:",cardOmitEmpty"` + Name string + CreateTime time.Time + LastModifierIdentity string `cli:",cardOmitEmpty"` + CurrentVersion string `cli:",cardOmitEmpty"` + RampingVersion string `cli:",cardOmitEmpty"` + RampingVersionPercentage float32 `cli:",cardOmitEmpty"` + CurrentVersionChangedTime time.Time `cli:",cardOmitEmpty"` + RampingVersionChangedTime time.Time `cli:",cardOmitEmpty"` + RampingVersionPercentageChangedTime time.Time `cli:",cardOmitEmpty"` }{ - SeriesName: deploymentInfo.Deployment.SeriesName, - BuildID: deploymentInfo.Deployment.BuildID, - CreateTime: deploymentInfo.CreateTime, - IsCurrent: deploymentInfo.IsCurrent, - Metadata: deploymentInfo.Metadata, + Name: deploymentInfo.Name, + CreateTime: deploymentInfo.CreateTime, + LastModifierIdentity: deploymentInfo.LastModifierIdentity, + CurrentVersion: deploymentInfo.RoutingConfig.CurrentVersion, + RampingVersion: deploymentInfo.RoutingConfig.RampingVersion, + RampingVersionPercentage: deploymentInfo.RoutingConfig.RampingVersionPercentage, + CurrentVersionChangedTime: deploymentInfo.RoutingConfig.CurrentVersionChangedTime, + RampingVersionChangedTime: deploymentInfo.RoutingConfig.RampingVersionChangedTime, + RampingVersionPercentageChangedTime: deploymentInfo.RoutingConfig.RampingVersionPercentageChangedTime, } err := cctx.Printer.PrintStructured(printMe, printer.StructuredOptions{}) if err != nil { return fmt.Errorf("displaying worker deployment info failed: %w", err) } - if len(deploymentInfo.TaskQueuesInfos) > 0 { + if len(deploymentInfo.VersionSummaries) > 0 { cctx.Printer.Println() - cctx.Printer.Println(color.MagentaString("Task Queues:")) + cctx.Printer.Println(color.MagentaString("Version Summaries:")) err := cctx.Printer.PrintStructured( - deploymentInfo.TaskQueuesInfos, + deploymentInfo.VersionSummaries, printer.StructuredOptions{Table: &printer.TableOptions{}}, ) if err != nil { - return fmt.Errorf("displaying task queues info failed: %w", err) + return fmt.Errorf("displaying version summaries failed: %w", err) } } @@ -127,153 +157,42 @@ func printDeploymentInfo(cctx *CommandContext, deploymentInfo client.DeploymentI return cctx.Printer.PrintStructured(fDeploymentInfo, printer.StructuredOptions{}) } -func deploymentReachabilityTypeToStr(reachabilityType client.DeploymentReachability) (string, error) { - switch reachabilityType { - case client.DeploymentReachabilityUnspecified: - return "unspecified", nil - case client.DeploymentReachabilityReachable: - return "reachable", nil - case client.DeploymentReachabilityClosedWorkflows: - return "closed", nil - case client.DeploymentReachabilityUnreachable: - return "unreachable", nil - default: - return "", fmt.Errorf("unrecognized deployment reachability type: %d", reachabilityType) - } -} - -func printDeploymentReachabilityInfo(cctx *CommandContext, reachability client.DeploymentReachabilityInfo) error { - fDeploymentInfo, err := deploymentInfoToRows(reachability.DeploymentInfo) - if err != nil { - return err - } - - rTypeStr, err := deploymentReachabilityTypeToStr(reachability.Reachability) +func (c *TemporalWorkerDeploymentDescribeCommand) run(cctx *CommandContext, args []string) error { + cl, err := c.Parent.Parent.ClientOptions.dialClient(cctx) if err != nil { return err } + defer cl.Close() - fReachabilityInfo := formattedDeploymentReachabilityInfoType{ - DeploymentInfo: fDeploymentInfo, - LastUpdateTime: reachability.LastUpdateTime, - Reachability: rTypeStr, - } - - if !cctx.JSONOutput { - err := printDeploymentInfo(cctx, reachability.DeploymentInfo, "Worker Deployment:") - if err != nil { - return err - } - - cctx.Printer.Println() - cctx.Printer.Println(color.MagentaString("Reachability:")) - printMe := struct { - LastUpdateTime time.Time - Reachability string - }{ - LastUpdateTime: fReachabilityInfo.LastUpdateTime, - Reachability: fReachabilityInfo.Reachability, - } - return cctx.Printer.PrintStructured(printMe, printer.StructuredOptions{}) - } - - // json output - return cctx.Printer.PrintStructured(fReachabilityInfo, printer.StructuredOptions{}) -} - -func printDeploymentSetCurrentResponse(cctx *CommandContext, response client.DeploymentSetCurrentResponse) error { - - if !cctx.JSONOutput { - err := printDeploymentInfo(cctx, response.Previous, "Previous Worker Deployment:") - if err != nil { - return fmt.Errorf("displaying previous worker deployment info failed: %w", err) - } - - err = printDeploymentInfo(cctx, response.Current, "Current Worker Deployment:") - if err != nil { - return fmt.Errorf("displaying current worker deployment info failed: %w", err) - } - - return nil - } - - previous, err := deploymentInfoToRows(response.Previous) + dHandle := cl.WorkerDeploymentClient().GetHandle(c.Name) + resp, err := dHandle.Describe(cctx, client.WorkerDeploymentDescribeOptions{}) if err != nil { - return fmt.Errorf("displaying previous worker deployment info failed: %w", err) + return fmt.Errorf("error describing worker deployment: %w", err) } - current, err := deploymentInfoToRows(response.Current) - if err != nil { - return fmt.Errorf("displaying current worker deployment info failed: %w", err) - } - - return cctx.Printer.PrintStructured(formattedDualDeploymentInfoType{ - Previous: previous, - Current: current, - }, printer.StructuredOptions{}) -} - -func (c *TemporalWorkerDeploymentDescribeCommand) run(cctx *CommandContext, args []string) error { - cl, err := c.Parent.Parent.ClientOptions.dialClient(cctx) + err = printWorkerDeploymentInfo(cctx, resp.Info, "Worker Deployment:") if err != nil { return err } - defer cl.Close() - - if c.ReportReachability { - // Expensive call, rate-limited by target method - resp, err := cl.DeploymentClient().GetReachability(cctx, client.DeploymentGetReachabilityOptions{ - Deployment: client.Deployment{ - SeriesName: c.SeriesName, - BuildID: c.BuildId, - }, - }) - if err != nil { - return fmt.Errorf("error describing worker deployment with reachability: %w", err) - } - - err = printDeploymentReachabilityInfo(cctx, resp) - if err != nil { - return err - } - } else { - resp, err := cl.DeploymentClient().Describe(cctx, client.DeploymentDescribeOptions{ - Deployment: client.Deployment{ - SeriesName: c.SeriesName, - BuildID: c.BuildId, - }, - }) - if err != nil { - return fmt.Errorf("error describing worker deployment: %w", err) - } - err = printDeploymentInfo(cctx, resp.DeploymentInfo, "Worker Deployment:") - if err != nil { - return err - } - - } return nil } -func (c *TemporalWorkerDeploymentGetCurrentCommand) run(cctx *CommandContext, args []string) error { +func (c *TemporalWorkerDeploymentDeleteCommand) run(cctx *CommandContext, args []string) error { cl, err := c.Parent.Parent.ClientOptions.dialClient(cctx) if err != nil { return err } defer cl.Close() - resp, err := cl.DeploymentClient().GetCurrent(cctx, client.DeploymentGetCurrentOptions{ - SeriesName: c.SeriesName, + _, err = cl.WorkerDeploymentClient().Delete(cctx, client.WorkerDeploymentDeleteOptions{ + Name: c.Name, + Identity: c.Identity, }) if err != nil { - return fmt.Errorf("error getting the current deployment: %w", err) - } - - err = printDeploymentInfo(cctx, resp.DeploymentInfo, "Current Worker Deployment:") - if err != nil { - return err + return fmt.Errorf("error deleting worker deployment: %w", err) } + cctx.Printer.Println("Successfully deleted worker deployment") return nil } @@ -284,9 +203,7 @@ func (c *TemporalWorkerDeploymentListCommand) run(cctx *CommandContext, args []s } defer cl.Close() - res, err := cl.DeploymentClient().List(cctx, client.DeploymentListOptions{ - SeriesName: c.SeriesName, - }) + res, err := cl.WorkerDeploymentClient().List(cctx, client.WorkerDeploymentListOptions{}) if err != nil { return err } @@ -300,31 +217,36 @@ func (c *TemporalWorkerDeploymentListCommand) run(cctx *CommandContext, args []s } // make artificial "pages" so we get better aligned columns - page := make([]*formattedDeploymentListEntryType, 0, 100) + page := make([]*formattedWorkerDeploymentListEntryType, 0, 100) for res.HasNext() { entry, err := res.Next() if err != nil { return err } - listEntry := formattedDeploymentInfoType{ - Deployment: deploymentType{ - SeriesName: entry.Deployment.SeriesName, - BuildID: entry.Deployment.BuildID, - }, - CreateTime: entry.CreateTime, - IsCurrent: entry.IsCurrent, + rc, err := formatRoutingConfig(entry.RoutingConfig) + if err != nil { + return err + } + listEntry := formattedWorkerDeploymentInfoType{ + Name: entry.Name, + CreateTime: entry.CreateTime, + RoutingConfig: rc, } if cctx.JSONOutput { // For JSON dump one line of JSON per deployment _ = cctx.Printer.PrintStructured(listEntry, printer.StructuredOptions{}) } else { // For non-JSON, we are doing a table for each page - page = append(page, &formattedDeploymentListEntryType{ - SeriesName: listEntry.Deployment.SeriesName, - BuildID: listEntry.Deployment.BuildID, - CreateTime: listEntry.CreateTime, - IsCurrent: listEntry.IsCurrent, + page = append(page, &formattedWorkerDeploymentListEntryType{ + Name: listEntry.Name, + CreateTime: listEntry.CreateTime, + CurrentVersion: listEntry.RoutingConfig.CurrentVersion, + RampingVersion: listEntry.RoutingConfig.RampingVersion, + RampingVersionPercentage: listEntry.RoutingConfig.RampingVersionPercentage, + CurrentVersionChangedTime: listEntry.RoutingConfig.CurrentVersionChangedTime, + RampingVersionChangedTime: listEntry.RoutingConfig.RampingVersionChangedTime, + RampingVersionPercentageChangedTime: listEntry.RoutingConfig.RampingVersionPercentageChangedTime, }) if len(page) == cap(page) { _ = cctx.Printer.PrintStructured(page, printTableOpts) @@ -341,37 +263,3 @@ func (c *TemporalWorkerDeploymentListCommand) run(cctx *CommandContext, args []s return nil } - -func (c *TemporalWorkerDeploymentSetCurrentCommand) run(cctx *CommandContext, args []string) error { - cl, err := c.Parent.Parent.dialClient(cctx) - if err != nil { - return err - } - defer cl.Close() - - metadata, err := stringKeysJSONValues(c.Metadata, false) - if err != nil { - return fmt.Errorf("invalid metadata values: %w", err) - } - - resp, err := cl.DeploymentClient().SetCurrent(cctx, client.DeploymentSetCurrentOptions{ - Deployment: client.Deployment{ - SeriesName: c.SeriesName, - BuildID: c.BuildId, - }, - MetadataUpdate: client.DeploymentMetadataUpdate{ - UpsertEntries: metadata, - }, - }) - if err != nil { - return fmt.Errorf("error setting the current worker deployment: %w", err) - } - - err = printDeploymentSetCurrentResponse(cctx, resp) - if err != nil { - return err - } - - cctx.Printer.Println("Successfully setting the current worker deployment") - return nil -} diff --git a/temporalcli/commands.worker.deployment.version.go b/temporalcli/commands.worker.deployment.version.go new file mode 100644 index 000000000..4f4732946 --- /dev/null +++ b/temporalcli/commands.worker.deployment.version.go @@ -0,0 +1,352 @@ +package temporalcli + +import ( + "fmt" + "strings" + "time" + + "github.com/fatih/color" + "github.com/temporalio/cli/temporalcli/internal/printer" + "go.temporal.io/api/common/v1" + "go.temporal.io/sdk/client" +) + +type formattedDrainageInfo struct { + DrainageStatus string `json:"drainageStatus"` + LastChangedTime time.Time `json:"lastChangedTime"` + LastCheckedTime time.Time `json:"lastCheckedTime"` +} + +type formattedTaskQueueInfoRowType struct { + Name string `json:"name"` + Type string `json:"type"` +} + +type formattedWorkerDeploymentVersionInfoType struct { + Version string `json:"version"` + CreateTime time.Time `json:"createTime"` + RoutingChangedTime time.Time `json:"routingChangedTime"` + CurrentSinceTime time.Time `json:"currentSinceTime"` + RampingSinceTime time.Time `json:"rampingSinceTime"` + RampPercentage float32 `json:"rampPercentage"` + DrainageInfo formattedDrainageInfo `json:"drainageInfo,omitempty"` + TaskQueuesInfos []formattedTaskQueueInfoRowType `json:"taskQueuesInfos,omitempty"` + Metadata map[string]*common.Payload `json:"metadata,omitempty"` +} + +func extractDeploymentName(version string, deploymentName string, failNonQualified bool) (string, error) { + if version == "" || version == "__unversioned__" { + if failNonQualified { + return "", fmt.Errorf( + "invalid deployment version type for this operation, use a fully-qualified version", + ) + } + if deploymentName == "" { + return "", fmt.Errorf( + "specify the deployment name with `--deployment-name` with a non-fully-qualified version", + ) + } + return deploymentName, nil + } + splitVersion := strings.SplitN(version, ".", 2) + if len(splitVersion) != 2 { + return "", fmt.Errorf( + "invalid format for worker deployment version %v, not YourDeploymentName.YourBuildID", + version, + ) + } + return splitVersion[0], nil +} + +func formatDrainageInfo(drainageInfo *client.WorkerDeploymentVersionDrainageInfo) (formattedDrainageInfo, error) { + if drainageInfo == nil { + return formattedDrainageInfo{}, nil + } + + drainageStr, err := drainageStatusToStr(drainageInfo.DrainageStatus) + if err != nil { + return formattedDrainageInfo{}, err + } + + return formattedDrainageInfo{ + DrainageStatus: drainageStr, + LastChangedTime: drainageInfo.LastChangedTime, + LastCheckedTime: drainageInfo.LastCheckedTime, + }, nil +} + +func formatTaskQueuesInfos(tqis []client.WorkerDeploymentTaskQueueInfo) ([]formattedTaskQueueInfoRowType, error) { + var tqiRows []formattedTaskQueueInfoRowType + for _, tqi := range tqis { + tqTypeStr, err := taskQueueTypeToStr(tqi.Type) + if err != nil { + return tqiRows, err + } + tqiRows = append(tqiRows, formattedTaskQueueInfoRowType{ + Name: tqi.Name, + Type: tqTypeStr, + }) + } + return tqiRows, nil +} + +func workerDeploymentVersionInfoToRows(deploymentInfo client.WorkerDeploymentVersionInfo) (formattedWorkerDeploymentVersionInfoType, error) { + tqi, err := formatTaskQueuesInfos(deploymentInfo.TaskQueuesInfos) + if err != nil { + return formattedWorkerDeploymentVersionInfoType{}, err + } + + drainage, err := formatDrainageInfo(deploymentInfo.DrainageInfo) + if err != nil { + return formattedWorkerDeploymentVersionInfoType{}, err + } + + return formattedWorkerDeploymentVersionInfoType{ + Version: deploymentInfo.Version, + CreateTime: deploymentInfo.CreateTime, + RoutingChangedTime: deploymentInfo.RoutingChangedTime, + CurrentSinceTime: deploymentInfo.CurrentSinceTime, + RampingSinceTime: deploymentInfo.RampingSinceTime, + RampPercentage: deploymentInfo.RampPercentage, + DrainageInfo: drainage, + TaskQueuesInfos: tqi, + Metadata: deploymentInfo.Metadata, + }, nil +} + +func printWorkerDeploymentVersionInfo(cctx *CommandContext, deploymentInfo client.WorkerDeploymentVersionInfo, msg string) error { + fDeploymentInfo, err := workerDeploymentVersionInfoToRows(deploymentInfo) + if err != nil { + return err + } + + if !cctx.JSONOutput { + cctx.Printer.Println(color.MagentaString(msg)) + var drainageStr string + var drainageLastChangedTime time.Time + var drainageLastCheckedTime time.Time + if deploymentInfo.DrainageInfo != nil { + drainageStr, err = drainageStatusToStr(deploymentInfo.DrainageInfo.DrainageStatus) + if err != nil { + return err + } + drainageLastChangedTime = deploymentInfo.DrainageInfo.LastChangedTime + drainageLastCheckedTime = deploymentInfo.DrainageInfo.LastCheckedTime + } + + printMe := struct { + Version string + CreateTime time.Time + RoutingChangedTime time.Time `cli:",cardOmitEmpty"` + CurrentSinceTime time.Time `cli:",cardOmitEmpty"` + RampingSinceTime time.Time `cli:",cardOmitEmpty"` + RampPercentage float32 + DrainageStatus string `cli:",cardOmitEmpty"` + DrainageLastChangedTime time.Time `cli:",cardOmitEmpty"` + DrainageLastCheckedTime time.Time `cli:",cardOmitEmpty"` + }{ + Version: deploymentInfo.Version, + CreateTime: deploymentInfo.CreateTime, + RoutingChangedTime: deploymentInfo.RoutingChangedTime, + CurrentSinceTime: deploymentInfo.CurrentSinceTime, + RampingSinceTime: deploymentInfo.RampingSinceTime, + RampPercentage: deploymentInfo.RampPercentage, + DrainageStatus: drainageStr, + DrainageLastChangedTime: drainageLastChangedTime, + DrainageLastCheckedTime: drainageLastCheckedTime, + } + err := cctx.Printer.PrintStructured(printMe, printer.StructuredOptions{}) + if err != nil { + return fmt.Errorf("displaying worker deployment version info failed: %w", err) + } + + if len(deploymentInfo.TaskQueuesInfos) > 0 { + cctx.Printer.Println() + cctx.Printer.Println(color.MagentaString("Task Queues:")) + err := cctx.Printer.PrintStructured( + deploymentInfo.TaskQueuesInfos, + printer.StructuredOptions{Table: &printer.TableOptions{}}, + ) + if err != nil { + return fmt.Errorf("displaying task queues failed: %w", err) + } + } + + // TODO(antlai-temporal): Print metadata + + return nil + } + + // json output + return cctx.Printer.PrintStructured(fDeploymentInfo, printer.StructuredOptions{}) +} + +type getDeploymentConflictTokenOptions struct { + safeMode bool + safeModeMessage string + deploymentName string +} + +func (c *TemporalWorkerDeploymentVersionCommand) getConflictToken(cctx *CommandContext, options *getDeploymentConflictTokenOptions) ([]byte, error) { + cl, err := c.Parent.Parent.ClientOptions.dialClient(cctx) + if err != nil { + return nil, err + } + defer cl.Close() + + dHandle := cl.WorkerDeploymentClient().GetHandle(options.deploymentName) + + resp, err := dHandle.Describe(cctx, client.WorkerDeploymentDescribeOptions{}) + if err != nil { + return nil, fmt.Errorf("unable to get deployment conflict token: %w", err) + } + + if options.safeMode { + // duplicate `cctx.promptYes` check to avoid printing current rules with json + if cctx.JSONOutput { + return nil, fmt.Errorf("must bypass prompts when using JSON output") + } + err = printWorkerDeploymentInfo(cctx, resp.Info, "Worker Deployment Before Update:") + if err != nil { + return nil, fmt.Errorf("displaying deployment failed: %w", err) + } + + yes, err := cctx.promptYes( + fmt.Sprintf("Continue with set %v? y/N", options.safeModeMessage), false) + if err != nil { + return nil, err + } else if !yes { + return nil, fmt.Errorf("user denied confirmation") + } + } + + return resp.ConflictToken, nil +} + +func (c *TemporalWorkerDeploymentVersionDeleteCommand) run(cctx *CommandContext, args []string) error { + cl, err := c.Parent.Parent.Parent.ClientOptions.dialClient(cctx) + if err != nil { + return err + } + defer cl.Close() + + name, err := extractDeploymentName(c.Version, "", true) + if err != nil { + return err + } + + dHandle := cl.WorkerDeploymentClient().GetHandle(name) + _, err = dHandle.DeleteVersion(cctx, client.WorkerDeploymentDeleteVersionOptions{ + Version: c.Version, + SkipDrainage: c.SkipDrainage, + Identity: c.Identity, + }) + if err != nil { + return fmt.Errorf("error deleting worker deployment version: %w", err) + } + + cctx.Printer.Println("Successfully deleted worker deployment version") + return nil +} + +func (c *TemporalWorkerDeploymentVersionDescribeCommand) run(cctx *CommandContext, args []string) error { + cl, err := c.Parent.Parent.Parent.ClientOptions.dialClient(cctx) + if err != nil { + return err + } + defer cl.Close() + + name, err := extractDeploymentName(c.Version, "", true) + if err != nil { + return err + } + + dHandle := cl.WorkerDeploymentClient().GetHandle(name) + + resp, err := dHandle.DescribeVersion(cctx, client.WorkerDeploymentDescribeVersionOptions{ + Version: c.Version, + }) + if err != nil { + return fmt.Errorf("error describing worker deployment version: %w", err) + } + + err = printWorkerDeploymentVersionInfo(cctx, resp.Info, "Worker Deployment Version:") + if err != nil { + return err + } + + return nil +} + +func (c *TemporalWorkerDeploymentVersionSetCurrentCommand) run(cctx *CommandContext, args []string) error { + cl, err := c.Parent.Parent.Parent.dialClient(cctx) + if err != nil { + return err + } + defer cl.Close() + + name, err := extractDeploymentName(c.Version, c.DeploymentName, false) + if err != nil { + return err + } + + token, err := c.Parent.getConflictToken(cctx, &getDeploymentConflictTokenOptions{ + safeMode: !c.Yes, + safeModeMessage: "Current", + deploymentName: name, + }) + if err != nil { + return err + } + + dHandle := cl.WorkerDeploymentClient().GetHandle(name) + _, err = dHandle.SetCurrentVersion(cctx, client.WorkerDeploymentSetCurrentVersionOptions{ + Version: c.Version, + Identity: c.Identity, + IgnoreMissingTaskQueues: c.IgnoreMissingTaskQueues, + ConflictToken: token, + }) + if err != nil { + return fmt.Errorf("error setting the current worker deployment version: %w", err) + } + + cctx.Printer.Println("Successfully setting the current worker deployment version") + return nil +} + +func (c *TemporalWorkerDeploymentVersionSetRampingCommand) run(cctx *CommandContext, args []string) error { + cl, err := c.Parent.Parent.Parent.ClientOptions.dialClient(cctx) + if err != nil { + return err + } + defer cl.Close() + + name, err := extractDeploymentName(c.Version, c.DeploymentName, false) + if err != nil { + return err + } + + token, err := c.Parent.getConflictToken(cctx, &getDeploymentConflictTokenOptions{ + safeMode: !c.Yes, + safeModeMessage: "Ramping", + deploymentName: name, + }) + if err != nil { + return err + } + + dHandle := cl.WorkerDeploymentClient().GetHandle(name) + _, err = dHandle.SetRampingVersion(cctx, client.WorkerDeploymentSetRampingVersionOptions{ + Version: c.Version, + Percentage: c.Percentage, + ConflictToken: token, + Identity: c.Identity, + IgnoreMissingTaskQueues: c.IgnoreMissingTaskQueues, + }) + if err != nil { + return fmt.Errorf("error setting the ramping worker deployment version: %w", err) + } + + cctx.Printer.Println("Successfully setting the ramping worker deployment version") + return nil +} diff --git a/temporalcli/commands.worker.deployment_test.go b/temporalcli/commands.worker.deployment_test.go index 08c61309d..c19eb5978 100644 --- a/temporalcli/commands.worker.deployment_test.go +++ b/temporalcli/commands.worker.deployment_test.go @@ -1,12 +1,8 @@ package temporalcli_test import ( - "encoding/base64" - "encoding/json" - "sort" "time" - "github.com/google/uuid" "go.temporal.io/api/common/v1" ) @@ -41,6 +37,7 @@ type jsonDeploymentListEntryType struct { IsCurrent bool `json:"isCurrent"` } +/* func (s *SharedServerSuite) TestDeployment_Set_Current() { seriesName := uuid.NewString() buildId := uuid.NewString() @@ -189,3 +186,4 @@ func (s *SharedServerSuite) TestDeployment_Describe_Reachability() { s.True(jsonOut.DeploymentInfo.IsCurrent) s.Equal(jsonOut.Reachability, "reachable") } +*/ diff --git a/temporalcli/commands.workflow_test.go b/temporalcli/commands.workflow_test.go index 8ece140c6..0f7a629bc 100644 --- a/temporalcli/commands.workflow_test.go +++ b/temporalcli/commands.workflow_test.go @@ -11,12 +11,9 @@ import ( "time" "github.com/google/uuid" - "github.com/stretchr/testify/assert" - "github.com/temporalio/cli/temporalcli" "go.temporal.io/api/enums/v1" "go.temporal.io/api/workflowservice/v1" "go.temporal.io/sdk/client" - "go.temporal.io/sdk/worker" "go.temporal.io/sdk/workflow" "google.golang.org/grpc" ) @@ -426,55 +423,137 @@ func (s *SharedServerSuite) TestWorkflow_Cancel_SingleWorkflowSuccess() { s.Error(workflow.ErrCanceled, run.Get(s.Context, nil)) } -func (s *SharedServerSuite) TestWorkflow_Batch_Update_Options_Versioning_Override() { - buildId1 := uuid.NewString() - buildId2 := uuid.NewString() - seriesName := uuid.NewString() - // Workflow that waits to be canceled. - waitingWorkflow := func(ctx workflow.Context) error { - ctx.Done().Receive(ctx, nil) - return ctx.Err() +/* + func (s *SharedServerSuite) TestWorkflow_Batch_Update_Options_Versioning_Override() { + buildId1 := uuid.NewString() + buildId2 := uuid.NewString() + seriesName := uuid.NewString() + // Workflow that waits to be canceled. + waitingWorkflow := func(ctx workflow.Context) error { + ctx.Done().Receive(ctx, nil) + return ctx.Err() + } + w := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + BuildID: buildId1, + UseBuildIDForVersioning: true, + DeploymentOptions: worker.DeploymentOptions{ + DeploymentSeriesName: seriesName, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + }, + }, + Workflows: []any{waitingWorkflow}, + }) + defer w.Stop() + + res := s.Execute( + "worker", "deployment", "set-current", + "--address", s.Address(), + "--series-name", seriesName, + "--build-id", buildId1, + ) + s.NoError(res.Err) + + // Start workflows + numWorkflows := 5 + runs := make([]client.WorkflowRun, numWorkflows) + searchAttr := "keyword-" + uuid.NewString() + for i := range runs { + run, err := s.Client.ExecuteWorkflow( + s.Context, + client.StartWorkflowOptions{ + TaskQueue: w.Options.TaskQueue, + SearchAttributes: map[string]any{"CustomKeywordField": searchAttr}, + }, + waitingWorkflow, + ) + s.NoError(err) + runs[i] = run + } + + s.EventuallyWithT(func(t *assert.CollectT) { + for _, run := range runs { + res = s.Execute( + "workflow", "describe", + "--address", s.Address(), + "-w", run.GetID(), + ) + assert.NoError(t, res.Err) + assert.Contains(t, res.Stdout.String(), buildId1) + assert.Contains(t, res.Stdout.String(), "Pinned") + } + }, 30*time.Second, 100*time.Millisecond) + + s.CommandHarness.Stdin.WriteString("y\n") + res = s.Execute( + "workflow", "update-options", + "--address", s.Address(), + "--query", "CustomKeywordField = '"+searchAttr+"'", + "--versioning-override-behavior", "pinned", + "--versioning-override-series-name", seriesName, + "--versioning-override-build-id", buildId2, + ) + s.NoError(res.Err) + + s.EventuallyWithT(func(t *assert.CollectT) { + for _, run := range runs { + // json + res = s.Execute( + "workflow", "describe", + "--address", s.Address(), + "-w", run.GetID(), + "--output", "json", + ) + assert.NoError(t, res.Err) + + var jsonResp workflowservice.DescribeWorkflowExecutionResponse + assert.NoError(t, temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonResp, true)) + versioningInfo := jsonResp.WorkflowExecutionInfo.VersioningInfo + assert.NotNil(t, versioningInfo.VersioningOverride) + assert.Equal(t, seriesName+"."+buildId2, versioningInfo.VersioningOverride.PinnedVersion) + } + }, 30*time.Second, 100*time.Millisecond) } - w := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ - Worker: worker.Options{ - BuildID: buildId1, - UseBuildIDForVersioning: true, - DeploymentOptions: worker.DeploymentOptions{ - DeploymentSeriesName: seriesName, - DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + + func (s *SharedServerSuite) TestWorkflow_Update_Options_Versioning_Override() { + buildId1 := uuid.NewString() + buildId2 := uuid.NewString() + seriesName := uuid.NewString() + // Workflow that waits to be canceled. + waitingWorkflow := func(ctx workflow.Context) error { + ctx.Done().Receive(ctx, nil) + return ctx.Err() + } + w := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + BuildID: buildId1, + UseBuildIDForVersioning: true, + DeploymentOptions: worker.DeploymentOptions{ + DeploymentSeriesName: seriesName, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + }, }, - }, - Workflows: []any{waitingWorkflow}, - }) - defer w.Stop() + Workflows: []any{waitingWorkflow}, + }) + defer w.Stop() - res := s.Execute( - "worker", "deployment", "set-current", - "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId1, - ) - s.NoError(res.Err) + res := s.Execute( + "worker", "deployment", "set-current", + "--address", s.Address(), + "--series-name", seriesName, + "--build-id", buildId1, + ) + s.NoError(res.Err) - // Start workflows - numWorkflows := 5 - runs := make([]client.WorkflowRun, numWorkflows) - searchAttr := "keyword-" + uuid.NewString() - for i := range runs { + // Start the workflow and wait until the operation is started. run, err := s.Client.ExecuteWorkflow( s.Context, - client.StartWorkflowOptions{ - TaskQueue: w.Options.TaskQueue, - SearchAttributes: map[string]any{"CustomKeywordField": searchAttr}, - }, + client.StartWorkflowOptions{TaskQueue: w.Options.TaskQueue}, waitingWorkflow, ) s.NoError(err) - runs[i] = run - } - s.EventuallyWithT(func(t *assert.CollectT) { - for _, run := range runs { + s.EventuallyWithT(func(t *assert.CollectT) { res = s.Execute( "workflow", "describe", "--address", s.Address(), @@ -483,136 +562,55 @@ func (s *SharedServerSuite) TestWorkflow_Batch_Update_Options_Versioning_Overrid assert.NoError(t, res.Err) assert.Contains(t, res.Stdout.String(), buildId1) assert.Contains(t, res.Stdout.String(), "Pinned") - } - }, 30*time.Second, 100*time.Millisecond) - - s.CommandHarness.Stdin.WriteString("y\n") - res = s.Execute( - "workflow", "update-options", - "--address", s.Address(), - "--query", "CustomKeywordField = '"+searchAttr+"'", - "--versioning-override-behavior", "pinned", - "--versioning-override-series-name", seriesName, - "--versioning-override-build-id", buildId2, - ) - s.NoError(res.Err) - - s.EventuallyWithT(func(t *assert.CollectT) { - for _, run := range runs { - // json - res = s.Execute( - "workflow", "describe", - "--address", s.Address(), - "-w", run.GetID(), - "--output", "json", - ) - assert.NoError(t, res.Err) - - var jsonResp workflowservice.DescribeWorkflowExecutionResponse - assert.NoError(t, temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonResp, true)) - versioningInfo := jsonResp.WorkflowExecutionInfo.VersioningInfo - assert.NotNil(t, versioningInfo.VersioningOverride) - assert.Equal(t, seriesName+"."+buildId2, versioningInfo.VersioningOverride.PinnedVersion) - } - }, 30*time.Second, 100*time.Millisecond) -} + }, 30*time.Second, 100*time.Millisecond) -func (s *SharedServerSuite) TestWorkflow_Update_Options_Versioning_Override() { - buildId1 := uuid.NewString() - buildId2 := uuid.NewString() - seriesName := uuid.NewString() - // Workflow that waits to be canceled. - waitingWorkflow := func(ctx workflow.Context) error { - ctx.Done().Receive(ctx, nil) - return ctx.Err() - } - w := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ - Worker: worker.Options{ - BuildID: buildId1, - UseBuildIDForVersioning: true, - DeploymentOptions: worker.DeploymentOptions{ - DeploymentSeriesName: seriesName, - DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, - }, - }, - Workflows: []any{waitingWorkflow}, - }) - defer w.Stop() - - res := s.Execute( - "worker", "deployment", "set-current", - "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId1, - ) - s.NoError(res.Err) - - // Start the workflow and wait until the operation is started. - run, err := s.Client.ExecuteWorkflow( - s.Context, - client.StartWorkflowOptions{TaskQueue: w.Options.TaskQueue}, - waitingWorkflow, - ) - s.NoError(err) + res = s.Execute( + "workflow", "update-options", + "--address", s.Address(), + "-w", run.GetID(), + "--versioning-override-behavior", "pinned", + "--versioning-override-series-name", seriesName, + "--versioning-override-build-id", buildId2, + ) + s.NoError(res.Err) - s.EventuallyWithT(func(t *assert.CollectT) { res = s.Execute( "workflow", "describe", "--address", s.Address(), "-w", run.GetID(), ) - assert.NoError(t, res.Err) - assert.Contains(t, res.Stdout.String(), buildId1) - assert.Contains(t, res.Stdout.String(), "Pinned") - }, 30*time.Second, 100*time.Millisecond) - - res = s.Execute( - "workflow", "update-options", - "--address", s.Address(), - "-w", run.GetID(), - "--versioning-override-behavior", "pinned", - "--versioning-override-series-name", seriesName, - "--versioning-override-build-id", buildId2, - ) - s.NoError(res.Err) - - res = s.Execute( - "workflow", "describe", - "--address", s.Address(), - "-w", run.GetID(), - ) - s.NoError(res.Err) - - s.ContainsOnSameLine(res.Stdout.String(), "OverrideBehavior", "Pinned") - // TODO(antlai-temporal): replace by new Deployment API - // These fields are deprecated, and not populated in latest server - // s.ContainsOnSameLine(res.Stdout.String(), "OverrideDeploymentSeriesName", seriesName) - // s.ContainsOnSameLine(res.Stdout.String(), "OverrideDeploymentBuildID", buildId2) + s.NoError(res.Err) - // remove override - res = s.Execute( - "workflow", "update-options", - "--address", s.Address(), - "-w", run.GetID(), - "--versioning-override-behavior", "unspecified", - ) - s.NoError(res.Err) + s.ContainsOnSameLine(res.Stdout.String(), "OverrideBehavior", "Pinned") + // TODO(antlai-temporal): replace by new Deployment API + // These fields are deprecated, and not populated in latest server + // s.ContainsOnSameLine(res.Stdout.String(), "OverrideDeploymentSeriesName", seriesName) + // s.ContainsOnSameLine(res.Stdout.String(), "OverrideDeploymentBuildID", buildId2) - // json - res = s.Execute( - "workflow", "describe", - "--address", s.Address(), - "-w", run.GetID(), - "--output", "json", - ) - s.NoError(res.Err) + // remove override + res = s.Execute( + "workflow", "update-options", + "--address", s.Address(), + "-w", run.GetID(), + "--versioning-override-behavior", "unspecified", + ) + s.NoError(res.Err) - var jsonResp workflowservice.DescribeWorkflowExecutionResponse - s.NoError(temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonResp, true)) - versioningInfo := jsonResp.WorkflowExecutionInfo.VersioningInfo - s.Nil(versioningInfo.VersioningOverride) -} + // json + res = s.Execute( + "workflow", "describe", + "--address", s.Address(), + "-w", run.GetID(), + "--output", "json", + ) + s.NoError(res.Err) + var jsonResp workflowservice.DescribeWorkflowExecutionResponse + s.NoError(temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonResp, true)) + versioningInfo := jsonResp.WorkflowExecutionInfo.VersioningInfo + s.Nil(versioningInfo.VersioningOverride) + } +*/ func (s *SharedServerSuite) TestWorkflow_Update_Execute() { workflowUpdateTest{ s: s, diff --git a/temporalcli/commands.workflow_view_test.go b/temporalcli/commands.workflow_view_test.go index 8ad7a80cc..b209bcfff 100644 --- a/temporalcli/commands.workflow_view_test.go +++ b/temporalcli/commands.workflow_view_test.go @@ -13,7 +13,6 @@ import ( "github.com/google/uuid" "github.com/nexus-rpc/sdk-go/nexus" - "github.com/stretchr/testify/assert" "github.com/temporalio/cli/temporalcli" "go.temporal.io/api/enums/v1" nexuspb "go.temporal.io/api/nexus/v1" @@ -22,7 +21,6 @@ import ( "go.temporal.io/sdk/client" "go.temporal.io/sdk/temporal" "go.temporal.io/sdk/temporalnexus" - "go.temporal.io/sdk/worker" "go.temporal.io/sdk/workflow" ) @@ -548,83 +546,84 @@ func (s *SharedServerSuite) TestWorkflow_Count() { s.Contains(out, `{"groupValues":["Completed"],"count":"3"}`) } -func (s *SharedServerSuite) TestWorkflow_Describe_Deployment() { - buildId := uuid.NewString() - seriesName := uuid.NewString() - // Workflow that waits to be canceled. - waitingWorkflow := func(ctx workflow.Context) error { - ctx.Done().Receive(ctx, nil) - return ctx.Err() - } - w := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ - Worker: worker.Options{ - BuildID: buildId, - UseBuildIDForVersioning: true, - DeploymentOptions: worker.DeploymentOptions{ - DeploymentSeriesName: seriesName, - DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, +/* + func (s *SharedServerSuite) TestWorkflow_Describe_Deployment() { + buildId := uuid.NewString() + seriesName := uuid.NewString() + // Workflow that waits to be canceled. + waitingWorkflow := func(ctx workflow.Context) error { + ctx.Done().Receive(ctx, nil) + return ctx.Err() + } + w := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + BuildID: buildId, + UseBuildIDForVersioning: true, + DeploymentOptions: worker.DeploymentOptions{ + DeploymentSeriesName: seriesName, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + }, }, - }, - Workflows: []any{waitingWorkflow}, - }) - defer w.Stop() + Workflows: []any{waitingWorkflow}, + }) + defer w.Stop() - res := s.Execute( - "worker", "deployment", "set-current", - "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId, - ) - s.NoError(res.Err) + res := s.Execute( + "worker", "deployment", "set-current", + "--address", s.Address(), + "--series-name", seriesName, + "--build-id", buildId, + ) + s.NoError(res.Err) - // Start the workflow and wait until the operation is started. - run, err := s.Client.ExecuteWorkflow( - s.Context, - client.StartWorkflowOptions{TaskQueue: w.Options.TaskQueue}, - waitingWorkflow, - ) - s.NoError(err) + // Start the workflow and wait until the operation is started. + run, err := s.Client.ExecuteWorkflow( + s.Context, + client.StartWorkflowOptions{TaskQueue: w.Options.TaskQueue}, + waitingWorkflow, + ) + s.NoError(err) - s.EventuallyWithT(func(t *assert.CollectT) { + s.EventuallyWithT(func(t *assert.CollectT) { + res = s.Execute( + "workflow", "describe", + "--address", s.Address(), + "-w", run.GetID(), + ) + assert.NoError(t, res.Err) + assert.Contains(t, res.Stdout.String(), buildId) + assert.Contains(t, res.Stdout.String(), "Pinned") + }, 30*time.Second, 100*time.Millisecond) + + out := res.Stdout.String() + s.ContainsOnSameLine(out, "Behavior", "Pinned") + // TODO(antlai-temporal): replace by new Deployment API + // These fields are deprecated, and not populated in latest server + //s.ContainsOnSameLine(out, "DeploymentBuildID", buildId) + //s.ContainsOnSameLine(out, "DeploymentSeriesName", seriesName) + s.ContainsOnSameLine(out, "OverrideBehavior", "Unspecified") + + // json res = s.Execute( "workflow", "describe", "--address", s.Address(), "-w", run.GetID(), + "--output", "json", ) - assert.NoError(t, res.Err) - assert.Contains(t, res.Stdout.String(), buildId) - assert.Contains(t, res.Stdout.String(), "Pinned") - }, 30*time.Second, 100*time.Millisecond) - - out := res.Stdout.String() - s.ContainsOnSameLine(out, "Behavior", "Pinned") - // TODO(antlai-temporal): replace by new Deployment API - // These fields are deprecated, and not populated in latest server - //s.ContainsOnSameLine(out, "DeploymentBuildID", buildId) - //s.ContainsOnSameLine(out, "DeploymentSeriesName", seriesName) - s.ContainsOnSameLine(out, "OverrideBehavior", "Unspecified") - - // json - res = s.Execute( - "workflow", "describe", - "--address", s.Address(), - "-w", run.GetID(), - "--output", "json", - ) - s.NoError(res.Err) - - var jsonResp workflowservice.DescribeWorkflowExecutionResponse - s.NoError(temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonResp, true)) - versioningInfo := jsonResp.WorkflowExecutionInfo.VersioningInfo - s.Equal("Pinned", versioningInfo.Behavior.String()) - // TODO(antlai-temporal): replace by new Deployment API - // These fields are deprecated, and not populated in latest server - // s.Equal(buildId, versioningInfo.Deployment.BuildId) - // s.Equal(seriesName, versioningInfo.Deployment.SeriesName) - s.Nil(versioningInfo.VersioningOverride) - s.Nil(versioningInfo.DeploymentTransition) -} - + s.NoError(res.Err) + + var jsonResp workflowservice.DescribeWorkflowExecutionResponse + s.NoError(temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonResp, true)) + versioningInfo := jsonResp.WorkflowExecutionInfo.VersioningInfo + s.Equal("Pinned", versioningInfo.Behavior.String()) + // TODO(antlai-temporal): replace by new Deployment API + // These fields are deprecated, and not populated in latest server + // s.Equal(buildId, versioningInfo.Deployment.BuildId) + // s.Equal(seriesName, versioningInfo.Deployment.SeriesName) + s.Nil(versioningInfo.VersioningOverride) + s.Nil(versioningInfo.DeploymentTransition) + } +*/ func (s *SharedServerSuite) TestWorkflow_Describe_NexusOperationAndCallback() { handlerWorkflowID := uuid.NewString() endpointName := validEndpointName(s.T()) diff --git a/temporalcli/commandsgen/commands.yml b/temporalcli/commandsgen/commands.yml index 249930ab3..889525719 100644 --- a/temporalcli/commandsgen/commands.yml +++ b/temporalcli/commandsgen/commands.yml @@ -672,7 +672,7 @@ commands: - worker deployment - name: temporal worker deployment - summary: Describe, list, and operate on Worker Deployments + summary: Describe, list, and operate on Worker Deployments and Versions description: | +---------------------------------------------------------------------+ | CAUTION: Worker Deployment is experimental. Deployment commands are | @@ -693,14 +693,14 @@ commands: docs: description-header: >- Temporal Deployment commands enable operations on Worker Deployments, - such as describe, list, set-current, and get-current, simplifying + such as describe, list, delete, and version, simplifying versioning and management of workers. keywords: - worker deployment - worker deployment describe - worker deployment list - - worker deployment get-current - - worker deployment set-current + - worker deployment delete + - worker deployment version - name: temporal worker deployment describe summary: Show properties of a Worker Deployment @@ -710,59 +710,54 @@ commands: | subject to change. | +---------------------------------------------------------------------+ - Describes properties of a Worker Deployment, such as whether it is - current, the non-empty list of its task queues, custom metadata if - present, and reachability status when requested. + Describes properties of a Worker Deployment, such as the versions + associated with it, routing information of new or existing tasks + executed by this deployment, or its creation time. ``` temporal worker deployment describe [options] ``` - For example, to also include reachability information: + For example, to describe a deployment `YourDeploymentName` in the default + namespace: ``` temporal worker deployment describe \ - --series-name YourDeploymentSeriesName \ - --build-id YourDeploymentBuildId \ - --report-reachability + --name YourDeploymentName ``` option-sets: - - deployment-reference - options: - - name: report-reachability - type: bool - description: | - Include reachability information of a Worker Deployment. + - deployment-name - - name: temporal worker deployment get-current - summary: Show the current Worker Deployment + - name: temporal worker deployment delete + summary: Deletes a Worker Deployment description: | +---------------------------------------------------------------------+ | CAUTION: Worker Deployment is experimental. Deployment commands are | | subject to change. | +---------------------------------------------------------------------+ - Gets the current Worker Deployment for a Deployment Series Name. - When a Deployment is current, Workers of that Deployment will receive - tasks from new Workflows and from existing AutoUpgrade Workflows that - are running on this Deployment Series. + Removes a Worker Deployment given its Deployment Name. + A Deployment can only be deleted if it has no Version in it. ``` - temporal worker deployment get-current [options] + temporal worker deployment delete [options] ``` - For example: + For example, setting the user identity that removed the deployment: ``` - temporal worker deployment get-current \ - --series-name YourDeploymentSeriesName + temporal worker deployment delete \ + --name YourDeploymentName \ + --identity YourIdentity + ``` + option-sets: + - deployment-name options: - - name: series-name + - name: identity type: string - description: Series Name for the current Worker Deployment. - required: true - + description: Identity of the user submitting this request. + - name: temporal worker deployment list summary: Enumerate Worker Deployments in the client's namespace description: | @@ -771,60 +766,255 @@ commands: | subject to change. | +---------------------------------------------------------------------+ - List existing Worker Deployments in the client's namespace, optionally - filtering them by Deployment Series Name. - + List existing Worker Deployments in the client's namespace. ``` temporal worker deployment list [options] ``` - For example, adding an optional filter: + For example, listing Deployments in YourDeploymentNamespace: ``` temporal worker deployment list \ - --series-name YourDeploymentSeriesName + --namespace YourDeploymentNamespace ``` - options: - - name: series-name - type: string - description: Series Name to filter Worker Deployments. - - name: temporal worker deployment set-current - summary: Change the current Worker Deployment + - name: temporal worker deployment version + summary: Describe, delete, setCurrent, or setRamping, a Deployment Version description: | +---------------------------------------------------------------------+ | CAUTION: Worker deployment is experimental. Deployment commands are | | subject to change. | +---------------------------------------------------------------------+ - Sets the current Deployment for a given Deployment Series. - When a Deployment is current, Workers of that Deployment will receive + Deployment commands to operate on Worker Deployment Versions: + + ``` + temporal worker deployment version [command] [options] + ``` + + For example, using a fully qualified Version identifier that + concatenates the Deployment Name with the Build ID using the + reserved separator ".": + + ``` + temporal worker deployment version setCurrent \ + --version YourDeploymentName.YourBuildID + ``` + Sets the current Deployment Version for a given Deployment. + When a Version is current, Workers of that Deployment Version will receive tasks from new Workflows and from existing AutoUpgrade Workflows that - are running on this Deployment Series. + are running on this Deployment. + docs: + description-header: >- + Temporal Deployment Version commands enable operations on Worker + Deployments Versions, + such as describe, delete, set as Current, set as Ramping, simplifying + versioning and management of workers. + keywords: + - worker deployment version + - worker deployment version describe + - worker deployment version set-current + - worker deployment version set-ramping + - worker deployment version delete + - worker deployment version update-metadata + + - name: temporal worker deployment version describe + summary: Show properties of a Worker Deployment Version + description: | + +---------------------------------------------------------------------+ + | CAUTION: Worker Deployment is experimental. Deployment commands are | + | subject to change. | + +---------------------------------------------------------------------+ + + Describes properties of a Worker Deployment Version, such as the task + queues polled by workers in this Deployment Version, or drainage + information required to safely decommission workers, or user-provided + metadata, or its creation/modification time. ``` - temporal worker deployment set-current [options] + temporal worker deployment version describe [options] ``` - For example: + For example, to describe a deployment version in a deployment + `YourDeploymentName`, with Build ID `YourBuildID`, and in the default + namespace: + + ``` + temporal worker deployment version describe \ + --version YourDeploymentName.YourBuildID + ``` + option-sets: + - deployment-version + + - name: temporal worker deployment version delete + summary: Deletes a Worker Deployment Version + description: | + +---------------------------------------------------------------------+ + | CAUTION: Worker Deployment is experimental. Deployment commands are | + | subject to change. | + +---------------------------------------------------------------------+ + + Removes a Worker Deployment Version given its fully-qualified identifier. + This is rarely needed during normal operation + since unused Versions are eventually garbage collected. + The client can delete a Version only when all of the following conditions + are met: + - It is not the Current or Ramping Version for this Deployment. + - It has no active pollers, i.e., none of the task queues in the + Version have pollers. + - It is not draining. This requirement can be ignored with the option + --skip-drainage. + + ``` + temporal worker deployment version delete [options] + ``` + + For example, forcing to skip the drainage restriction: ``` - temporal worker deployment set-current \ - --series-name YourDeploymentSeriesName \ - --build-id YourDeploymentBuildId + temporal worker deployment version delete \ + --version YourDeploymentName.YourBuildID \ + --skip-drainage ``` option-sets: - - deployment-reference + - deployment-version options: - - name: metadata - type: string[] + - name: identity + type: string + description: Identity of the user submitting this request. + - name: skip-drainage + type: bool + description: Ignore the deletion requirement of not draining. + + - name: temporal worker deployment version set-current + summary: Make a Worker Deployment Version Current for a Deployment + description: | + +---------------------------------------------------------------------+ + | CAUTION: Worker Deployment is experimental. Deployment commands are | + | subject to change. | + +---------------------------------------------------------------------+ + + Sets the Current Version for a Deployment. + When a Version is current, Workers of that Deployment Version will receive + tasks from new Workflows and from existing AutoUpgrade Workflows that + are running on this Deployment. + + If not all the expected Task Queues are being polled by Workers in the + new Version the request will fail. To override this protection use + `--ignore-missing-task-queues`. Note that this would ignore task queues + in a deployment that are not yet discovered, leading to inconsistent task + queue configuration. + + ``` + temporal worker deployment version set-current [options] + ``` + + For example, to set the Current Version of a deployment + `YourDeploymentName`, with a version with Build ID `YourBuildID`, and + in the default namespace: + + ``` + temporal worker deployment version set-current \ + --version YourDeploymentName.YourBuildID + ``` + option-sets: + - deployment-version + options: + - name: deployment-name + type: string description: | - Set deployment metadata using `KEY="VALUE"` pairs. - Keys must be identifiers, and values must be JSON values. - For example: 'YourKey={"your": "value"}'. - Can be passed multiple times. + Deployment name. + Only needed when `--version` is `__unversioned__` or empty. + - name: identity + type: string + description: Identity of the user submitting this request. + - name: ignore-missing-task-queues + type: bool + description: Override protection to accidentally remove task queues. + - name: yes + short: y + type: bool + description: Don't prompt to confirm set Current Version. + + - name: temporal worker deployment version set-ramping + summary: Change Version Ramping settings for a Worker Deployment + description: | + +---------------------------------------------------------------------+ + | CAUTION: Worker Deployment is experimental. Deployment commands are | + | subject to change. | + +---------------------------------------------------------------------+ + + Sets the Ramping Version and Percentage for a Deployment. + + The Ramping Version can be set to a fully-qualified Version of the form + `YourDeploymentName.YourBuildID`, or set to "__unversioned__", a special + value, which represents all the unversioned workers. + + The Ramping Percentage is a float with values in the range [0, 100]. + A value of 100 does not make the Ramping Version Current, use + `set-current` instead. + + To remove a Ramping Version use the flag `--delete` and set Percentage + to 0. + + If not all the expected Task Queues are being polled by Workers in the + new Ramping Version the request will fail. To override this protection use + `--ignore-missing-task-queues`. Note that this would ignore task queues + in a deployment that are not yet discovered, leading to inconsistent task + queue configuration. + + ``` + temporal worker deployment version set-ramping [options] + ``` + For example, to set the Ramping Version of a deployment + `YourDeploymentName`, with a version with Build ID `YourBuildID`, with + 10 percent of tasks redirected to this version, and + using the default namespace: + + ``` + temporal worker deployment version set-ramping \ + --version YourDeploymentName.YourBuildID + --percentage 10.0 + ``` + + And to remove that ramping: + + ``` + temporal worker deployment version set-ramping \ + --version YourDeploymentName.YourBuildID \ + --percentage 0.0 \ + --delete + ``` + option-sets: + - deployment-version + options: + - name: deployment-name + type: string + description: | + Deployment name. + Only needed when `--version` is `__unversioned__` or empty. + - name: percentage + type: float + required: true + description: | + Percentage of tasks redirected to the Ramping Version. + Valid range [0,100]. + - name: delete + type: bool + description: Delete the Ramping Version. + - name: identity + type: string + description: Identity of the user submitting this request. + - name: ignore-missing-task-queues + type: bool + description: Override protection to accidentally remove task queues. + - name: yes + short: y + type: bool + description: Don't prompt to confirm set Ramping Version. + - name: temporal env summary: Manage environments description: | @@ -3608,6 +3798,24 @@ option-sets: short: r description: Run ID. + - name: deployment-name + options: + - name: name + type: string + short: d + description: Name for a Worker Deployment. + required: true + + - name: deployment-version + options: + - name: version + type: string + short: v + description: | + Fully-qualified name for a Worker Deployment Version. + Use the format `YourDeploymentName.YourBuildID`. + required: true + - name: deployment-reference options: - name: series-name From d737ff156e68e1fc9bf8eb983233bef4bd2ffd12 Mon Sep 17 00:00:00 2001 From: Antonio Lain Date: Tue, 25 Feb 2025 21:27:24 -0800 Subject: [PATCH 2/2] Full deployment api --- go.mod | 52 +- go.sum | 125 +++-- temporalcli/commands.gen.go | 225 ++++---- temporalcli/commands.worker.deployment.go | 434 ++++++++++++++- .../commands.worker.deployment.version.go | 352 ------------ .../commands.worker.deployment_test.go | 511 +++++++++++++++--- temporalcli/commands.workflow.go | 35 +- temporalcli/commands.workflow_test.go | 336 +++++++----- temporalcli/commands.workflow_view.go | 26 +- temporalcli/commands.workflow_view_test.go | 142 ++--- temporalcli/commands_test.go | 1 + temporalcli/commandsgen/commands.yml | 223 ++++---- 12 files changed, 1459 insertions(+), 1003 deletions(-) delete mode 100644 temporalcli/commands.worker.deployment.version.go diff --git a/go.mod b/go.mod index 51da57606..f21f0d56d 100644 --- a/go.mod +++ b/go.mod @@ -9,28 +9,28 @@ require ( github.com/fatih/color v1.18.0 github.com/google/uuid v1.6.0 github.com/mattn/go-isatty v0.0.20 - github.com/nexus-rpc/sdk-go v0.2.0 + github.com/nexus-rpc/sdk-go v0.3.0 github.com/olekukonko/tablewriter v0.0.5 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.6 github.com/stretchr/testify v1.10.0 - github.com/temporalio/ui-server/v2 v2.35.0 - go.temporal.io/api v1.44.1 - go.temporal.io/sdk v1.32.2-0.20250219024739-0c6b17c4eef4 - go.temporal.io/server v1.27.0-128.4 + github.com/temporalio/ui-server/v2 v2.36.0 + go.temporal.io/api v1.45.0 + go.temporal.io/sdk v1.33.0 + go.temporal.io/server v1.27.0-127.0.0.20250226023855-64a2e8cb4a17 google.golang.org/grpc v1.70.0 google.golang.org/protobuf v1.36.5 gopkg.in/yaml.v3 v3.0.1 ) require ( - cel.dev/expr v0.19.2 // indirect - cloud.google.com/go v0.118.1 // indirect + cel.dev/expr v0.20.0 // indirect + cloud.google.com/go v0.118.2 // indirect cloud.google.com/go/auth v0.14.1 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect cloud.google.com/go/compute/metadata v0.6.0 // indirect - cloud.google.com/go/iam v1.3.1 // indirect - cloud.google.com/go/monitoring v1.23.0 // indirect + cloud.google.com/go/iam v1.4.0 // indirect + cloud.google.com/go/monitoring v1.24.0 // indirect cloud.google.com/go/storage v1.50.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.26.0 // indirect @@ -53,10 +53,10 @@ require ( github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/go-jose/go-jose/v4 v4.0.4 // indirect + github.com/go-jose/go-jose/v4 v4.0.5 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-sql-driver/mysql v1.8.1 // indirect + github.com/go-sql-driver/mysql v1.9.0 // indirect github.com/gocql/gocql v1.7.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect @@ -70,7 +70,7 @@ require ( github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/securecookie v1.1.2 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -81,7 +81,7 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmoiron/sqlx v1.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/klauspost/compress v1.17.11 // indirect + github.com/klauspost/compress v1.18.0 // indirect github.com/labstack/echo/v4 v4.9.1 // indirect github.com/labstack/gommon v0.4.0 // indirect github.com/lib/pq v1.10.9 // indirect @@ -97,7 +97,7 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.20.5 // indirect + github.com/prometheus/client_golang v1.21.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect @@ -138,18 +138,18 @@ require ( go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.32.0 // indirect - golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/oauth2 v0.25.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/text v0.21.0 // indirect - golang.org/x/time v0.9.0 // indirect - google.golang.org/api v0.219.0 // indirect - google.golang.org/genproto v0.0.0-20250127172529-29210b9bc287 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250127172529-29210b9bc287 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 // indirect + golang.org/x/crypto v0.33.0 // indirect + golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa // indirect + golang.org/x/net v0.35.0 // indirect + golang.org/x/oauth2 v0.26.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/text v0.22.0 // indirect + golang.org/x/time v0.10.0 // indirect + google.golang.org/api v0.222.0 // indirect + google.golang.org/genproto v0.0.0-20250218202821-56aae31c358a // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/validator.v2 v2.0.1 // indirect diff --git a/go.sum b/go.sum index 5c9f471e7..4fb819a10 100644 --- a/go.sum +++ b/go.sum @@ -1,22 +1,22 @@ -cel.dev/expr v0.19.2 h1:V354PbqIXr9IQdwy4SYA4xa0HXaWq1BUPAGzugBY5V4= -cel.dev/expr v0.19.2/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +cel.dev/expr v0.20.0 h1:OunBvVCfvpWlt4dN7zg3FM6TDkzOePe1+foGJ9AXeeI= +cel.dev/expr v0.20.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.118.1 h1:b8RATMcrK9A4BH0rj8yQupPXp+aP+cJ0l6H7V9osV1E= -cloud.google.com/go v0.118.1/go.mod h1:CFO4UPEPi8oV21xoezZCrd3d81K4fFkDTEJu4R8K+9M= +cloud.google.com/go v0.118.2 h1:bKXO7RXMFDkniAAvvuMrAPtQ/VHrs9e7J5UT3yrGdTY= +cloud.google.com/go v0.118.2/go.mod h1:CFO4UPEPi8oV21xoezZCrd3d81K4fFkDTEJu4R8K+9M= cloud.google.com/go/auth v0.14.1 h1:AwoJbzUdxA/whv1qj3TLKwh3XX5sikny2fc40wUl+h0= cloud.google.com/go/auth v0.14.1/go.mod h1:4JHUxlGXisL0AW8kXPtUF6ztuOksyfUQNFjfsOCXkPM= cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M= cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc= cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= -cloud.google.com/go/iam v1.3.1 h1:KFf8SaT71yYq+sQtRISn90Gyhyf4X8RGgeAVC8XGf3E= -cloud.google.com/go/iam v1.3.1/go.mod h1:3wMtuyT4NcbnYNPLMBzYRFiEfjKfJlLVLrisE7bwm34= +cloud.google.com/go/iam v1.4.0 h1:ZNfy/TYfn2uh/ukvhp783WhnbVluqf/tzOaqVUPlIPA= +cloud.google.com/go/iam v1.4.0/go.mod h1:gMBgqPaERlriaOV0CUl//XUzDhSfXevn4OEUbg6VRs4= cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc= cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA= cloud.google.com/go/longrunning v0.6.4 h1:3tyw9rO3E2XVXzSApn1gyEEnH2K9SynNQjMlBi3uHLg= cloud.google.com/go/longrunning v0.6.4/go.mod h1:ttZpLCe6e7EXvn9OxpBRx7kZEB0efv8yBO6YnVMfhJs= -cloud.google.com/go/monitoring v1.23.0 h1:M3nXww2gn9oZ/qWN2bZ35CjolnVHM3qnSbu6srCPgjk= -cloud.google.com/go/monitoring v1.23.0/go.mod h1:034NnlQPDzrQ64G2Gavhl0LUHZs9H3rRmhtnp7jiJgg= +cloud.google.com/go/monitoring v1.24.0 h1:csSKiCJ+WVRgNkRzzz3BPoGjFhjPY23ZTcaenToJxMM= +cloud.google.com/go/monitoring v1.24.0/go.mod h1:Bd1PRK5bmQBQNnuGwHBfUamAV1ys9049oEPHnn4pcsc= cloud.google.com/go/storage v1.50.0 h1:3TbVkzTooBvnZsk7WaAQfOsNrdoM8QHusXA1cpk6QJs= cloud.google.com/go/storage v1.50.0/go.mod h1:l7XeiD//vx5lfqE3RavfmU9yvk5Pp0Zhcv482poyafY= cloud.google.com/go/trace v1.11.3 h1:c+I4YFjxRQjvAhRmSsmjpASUKq88chOX854ied0K/pE= @@ -109,11 +109,11 @@ github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/go-faker/faker/v4 v4.5.0 h1:ARzAY2XoOL9tOUK+KSecUQzyXQsUaZHefjyF8x6YFHc= -github.com/go-faker/faker/v4 v4.5.0/go.mod h1:p3oq1GRjG2PZ7yqeFFfQI20Xm61DoBDlCA8RiSyZ48M= +github.com/go-faker/faker/v4 v4.6.0 h1:6aOPzNptRiDwD14HuAnEtlTa+D1IfFuEHO8+vEFwjTs= +github.com/go-faker/faker/v4 v4.6.0/go.mod h1:ZmrHuVtTTm2Em9e0Du6CJ9CADaLEzGXW62z1YqFH0m0= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= -github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= +github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= +github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -121,8 +121,9 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/go-sql-driver/mysql v1.9.0 h1:Y0zIbQXhQKmQgTp44Y1dp3wTXcn804QoTptLZT1vtvo= +github.com/go-sql-driver/mysql v1.9.0/go.mod h1:pDetrLJeA3oMujJuvXc8RJoasr589B6A9fwzD3QMrqw= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gocql/gocql v1.7.0 h1:O+7U7/1gSN7QTEAaMEsJc1Oq2QHXvCWoF3DFK9HDHus= github.com/gocql/gocql v1.7.0/go.mod h1:vnlvXyFZeLBF0Wy+RS8hrOdbn0UWsWtdg07XJnFxZ+4= @@ -156,8 +157,8 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= -github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= -github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20250208200701-d0013a598941 h1:43XjGa6toxLpeksjcxs1jIoIyr+vUfOqY2c6HB4bpoc= +github.com/google/pprof v0.0.0-20250208200701-d0013a598941/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= @@ -174,8 +175,8 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0 h1:VD1gqscl4nYs1YxVuSdemTrSgTKrwOWDK0FVFMqm+Cg= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0/go.mod h1:4EgsQoS4TOhJizV+JTFg40qx1Ofh3XmXEQNBpgvNT40= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= @@ -203,8 +204,8 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= -github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -241,8 +242,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= -github.com/nexus-rpc/sdk-go v0.2.0 h1:NKMkfTTQDEkbnP46/oB7cV7Ml25Wk+9w7lOyeYJQLAc= -github.com/nexus-rpc/sdk-go v0.2.0/go.mod h1:TpfkM2Cw0Rlk9drGkoiSMpFqflKTiQLWUNyKJjF8mKQ= +github.com/nexus-rpc/sdk-go v0.3.0 h1:Y3B0kLYbMhd4C2u00kcYajvmOrfozEtTV/nHSnV57jA= +github.com/nexus-rpc/sdk-go v0.3.0/go.mod h1:TpfkM2Cw0Rlk9drGkoiSMpFqflKTiQLWUNyKJjF8mKQ= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= @@ -263,8 +264,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prashantv/protectmem v0.0.0-20171002184600-e20412882b3a h1:AA9vgIBDjMHPC2McaGPojgV2dcI78ZC0TLNhYCXEKH8= github.com/prashantv/protectmem v0.0.0-20171002184600-e20412882b3a/go.mod h1:lzZQ3Noex5pfAy7mkAeCjcBDteYU85uWWnJ/y6gKU8k= -github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= -github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA= +github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= @@ -318,8 +319,8 @@ github.com/temporalio/sqlparser v0.0.0-20231115171017-f4060bcfa6cb/go.mod h1:143 github.com/temporalio/tchannel-go v1.22.1-0.20220818200552-1be8d8cffa5b/go.mod h1:c+V9Z/ZgkzAdyGvHrvC5AsXgN+M9Qwey04cBdKYzV7U= github.com/temporalio/tchannel-go v1.22.1-0.20240528171429-1db37fdea938 h1:sEJGhmDo+0FaPWM6f0v8Tjia0H5pR6/Baj6+kS78B+M= github.com/temporalio/tchannel-go v1.22.1-0.20240528171429-1db37fdea938/go.mod h1:ezRQRwu9KQXy8Wuuv1aaFFxoCNz5CeNbVOOkh3xctbY= -github.com/temporalio/ui-server/v2 v2.35.0 h1:9msJGma2dEiwI+nI3iU7TfpnmgRCQv+R8Yd8JWqurC4= -github.com/temporalio/ui-server/v2 v2.35.0/go.mod h1:suM9z9+8208achw/6ZWd3/mF4k9x567mIBAg10S5lf4= +github.com/temporalio/ui-server/v2 v2.36.0 h1:U9ZKCEfnW7a7I0axhOPaOIDeeF+i09K3v1OHeiXCSkQ= +github.com/temporalio/ui-server/v2 v2.36.0/go.mod h1:1v+2UefCW9DSTskDbmrXcyhR+r+m2XdvDU1IwBAwDmE= github.com/twmb/murmur3 v1.1.8 h1:8Yt9taO/WN3l08xErzjeschgZU2QSrwm1kclYq+0aRg= github.com/twmb/murmur3 v1.1.8/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= github.com/uber-common/bark v1.0.0/go.mod h1:g0ZuPcD7XiExKHynr93Q742G/sbrdVQkghrqLGOoFuY= @@ -370,14 +371,12 @@ go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= -go.temporal.io/api v1.44.1 h1:sb5Hq08AB0WtYvfLJMiWmHzxjqs2b+6Jmzg4c8IOeng= -go.temporal.io/api v1.44.1/go.mod h1:1WwYUMo6lao8yl0371xWUm13paHExN5ATYT/B7QtFis= -go.temporal.io/sdk v1.32.1 h1:slA8prhdFr4lxpsTcRusWVitD/cGjELfKUh0mBj73SU= -go.temporal.io/sdk v1.32.1/go.mod h1:8U8H7rF9u4Hyb4Ry9yiEls5716DHPNvVITPNkgWUwE8= -go.temporal.io/sdk v1.32.2-0.20250219024739-0c6b17c4eef4 h1:3IIf8PkvJTLdTG4KHhUGHOlXANny9DyJbw58AQAeIxo= -go.temporal.io/sdk v1.32.2-0.20250219024739-0c6b17c4eef4/go.mod h1:XC1GMz3ETAROeV4BrFBXeCJEOEujfRb29xNB2uhXbZY= -go.temporal.io/server v1.27.0-128.4 h1:K3N4AMhEot0/E4eXA7hnYu+D/vC4UTF2cilVbxKqd8o= -go.temporal.io/server v1.27.0-128.4/go.mod h1:YgN/yuBArvm7q5VEk2SXY+cGTTvDbt5AyH34DvEd3so= +go.temporal.io/api v1.45.0 h1:2FZ3eUoOYjavBaQi3/V93MBl99Nq1ifFRjrRwT3MeC8= +go.temporal.io/api v1.45.0/go.mod h1:iaxoP/9OXMJcQkETTECfwYq4cw/bj4nwov8b3ZLVnXM= +go.temporal.io/sdk v1.33.0 h1:T91UzeRdlHTiMGgpygsItOH9+VSkg+M/mG85PqNjdog= +go.temporal.io/sdk v1.33.0/go.mod h1:WwCmJZLy7zabz3ar5NRAQEygsdP8tgR9sDjISSHuWZw= +go.temporal.io/server v1.27.0-127.0.0.20250226023855-64a2e8cb4a17 h1:HGNLkRp18RIdYQIi9H3UwE1S+t8kVUuoNG7R6YMfhVM= +go.temporal.io/server v1.27.0-127.0.0.20250226023855-64a2e8cb4a17/go.mod h1:srmZuuEFsechItNt7XSU2yrlUIf7cJjaN7M7/qtyP+g= go.temporal.io/version v0.3.0 h1:dMrei9l9NyHt8nG6EB8vAwDLLTwx2SvRyucCSumAiig= go.temporal.io/version v0.3.0/go.mod h1:UA9S8/1LaKYae6TyD9NaPMJTZb911JcbqghI2CBSP78= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -409,16 +408,16 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c h1:KL/ZBHXgKGVmuZBZ01Lt57yE5ws8ZPSkkihmEyq7FXc= -golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= +golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4= +golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -434,8 +433,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= -golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= +golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -450,11 +449,11 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= -golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE= +golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -463,8 +462,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -488,8 +487,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -502,10 +501,10 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= -golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= +golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -524,8 +523,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= -golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= +golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= +golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -534,19 +533,19 @@ gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJ gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -google.golang.org/api v0.219.0 h1:nnKIvxKs/06jWawp2liznTBnMRQBEPpGo7I+oEypTX0= -google.golang.org/api v0.219.0/go.mod h1:K6OmjGm+NtLrIkHxv1U3a0qIf/0JOvAHd5O/6AoyKYE= +google.golang.org/api v0.222.0 h1:Aiewy7BKLCuq6cUCeOUrsAlzjXPqBkEeQ/iwGHVQa/4= +google.golang.org/api v0.222.0/go.mod h1:efZia3nXpWELrwMlN5vyQrD4GmJN1Vw0x68Et3r+a9c= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20250127172529-29210b9bc287 h1:WoUI1G0DQ648FKvSl756SKxHQR/bI+y4HyyIQfxMWI8= -google.golang.org/genproto v0.0.0-20250127172529-29210b9bc287/go.mod h1:wkQ2Aj/xvshAUDtO/JHvu9y+AaN9cqs28QuSVSHtZSY= -google.golang.org/genproto/googleapis/api v0.0.0-20250127172529-29210b9bc287 h1:A2ni10G3UlplFrWdCDJTl7D7mJ7GSRm37S+PDimaKRw= -google.golang.org/genproto/googleapis/api v0.0.0-20250127172529-29210b9bc287/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 h1:J1H9f+LEdWAfHcez/4cvaVBox7cOYT+IU6rgqj5x++8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= +google.golang.org/genproto v0.0.0-20250218202821-56aae31c358a h1:Xx6e5r1AOINOgm2ZuzvwDueGlOOml4PKBUry8jqyS6U= +google.golang.org/genproto v0.0.0-20250218202821-56aae31c358a/go.mod h1:Cmg1ztsSOnOsWxOiPTOUX8gegyHg5xADRncIHdtec8U= +google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a h1:nwKuGPlUAt+aR+pcrkfFRrTU1BVrSmYyYMxYbUIVHr0= +google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a/go.mod h1:3kWAYMk1I75K4vykHtKt2ycnOgpA6974V7bREqbsenU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -585,8 +584,8 @@ modernc.org/ccgo/v4 v4.23.15 h1:wFDan71KnYqeHz4eF63vmGE6Q6Pc0PUGDpP0PRMYjDc= modernc.org/ccgo/v4 v4.23.15/go.mod h1:nJX30dks/IWuBOnVa7VRii9Me4/9TZ1SC9GNtmARTy0= modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= -modernc.org/gc/v2 v2.6.2 h1:YBXi5Kqp6aCK3fIxwKQ3/fErvawVKwjOLItxj1brGds= -modernc.org/gc/v2 v2.6.2/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= +modernc.org/gc/v2 v2.6.3 h1:aJVhcqAte49LF+mGveZ5KPlsp4tdGdAOT4sipJXADjw= +modernc.org/gc/v2 v2.6.3/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= modernc.org/libc v1.61.11 h1:6sZG8uB6EMMG7iTLPTndi8jyTdgAQNIeLGjCFICACZw= modernc.org/libc v1.61.11/go.mod h1:HHX+srFdn839oaJRd0W8hBM3eg+mieyZCAjWwB08/nM= modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= diff --git a/temporalcli/commands.gen.go b/temporalcli/commands.gen.go index a7061dd9d..66fe02dc1 100644 --- a/temporalcli/commands.gen.go +++ b/temporalcli/commands.gen.go @@ -2264,9 +2264,9 @@ func NewTemporalTaskQueueVersioningCommand(cctx *CommandContext, parent *Tempora s.Command.Use = "versioning" s.Command.Short = "Manage Task Queue Build ID handling (Experimental)" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nProvides commands to add, list, remove, or replace Worker Build ID assignment\nand redirect rules associated with Task Queues:\n\n\x1b[1mtemporal task-queue versioning [subcommands] [options] \\\n --task-queue YourTaskQueue\x1b[0m\n\nTask Queues support the following versioning rules and policies:\n\n- Assignment Rules: manage how new executions are assigned to run on specific\n Worker Build IDs. Each Task Queue stores a list of ordered Assignment Rules,\n which are evaluated from first to last. Assignment Rules also allow for\n gradual rollout of new Build IDs by setting ramp percentage.\n- Redirect Rules: automatically assign work for a source Build ID to a target\n Build ID. You may add at most one redirect rule for each source Build ID.\n Redirect rules require that a target Build ID is fully compatible with\n the source Build ID." + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+\n\nProvides commands to add, list, remove, or replace Worker Build ID assignment\nand redirect rules associated with Task Queues:\n\n\x1b[1mtemporal task-queue versioning [subcommands] [options] \\\n --task-queue YourTaskQueue\x1b[0m\n\nTask Queues support the following versioning rules and policies:\n\n- Assignment Rules: manage how new executions are assigned to run on specific\n Worker Build IDs. Each Task Queue stores a list of ordered Assignment Rules,\n which are evaluated from first to last. Assignment Rules also allow for\n gradual rollout of new Build IDs by setting ramp percentage.\n- Redirect Rules: automatically assign work for a source Build ID to a target\n Build ID. You may add at most one redirect rule for each source Build ID.\n Redirect rules require that a target Build ID is fully compatible with\n the source Build ID." } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nProvides commands to add, list, remove, or replace Worker Build ID assignment\nand redirect rules associated with Task Queues:\n\n```\ntemporal task-queue versioning [subcommands] [options] \\\n --task-queue YourTaskQueue\n```\n\nTask Queues support the following versioning rules and policies:\n\n- Assignment Rules: manage how new executions are assigned to run on specific\n Worker Build IDs. Each Task Queue stores a list of ordered Assignment Rules,\n which are evaluated from first to last. Assignment Rules also allow for\n gradual rollout of new Build IDs by setting ramp percentage.\n- Redirect Rules: automatically assign work for a source Build ID to a target\n Build ID. You may add at most one redirect rule for each source Build ID.\n Redirect rules require that a target Build ID is fully compatible with\n the source Build ID." + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+\n\nProvides commands to add, list, remove, or replace Worker Build ID assignment\nand redirect rules associated with Task Queues:\n\n```\ntemporal task-queue versioning [subcommands] [options] \\\n --task-queue YourTaskQueue\n```\n\nTask Queues support the following versioning rules and policies:\n\n- Assignment Rules: manage how new executions are assigned to run on specific\n Worker Build IDs. Each Task Queue stores a list of ordered Assignment Rules,\n which are evaluated from first to last. Assignment Rules also allow for\n gradual rollout of new Build IDs by setting ramp percentage.\n- Redirect Rules: automatically assign work for a source Build ID to a target\n Build ID. You may add at most one redirect rule for each source Build ID.\n Redirect rules require that a target Build ID is fully compatible with\n the source Build ID." } s.Command.Args = cobra.NoArgs s.Command.AddCommand(&NewTemporalTaskQueueVersioningAddRedirectRuleCommand(cctx, &s).Command) @@ -2297,9 +2297,9 @@ func NewTemporalTaskQueueVersioningAddRedirectRuleCommand(cctx *CommandContext, s.Command.Use = "add-redirect-rule [flags]" s.Command.Short = "Add Task Queue redirect rules (Experimental)" if hasHighlighting { - s.Command.Long = "Add a new redirect rule for a given Task Queue. You may add at most one\nredirect rule for each distinct source build ID:\n\n\x1b[1mtemporal task-queue versioning add-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id \"YourSourceBuildID\" \\\n --target-build-id \"YourTargetBuildID\"\x1b[0m\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Add a new redirect rule for a given Task Queue. You may add at most one\nredirect rule for each distinct source build ID:\n\n\x1b[1mtemporal task-queue versioning add-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id \"YourSourceBuildID\" \\\n --target-build-id \"YourTargetBuildID\"\x1b[0m\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } else { - s.Command.Long = "Add a new redirect rule for a given Task Queue. You may add at most one\nredirect rule for each distinct source build ID:\n\n```\ntemporal task-queue versioning add-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id \"YourSourceBuildID\" \\\n --target-build-id \"YourTargetBuildID\"\n```\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Add a new redirect rule for a given Task Queue. You may add at most one\nredirect rule for each distinct source build ID:\n\n```\ntemporal task-queue versioning add-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id \"YourSourceBuildID\" \\\n --target-build-id \"YourTargetBuildID\"\n```\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVar(&s.SourceBuildId, "source-build-id", "", "Source build ID. Required.") @@ -2330,9 +2330,9 @@ func NewTemporalTaskQueueVersioningCommitBuildIdCommand(cctx *CommandContext, pa s.Command.Use = "commit-build-id [flags]" s.Command.Short = "Complete Build ID rollout (Experimental)" if hasHighlighting { - s.Command.Long = "Complete a Build ID's rollout and clean up unnecessary rules that might have\nbeen created during a gradual rollout:\n\n\x1b[1mtemporal task-queue versioning commit-build-id \\\n --task-queue YourTaskQueue\n --build-id \"YourBuildId\"\x1b[0m\n\nThis command automatically applies the following atomic changes:\n\n- Adds an unconditional assignment rule for the target Build ID at the\n end of the list.\n- Removes all previously added assignment rules to the given target\n Build ID.\n- Removes any unconditional assignment rules for other Build IDs.\n\nRejects requests when there have been no recent pollers for this Build ID.\nThis prevents committing invalid Build IDs. Use the \x1b[1m--force\x1b[0m option to\noverride this validation.\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Complete a Build ID's rollout and clean up unnecessary rules that might have\nbeen created during a gradual rollout:\n\n\x1b[1mtemporal task-queue versioning commit-build-id \\\n --task-queue YourTaskQueue\n --build-id \"YourBuildId\"\x1b[0m\n\nThis command automatically applies the following atomic changes:\n\n- Adds an unconditional assignment rule for the target Build ID at the\n end of the list.\n- Removes all previously added assignment rules to the given target\n Build ID.\n- Removes any unconditional assignment rules for other Build IDs.\n\nRejects requests when there have been no recent pollers for this Build ID.\nThis prevents committing invalid Build IDs. Use the \x1b[1m--force\x1b[0m option to\noverride this validation.\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } else { - s.Command.Long = "Complete a Build ID's rollout and clean up unnecessary rules that might have\nbeen created during a gradual rollout:\n\n```\ntemporal task-queue versioning commit-build-id \\\n --task-queue YourTaskQueue\n --build-id \"YourBuildId\"\n```\n\nThis command automatically applies the following atomic changes:\n\n- Adds an unconditional assignment rule for the target Build ID at the\n end of the list.\n- Removes all previously added assignment rules to the given target\n Build ID.\n- Removes any unconditional assignment rules for other Build IDs.\n\nRejects requests when there have been no recent pollers for this Build ID.\nThis prevents committing invalid Build IDs. Use the `--force` option to\noverride this validation.\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Complete a Build ID's rollout and clean up unnecessary rules that might have\nbeen created during a gradual rollout:\n\n```\ntemporal task-queue versioning commit-build-id \\\n --task-queue YourTaskQueue\n --build-id \"YourBuildId\"\n```\n\nThis command automatically applies the following atomic changes:\n\n- Adds an unconditional assignment rule for the target Build ID at the\n end of the list.\n- Removes all previously added assignment rules to the given target\n Build ID.\n- Removes any unconditional assignment rules for other Build IDs.\n\nRejects requests when there have been no recent pollers for this Build ID.\nThis prevents committing invalid Build IDs. Use the `--force` option to\noverride this validation.\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVar(&s.BuildId, "build-id", "", "Target build ID. Required.") @@ -2362,9 +2362,9 @@ func NewTemporalTaskQueueVersioningDeleteAssignmentRuleCommand(cctx *CommandCont s.Command.Use = "delete-assignment-rule [flags]" s.Command.Short = "Removes a Task Queue assignment rule (Experimental)" if hasHighlighting { - s.Command.Long = "Deletes a rule identified by its index in the Task Queue's list of assignment\nrules.\n\n\x1b[1mtemporal task-queue versioning delete-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index YourIntegerRuleIndex\x1b[0m\n\nBy default, the Task Queue must retain one unconditional rule, such as \"no\nhint filter\" or \"percentage\". Otherwise, the delete operation is rejected.\nUse the \x1b[1m--force\x1b[0m option to override this validation.\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Deletes a rule identified by its index in the Task Queue's list of assignment\nrules.\n\n\x1b[1mtemporal task-queue versioning delete-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index YourIntegerRuleIndex\x1b[0m\n\nBy default, the Task Queue must retain one unconditional rule, such as \"no\nhint filter\" or \"percentage\". Otherwise, the delete operation is rejected.\nUse the \x1b[1m--force\x1b[0m option to override this validation.\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } else { - s.Command.Long = "Deletes a rule identified by its index in the Task Queue's list of assignment\nrules.\n\n```\ntemporal task-queue versioning delete-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index YourIntegerRuleIndex\n```\n\nBy default, the Task Queue must retain one unconditional rule, such as \"no\nhint filter\" or \"percentage\". Otherwise, the delete operation is rejected.\nUse the `--force` option to override this validation.\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Deletes a rule identified by its index in the Task Queue's list of assignment\nrules.\n\n```\ntemporal task-queue versioning delete-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index YourIntegerRuleIndex\n```\n\nBy default, the Task Queue must retain one unconditional rule, such as \"no\nhint filter\" or \"percentage\". Otherwise, the delete operation is rejected.\nUse the `--force` option to override this validation.\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } s.Command.Args = cobra.NoArgs s.Command.Flags().IntVarP(&s.RuleIndex, "rule-index", "i", 0, "Position of the assignment rule to be replaced. Requests for invalid indices will fail. Required.") @@ -2393,9 +2393,9 @@ func NewTemporalTaskQueueVersioningDeleteRedirectRuleCommand(cctx *CommandContex s.Command.Use = "delete-redirect-rule [flags]" s.Command.Short = "Removes Build-ID routing rule (Experimental)" if hasHighlighting { - s.Command.Long = "Deletes the routing rule for the given source Build ID.\n\n\x1b[1mtemporal task-queue versioning delete-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id \"YourBuildId\"\x1b[0m\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Deletes the routing rule for the given source Build ID.\n\n\x1b[1mtemporal task-queue versioning delete-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id \"YourBuildId\"\x1b[0m\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } else { - s.Command.Long = "Deletes the routing rule for the given source Build ID.\n\n```\ntemporal task-queue versioning delete-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id \"YourBuildId\"\n```\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Deletes the routing rule for the given source Build ID.\n\n```\ntemporal task-queue versioning delete-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id \"YourBuildId\"\n```\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVar(&s.SourceBuildId, "source-build-id", "", "Source Build ID. Required.") @@ -2421,9 +2421,9 @@ func NewTemporalTaskQueueVersioningGetRulesCommand(cctx *CommandContext, parent s.Command.Use = "get-rules [flags]" s.Command.Short = "Fetch Worker Build ID assignments and redirect rules (Experimental)" if hasHighlighting { - s.Command.Long = "Retrieve all the Worker Build ID assignments and redirect rules associated\nwith a Task Queue:\n\n\x1b[1mtemporal task-queue versioning get-rules \\\n --task-queue YourTaskQueue\x1b[0m\n\nTask Queues support the following versioning rules:\n\n- Assignment Rules: manage how new executions are assigned to run on specific\n Worker Build IDs. Each Task Queue stores a list of ordered Assignment Rules,\n which are evaluated from first to last. Assignment Rules also allow for\n gradual rollout of new Build IDs by setting ramp percentage.\n- Redirect Rules: automatically assign work for a source Build ID to a target\n Build ID. You may add at most one redirect rule for each source Build ID.\n Redirect rules require that a target Build ID is fully compatible with\n the source Build ID.\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Retrieve all the Worker Build ID assignments and redirect rules associated\nwith a Task Queue:\n\n\x1b[1mtemporal task-queue versioning get-rules \\\n --task-queue YourTaskQueue\x1b[0m\n\nTask Queues support the following versioning rules:\n\n- Assignment Rules: manage how new executions are assigned to run on specific\n Worker Build IDs. Each Task Queue stores a list of ordered Assignment Rules,\n which are evaluated from first to last. Assignment Rules also allow for\n gradual rollout of new Build IDs by setting ramp percentage.\n- Redirect Rules: automatically assign work for a source Build ID to a target\n Build ID. You may add at most one redirect rule for each source Build ID.\n Redirect rules require that a target Build ID is fully compatible with\n the source Build ID.\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } else { - s.Command.Long = "Retrieve all the Worker Build ID assignments and redirect rules associated\nwith a Task Queue:\n\n```\ntemporal task-queue versioning get-rules \\\n --task-queue YourTaskQueue\n```\n\nTask Queues support the following versioning rules:\n\n- Assignment Rules: manage how new executions are assigned to run on specific\n Worker Build IDs. Each Task Queue stores a list of ordered Assignment Rules,\n which are evaluated from first to last. Assignment Rules also allow for\n gradual rollout of new Build IDs by setting ramp percentage.\n- Redirect Rules: automatically assign work for a source Build ID to a target\n Build ID. You may add at most one redirect rule for each source Build ID.\n Redirect rules require that a target Build ID is fully compatible with\n the source Build ID.\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Retrieve all the Worker Build ID assignments and redirect rules associated\nwith a Task Queue:\n\n```\ntemporal task-queue versioning get-rules \\\n --task-queue YourTaskQueue\n```\n\nTask Queues support the following versioning rules:\n\n- Assignment Rules: manage how new executions are assigned to run on specific\n Worker Build IDs. Each Task Queue stores a list of ordered Assignment Rules,\n which are evaluated from first to last. Assignment Rules also allow for\n gradual rollout of new Build IDs by setting ramp percentage.\n- Redirect Rules: automatically assign work for a source Build ID to a target\n Build ID. You may add at most one redirect rule for each source Build ID.\n Redirect rules require that a target Build ID is fully compatible with\n the source Build ID.\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } s.Command.Args = cobra.NoArgs s.Command.Run = func(c *cobra.Command, args []string) { @@ -2450,9 +2450,9 @@ func NewTemporalTaskQueueVersioningInsertAssignmentRuleCommand(cctx *CommandCont s.Command.Use = "insert-assignment-rule [flags]" s.Command.Short = "Add an assignment rule at a index (Experimental)" if hasHighlighting { - s.Command.Long = "Inserts a new assignment rule for this Task Queue. Rules are evaluated in\norder, starting from index 0. The first applicable rule is applied, and the\nrest ignored:\n\n\x1b[1mtemporal task-queue versioning insert-assignment-rule \\\n --task-queue YourTaskQueue \\\n --build-id \"YourBuildId\"\x1b[0m\n\nIf you do not specify a \x1b[1m--rule-index\x1b[0m, this command inserts at index 0.\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Inserts a new assignment rule for this Task Queue. Rules are evaluated in\norder, starting from index 0. The first applicable rule is applied, and the\nrest ignored:\n\n\x1b[1mtemporal task-queue versioning insert-assignment-rule \\\n --task-queue YourTaskQueue \\\n --build-id \"YourBuildId\"\x1b[0m\n\nIf you do not specify a \x1b[1m--rule-index\x1b[0m, this command inserts at index 0.\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } else { - s.Command.Long = "Inserts a new assignment rule for this Task Queue. Rules are evaluated in\norder, starting from index 0. The first applicable rule is applied, and the\nrest ignored:\n\n```\ntemporal task-queue versioning insert-assignment-rule \\\n --task-queue YourTaskQueue \\\n --build-id \"YourBuildId\"\n```\n\nIf you do not specify a `--rule-index`, this command inserts at index 0.\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Inserts a new assignment rule for this Task Queue. Rules are evaluated in\norder, starting from index 0. The first applicable rule is applied, and the\nrest ignored:\n\n```\ntemporal task-queue versioning insert-assignment-rule \\\n --task-queue YourTaskQueue \\\n --build-id \"YourBuildId\"\n```\n\nIf you do not specify a `--rule-index`, this command inserts at index 0.\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVar(&s.BuildId, "build-id", "", "Target Build ID. Required.") @@ -2485,9 +2485,9 @@ func NewTemporalTaskQueueVersioningReplaceAssignmentRuleCommand(cctx *CommandCon s.Command.Use = "replace-assignment-rule [flags]" s.Command.Short = "Update assignment rule at index (Experimental)" if hasHighlighting { - s.Command.Long = "Change an assignment rule for this Task Queue. By default, this enforces one\nunconditional rule (no hint filter or percentage). Otherwise, the operation\nwill be rejected. Set \x1b[1mforce\x1b[0m to true to bypass this validation.\n\n\x1b[1mtemporal task-queue versioning replace-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index AnIntegerIndex \\\n --build-id \"YourBuildId\"\x1b[0m\n\nTo assign multiple assignment rules to a single Build ID, use\n'insert-assignment-rule'.\n\nTo update the percent:\n\n\x1b[1mtemporal task-queue versioning replace-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index AnIntegerIndex \\\n --build-id \"YourBuildId\" \\\n --percentage AnIntegerPercent\x1b[0m\n\nPercent may vary between 0 and 100 (default).\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Change an assignment rule for this Task Queue. By default, this enforces one\nunconditional rule (no hint filter or percentage). Otherwise, the operation\nwill be rejected. Set \x1b[1mforce\x1b[0m to true to bypass this validation.\n\n\x1b[1mtemporal task-queue versioning replace-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index AnIntegerIndex \\\n --build-id \"YourBuildId\"\x1b[0m\n\nTo assign multiple assignment rules to a single Build ID, use\n'insert-assignment-rule'.\n\nTo update the percent:\n\n\x1b[1mtemporal task-queue versioning replace-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index AnIntegerIndex \\\n --build-id \"YourBuildId\" \\\n --percentage AnIntegerPercent\x1b[0m\n\nPercent may vary between 0 and 100 (default).\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } else { - s.Command.Long = "Change an assignment rule for this Task Queue. By default, this enforces one\nunconditional rule (no hint filter or percentage). Otherwise, the operation\nwill be rejected. Set `force` to true to bypass this validation.\n\n```\ntemporal task-queue versioning replace-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index AnIntegerIndex \\\n --build-id \"YourBuildId\"\n```\n\nTo assign multiple assignment rules to a single Build ID, use\n'insert-assignment-rule'.\n\nTo update the percent:\n\n```\ntemporal task-queue versioning replace-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index AnIntegerIndex \\\n --build-id \"YourBuildId\" \\\n --percentage AnIntegerPercent\n```\n\nPercent may vary between 0 and 100 (default).\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Change an assignment rule for this Task Queue. By default, this enforces one\nunconditional rule (no hint filter or percentage). Otherwise, the operation\nwill be rejected. Set `force` to true to bypass this validation.\n\n```\ntemporal task-queue versioning replace-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index AnIntegerIndex \\\n --build-id \"YourBuildId\"\n```\n\nTo assign multiple assignment rules to a single Build ID, use\n'insert-assignment-rule'.\n\nTo update the percent:\n\n```\ntemporal task-queue versioning replace-assignment-rule \\\n --task-queue YourTaskQueue \\\n --rule-index AnIntegerIndex \\\n --build-id \"YourBuildId\" \\\n --percentage AnIntegerPercent\n```\n\nPercent may vary between 0 and 100 (default).\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVar(&s.BuildId, "build-id", "", "Target Build ID. Required.") @@ -2520,9 +2520,9 @@ func NewTemporalTaskQueueVersioningReplaceRedirectRuleCommand(cctx *CommandConte s.Command.Use = "replace-redirect-rule [flags]" s.Command.Short = "Change the target for a Build ID's redirect (Experimental)" if hasHighlighting { - s.Command.Long = "Updates a Build ID's redirect rule on a Task Queue by replacing its target\nBuild ID:\n\n\x1b[1mtemporal task-queue versioning replace-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id YourSourceBuildId \\\n --target-build-id YourNewTargetBuildId\x1b[0m\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Updates a Build ID's redirect rule on a Task Queue by replacing its target\nBuild ID:\n\n\x1b[1mtemporal task-queue versioning replace-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id YourSourceBuildId \\\n --target-build-id YourNewTargetBuildId\x1b[0m\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } else { - s.Command.Long = "Updates a Build ID's redirect rule on a Task Queue by replacing its target\nBuild ID:\n\n```\ntemporal task-queue versioning replace-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id YourSourceBuildId \\\n --target-build-id YourNewTargetBuildId\n```\n\n+---------------------------------------------------------------------+\n| CAUTION: Worker versioning is experimental. Versioning commands are |\n| subject to change. |\n+---------------------------------------------------------------------+" + s.Command.Long = "Updates a Build ID's redirect rule on a Task Queue by replacing its target\nBuild ID:\n\n```\ntemporal task-queue versioning replace-redirect-rule \\\n --task-queue YourTaskQueue \\\n --source-build-id YourSourceBuildId \\\n --target-build-id YourNewTargetBuildId\n```\n\n+---------------------------------------------------------------------+\n| CAUTION: This API has been deprecated by Worker Deployment. |\n+---------------------------------------------------------------------+" } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVar(&s.SourceBuildId, "source-build-id", "", "Source Build ID. Required.") @@ -2571,15 +2571,19 @@ func NewTemporalWorkerDeploymentCommand(cctx *CommandContext, parent *TemporalWo s.Command.Use = "deployment" s.Command.Short = "Describe, list, and operate on Worker Deployments and Versions" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDeployment commands perform operations on Worker Deployments:\n\n\x1b[1mtemporal worker deployment [command] [options]\x1b[0m\n\nFor example:\n\n\x1b[1mtemporal worker deployment list\x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDeployment commands perform operations on Worker Deployments:\n\n\x1b[1mtemporal worker deployment [command] [options]\x1b[0m\n\nFor example:\n\n\x1b[1mtemporal worker deployment list\x1b[0m\n\nLists the Deployments in the client's namespace.\n\nArguments can be Worker Deployment Versions associated with\na Deployment, using a fully qualified Version identifier that\nconcatenates the Deployment Name and the Build ID with the\nreserved separator \".\".\n\nFor example:\n\n\x1b[1mtemporal worker deployment set-current-version \\\n --version YourDeploymentName.YourBuildID\x1b[0m\n\nSets the current Deployment Version for a given Deployment." } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDeployment commands perform operations on Worker Deployments:\n\n```\ntemporal worker deployment [command] [options]\n```\n\nFor example:\n\n```\ntemporal worker deployment list\n```" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDeployment commands perform operations on Worker Deployments:\n\n```\ntemporal worker deployment [command] [options]\n```\n\nFor example:\n\n```\ntemporal worker deployment list\n```\n\nLists the Deployments in the client's namespace.\n\nArguments can be Worker Deployment Versions associated with\na Deployment, using a fully qualified Version identifier that\nconcatenates the Deployment Name and the Build ID with the\nreserved separator \".\".\n\nFor example:\n\n```\ntemporal worker deployment set-current-version \\\n --version YourDeploymentName.YourBuildID\n```\n\nSets the current Deployment Version for a given Deployment." } s.Command.Args = cobra.NoArgs s.Command.AddCommand(&NewTemporalWorkerDeploymentDeleteCommand(cctx, &s).Command) + s.Command.AddCommand(&NewTemporalWorkerDeploymentDeleteVersionCommand(cctx, &s).Command) s.Command.AddCommand(&NewTemporalWorkerDeploymentDescribeCommand(cctx, &s).Command) + s.Command.AddCommand(&NewTemporalWorkerDeploymentDescribeVersionCommand(cctx, &s).Command) s.Command.AddCommand(&NewTemporalWorkerDeploymentListCommand(cctx, &s).Command) - s.Command.AddCommand(&NewTemporalWorkerDeploymentVersionCommand(cctx, &s).Command) + s.Command.AddCommand(&NewTemporalWorkerDeploymentSetCurrentVersionCommand(cctx, &s).Command) + s.Command.AddCommand(&NewTemporalWorkerDeploymentSetRampingVersionCommand(cctx, &s).Command) + s.Command.AddCommand(&NewTemporalWorkerDeploymentUpdateMetadataVersionCommand(cctx, &s).Command) return &s } @@ -2595,11 +2599,11 @@ func NewTemporalWorkerDeploymentDeleteCommand(cctx *CommandContext, parent *Temp s.Parent = parent s.Command.DisableFlagsInUseLine = true s.Command.Use = "delete [flags]" - s.Command.Short = "Deletes a Worker Deployment" + s.Command.Short = "Delete a Worker Deployment" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemoves a Worker Deployment given its Deployment Name.\nA Deployment can only be deleted if it has no Version in it.\n\n\x1b[1mtemporal worker deployment delete [options]\x1b[0m\n\nFor example, setting the user identity that removed the deployment:\n\n\x1b[1mtemporal worker deployment delete \\\n --name YourDeploymentName \\\n --identity YourIdentity\x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemove a Worker Deployment given its Deployment Name.\nA Deployment can only be deleted if it has no Version in it.\n\n\x1b[1mtemporal worker deployment delete [options]\x1b[0m\n\nFor example, setting the user identity that removed the deployment:\n\n\x1b[1mtemporal worker deployment delete \\\n --name YourDeploymentName \\\n --identity YourIdentity\x1b[0m" } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemoves a Worker Deployment given its Deployment Name.\nA Deployment can only be deleted if it has no Version in it.\n\n```\ntemporal worker deployment delete [options]\n```\n\nFor example, setting the user identity that removed the deployment:\n\n```\ntemporal worker deployment delete \\\n --name YourDeploymentName \\\n --identity YourIdentity\n\n```" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemove a Worker Deployment given its Deployment Name.\nA Deployment can only be deleted if it has no Version in it.\n\n```\ntemporal worker deployment delete [options]\n```\n\nFor example, setting the user identity that removed the deployment:\n\n```\ntemporal worker deployment delete \\\n --name YourDeploymentName \\\n --identity YourIdentity\n\n```" } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") @@ -2612,25 +2616,29 @@ func NewTemporalWorkerDeploymentDeleteCommand(cctx *CommandContext, parent *Temp return &s } -type TemporalWorkerDeploymentDescribeCommand struct { +type TemporalWorkerDeploymentDeleteVersionCommand struct { Parent *TemporalWorkerDeploymentCommand Command cobra.Command - DeploymentNameOptions + DeploymentVersionOptions + Identity string + SkipDrainage bool } -func NewTemporalWorkerDeploymentDescribeCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentDescribeCommand { - var s TemporalWorkerDeploymentDescribeCommand +func NewTemporalWorkerDeploymentDeleteVersionCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentDeleteVersionCommand { + var s TemporalWorkerDeploymentDeleteVersionCommand s.Parent = parent s.Command.DisableFlagsInUseLine = true - s.Command.Use = "describe [flags]" - s.Command.Short = "Show properties of a Worker Deployment" + s.Command.Use = "delete-version [flags]" + s.Command.Short = "Delete a Worker Deployment Version" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribes properties of a Worker Deployment, such as the versions\nassociated with it, routing information of new or existing tasks\nexecuted by this deployment, or its creation time.\n\n\x1b[1mtemporal worker deployment describe [options]\x1b[0m\n\nFor example, to describe a deployment \x1b[1mYourDeploymentName\x1b[0m in the default\nnamespace:\n\n\x1b[1mtemporal worker deployment describe \\\n --name YourDeploymentName\x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemove a Worker Deployment Version given its fully-qualified identifier.\nThis is rarely needed during normal operation\nsince unused Versions are eventually garbage collected.\nThe client can delete a Version only when all of the following conditions\nare met:\n - It is not the Current or Ramping Version for this Deployment.\n - It has no active pollers, i.e., none of the task queues in the\n Version have pollers.\n - It is not draining. This requirement can be ignored with the option\n\x1b[1m--skip-drainage\x1b[0m.\n \n\x1b[1mtemporal worker deployment delete-version [options]\x1b[0m\n\nFor example, skipping the drainage restriction:\n\n\x1b[1mtemporal worker deployment delete-version \\\n --version YourDeploymentName.YourBuildID \\\n --skip-drainage \x1b[0m" } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribes properties of a Worker Deployment, such as the versions\nassociated with it, routing information of new or existing tasks\nexecuted by this deployment, or its creation time.\n\n```\ntemporal worker deployment describe [options]\n```\n\nFor example, to describe a deployment `YourDeploymentName` in the default\nnamespace:\n\n```\ntemporal worker deployment describe \\\n --name YourDeploymentName\n```" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemove a Worker Deployment Version given its fully-qualified identifier.\nThis is rarely needed during normal operation\nsince unused Versions are eventually garbage collected.\nThe client can delete a Version only when all of the following conditions\nare met:\n - It is not the Current or Ramping Version for this Deployment.\n - It has no active pollers, i.e., none of the task queues in the\n Version have pollers.\n - It is not draining. This requirement can be ignored with the option\n`--skip-drainage`.\n \n```\ntemporal worker deployment delete-version [options]\n```\n\nFor example, skipping the drainage restriction:\n\n```\ntemporal worker deployment delete-version \\\n --version YourDeploymentName.YourBuildID \\\n --skip-drainage \n```" } s.Command.Args = cobra.NoArgs - s.DeploymentNameOptions.buildFlags(cctx, s.Command.Flags()) + s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") + s.Command.Flags().BoolVar(&s.SkipDrainage, "skip-drainage", false, "Ignore the deletion requirement of not draining.") + s.DeploymentVersionOptions.buildFlags(cctx, s.Command.Flags()) s.Command.Run = func(c *cobra.Command, args []string) { if err := s.run(cctx, args); err != nil { cctx.Options.Fail(err) @@ -2639,23 +2647,25 @@ func NewTemporalWorkerDeploymentDescribeCommand(cctx *CommandContext, parent *Te return &s } -type TemporalWorkerDeploymentListCommand struct { +type TemporalWorkerDeploymentDescribeCommand struct { Parent *TemporalWorkerDeploymentCommand Command cobra.Command + DeploymentNameOptions } -func NewTemporalWorkerDeploymentListCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentListCommand { - var s TemporalWorkerDeploymentListCommand +func NewTemporalWorkerDeploymentDescribeCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentDescribeCommand { + var s TemporalWorkerDeploymentDescribeCommand s.Parent = parent s.Command.DisableFlagsInUseLine = true - s.Command.Use = "list [flags]" - s.Command.Short = "Enumerate Worker Deployments in the client's namespace" + s.Command.Use = "describe [flags]" + s.Command.Short = "Show properties of a Worker Deployment" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nList existing Worker Deployments in the client's namespace.\n\n\x1b[1mtemporal worker deployment list [options]\x1b[0m\n\nFor example, listing Deployments in YourDeploymentNamespace:\n\n\x1b[1mtemporal worker deployment list \\\n --namespace YourDeploymentNamespace\x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribe properties of a Worker Deployment, such as the versions\nassociated with it, routing information of new or existing tasks\nexecuted by this deployment, or its creation time.\n\n\x1b[1mtemporal worker deployment describe [options]\x1b[0m\n\nFor example, to describe a deployment \x1b[1mYourDeploymentName\x1b[0m in the default\nnamespace:\n\n\x1b[1mtemporal worker deployment describe \\\n --name YourDeploymentName\x1b[0m" } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nList existing Worker Deployments in the client's namespace.\n\n```\ntemporal worker deployment list [options]\n```\n\nFor example, listing Deployments in YourDeploymentNamespace:\n\n```\ntemporal worker deployment list \\\n --namespace YourDeploymentNamespace\n```" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribe properties of a Worker Deployment, such as the versions\nassociated with it, routing information of new or existing tasks\nexecuted by this deployment, or its creation time.\n\n```\ntemporal worker deployment describe [options]\n```\n\nFor example, to describe a deployment `YourDeploymentName` in the default\nnamespace:\n\n```\ntemporal worker deployment describe \\\n --name YourDeploymentName\n```" } s.Command.Args = cobra.NoArgs + s.DeploymentNameOptions.buildFlags(cctx, s.Command.Flags()) s.Command.Run = func(c *cobra.Command, args []string) { if err := s.run(cctx, args); err != nil { cctx.Options.Fail(err) @@ -2664,51 +2674,24 @@ func NewTemporalWorkerDeploymentListCommand(cctx *CommandContext, parent *Tempor return &s } -type TemporalWorkerDeploymentVersionCommand struct { +type TemporalWorkerDeploymentDescribeVersionCommand struct { Parent *TemporalWorkerDeploymentCommand Command cobra.Command -} - -func NewTemporalWorkerDeploymentVersionCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentVersionCommand { - var s TemporalWorkerDeploymentVersionCommand - s.Parent = parent - s.Command.Use = "version" - s.Command.Short = "Describe, delete, setCurrent, or setRamping, a Deployment Version" - if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDeployment commands to operate on Worker Deployment Versions:\n \n\x1b[1mtemporal worker deployment version [command] [options]\x1b[0m\n\nFor example, using a fully qualified Version identifier that\nconcatenates the Deployment Name with the Build ID using the\nreserved separator \".\":\n\n\x1b[1mtemporal worker deployment version setCurrent \\\n --version YourDeploymentName.YourBuildID\x1b[0m \nSets the current Deployment Version for a given Deployment.\nWhen a Version is current, Workers of that Deployment Version will receive\ntasks from new Workflows and from existing AutoUpgrade Workflows that\nare running on this Deployment." - } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDeployment commands to operate on Worker Deployment Versions:\n \n```\ntemporal worker deployment version [command] [options]\n```\n\nFor example, using a fully qualified Version identifier that\nconcatenates the Deployment Name with the Build ID using the\nreserved separator \".\":\n\n```\ntemporal worker deployment version setCurrent \\\n --version YourDeploymentName.YourBuildID\n``` \nSets the current Deployment Version for a given Deployment.\nWhen a Version is current, Workers of that Deployment Version will receive\ntasks from new Workflows and from existing AutoUpgrade Workflows that\nare running on this Deployment." - } - s.Command.Args = cobra.NoArgs - s.Command.AddCommand(&NewTemporalWorkerDeploymentVersionDeleteCommand(cctx, &s).Command) - s.Command.AddCommand(&NewTemporalWorkerDeploymentVersionDescribeCommand(cctx, &s).Command) - s.Command.AddCommand(&NewTemporalWorkerDeploymentVersionSetCurrentCommand(cctx, &s).Command) - s.Command.AddCommand(&NewTemporalWorkerDeploymentVersionSetRampingCommand(cctx, &s).Command) - return &s -} - -type TemporalWorkerDeploymentVersionDeleteCommand struct { - Parent *TemporalWorkerDeploymentVersionCommand - Command cobra.Command DeploymentVersionOptions - Identity string - SkipDrainage bool } -func NewTemporalWorkerDeploymentVersionDeleteCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentVersionCommand) *TemporalWorkerDeploymentVersionDeleteCommand { - var s TemporalWorkerDeploymentVersionDeleteCommand +func NewTemporalWorkerDeploymentDescribeVersionCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentDescribeVersionCommand { + var s TemporalWorkerDeploymentDescribeVersionCommand s.Parent = parent s.Command.DisableFlagsInUseLine = true - s.Command.Use = "delete [flags]" - s.Command.Short = "Deletes a Worker Deployment Version" + s.Command.Use = "describe-version [flags]" + s.Command.Short = "Show properties of a Worker Deployment Version" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemoves a Worker Deployment Version given its fully-qualified identifier.\nThis is rarely needed during normal operation\nsince unused Versions are eventually garbage collected.\nThe client can delete a Version only when all of the following conditions\nare met:\n - It is not the Current or Ramping Version for this Deployment.\n - It has no active pollers, i.e., none of the task queues in the\n Version have pollers.\n - It is not draining. This requirement can be ignored with the option\n --skip-drainage.\n \n\x1b[1mtemporal worker deployment version delete [options]\x1b[0m\n\nFor example, forcing to skip the drainage restriction:\n\n\x1b[1mtemporal worker deployment version delete \\\n --version YourDeploymentName.YourBuildID \\\n --skip-drainage \x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribe properties of a Worker Deployment Version, such as the task \nqueues polled by workers in this Deployment Version, or drainage\ninformation required to safely decommission workers, or user-provided\nmetadata, or its creation/modification time.\n\n\x1b[1mtemporal worker deployment describe-version [options]\x1b[0m\n\nFor example, to describe a deployment version in a deployment\n\x1b[1mYourDeploymentName\x1b[0m, with Build ID \x1b[1mYourBuildID\x1b[0m, and in the default\nnamespace:\n\n\x1b[1mtemporal worker deployment describe-version \\\n --version YourDeploymentName.YourBuildID\x1b[0m" } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nRemoves a Worker Deployment Version given its fully-qualified identifier.\nThis is rarely needed during normal operation\nsince unused Versions are eventually garbage collected.\nThe client can delete a Version only when all of the following conditions\nare met:\n - It is not the Current or Ramping Version for this Deployment.\n - It has no active pollers, i.e., none of the task queues in the\n Version have pollers.\n - It is not draining. This requirement can be ignored with the option\n --skip-drainage.\n \n```\ntemporal worker deployment version delete [options]\n```\n\nFor example, forcing to skip the drainage restriction:\n\n```\ntemporal worker deployment version delete \\\n --version YourDeploymentName.YourBuildID \\\n --skip-drainage \n```" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribe properties of a Worker Deployment Version, such as the task \nqueues polled by workers in this Deployment Version, or drainage\ninformation required to safely decommission workers, or user-provided\nmetadata, or its creation/modification time.\n\n```\ntemporal worker deployment describe-version [options]\n```\n\nFor example, to describe a deployment version in a deployment\n`YourDeploymentName`, with Build ID `YourBuildID`, and in the default\nnamespace:\n\n```\ntemporal worker deployment describe-version \\\n --version YourDeploymentName.YourBuildID\n```" } s.Command.Args = cobra.NoArgs - s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") - s.Command.Flags().BoolVar(&s.SkipDrainage, "skip-drainage", false, "Ignore the deletion requirement of not draining.") s.DeploymentVersionOptions.buildFlags(cctx, s.Command.Flags()) s.Command.Run = func(c *cobra.Command, args []string) { if err := s.run(cctx, args); err != nil { @@ -2718,25 +2701,23 @@ func NewTemporalWorkerDeploymentVersionDeleteCommand(cctx *CommandContext, paren return &s } -type TemporalWorkerDeploymentVersionDescribeCommand struct { - Parent *TemporalWorkerDeploymentVersionCommand +type TemporalWorkerDeploymentListCommand struct { + Parent *TemporalWorkerDeploymentCommand Command cobra.Command - DeploymentVersionOptions } -func NewTemporalWorkerDeploymentVersionDescribeCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentVersionCommand) *TemporalWorkerDeploymentVersionDescribeCommand { - var s TemporalWorkerDeploymentVersionDescribeCommand +func NewTemporalWorkerDeploymentListCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentListCommand { + var s TemporalWorkerDeploymentListCommand s.Parent = parent s.Command.DisableFlagsInUseLine = true - s.Command.Use = "describe [flags]" - s.Command.Short = "Show properties of a Worker Deployment Version" + s.Command.Use = "list [flags]" + s.Command.Short = "Enumerate Worker Deployments in the client's namespace" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribes properties of a Worker Deployment Version, such as the task \nqueues polled by workers in this Deployment Version, or drainage\ninformation required to safely decommission workers, or user-provided\nmetadata, or its creation/modification time.\n\n\x1b[1mtemporal worker deployment version describe [options]\x1b[0m\n\nFor example, to describe a deployment version in a deployment\n\x1b[1mYourDeploymentName\x1b[0m, with Build ID \x1b[1mYourBuildID\x1b[0m, and in the default\nnamespace:\n\n\x1b[1mtemporal worker deployment version describe \\\n --version YourDeploymentName.YourBuildID\x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nList existing Worker Deployments in the client's namespace.\n\n\x1b[1mtemporal worker deployment list [options]\x1b[0m\n\nFor example, listing Deployments in YourDeploymentNamespace:\n\n\x1b[1mtemporal worker deployment list \\\n --namespace YourDeploymentNamespace\x1b[0m" } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nDescribes properties of a Worker Deployment Version, such as the task \nqueues polled by workers in this Deployment Version, or drainage\ninformation required to safely decommission workers, or user-provided\nmetadata, or its creation/modification time.\n\n```\ntemporal worker deployment version describe [options]\n```\n\nFor example, to describe a deployment version in a deployment\n`YourDeploymentName`, with Build ID `YourBuildID`, and in the default\nnamespace:\n\n```\ntemporal worker deployment version describe \\\n --version YourDeploymentName.YourBuildID\n```" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nList existing Worker Deployments in the client's namespace.\n\n```\ntemporal worker deployment list [options]\n```\n\nFor example, listing Deployments in YourDeploymentNamespace:\n\n```\ntemporal worker deployment list \\\n --namespace YourDeploymentNamespace\n```" } s.Command.Args = cobra.NoArgs - s.DeploymentVersionOptions.buildFlags(cctx, s.Command.Flags()) s.Command.Run = func(c *cobra.Command, args []string) { if err := s.run(cctx, args); err != nil { cctx.Options.Fail(err) @@ -2745,8 +2726,8 @@ func NewTemporalWorkerDeploymentVersionDescribeCommand(cctx *CommandContext, par return &s } -type TemporalWorkerDeploymentVersionSetCurrentCommand struct { - Parent *TemporalWorkerDeploymentVersionCommand +type TemporalWorkerDeploymentSetCurrentVersionCommand struct { + Parent *TemporalWorkerDeploymentCommand Command cobra.Command DeploymentVersionOptions DeploymentName string @@ -2755,16 +2736,16 @@ type TemporalWorkerDeploymentVersionSetCurrentCommand struct { Yes bool } -func NewTemporalWorkerDeploymentVersionSetCurrentCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentVersionCommand) *TemporalWorkerDeploymentVersionSetCurrentCommand { - var s TemporalWorkerDeploymentVersionSetCurrentCommand +func NewTemporalWorkerDeploymentSetCurrentVersionCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentSetCurrentVersionCommand { + var s TemporalWorkerDeploymentSetCurrentVersionCommand s.Parent = parent s.Command.DisableFlagsInUseLine = true - s.Command.Use = "set-current [flags]" + s.Command.Use = "set-current-version [flags]" s.Command.Short = "Make a Worker Deployment Version Current for a Deployment" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSets the Current Version for a Deployment.\nWhen a Version is current, Workers of that Deployment Version will receive\ntasks from new Workflows and from existing AutoUpgrade Workflows that\nare running on this Deployment.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Version the request will fail. To override this protection use\n\x1b[1m--ignore-missing-task-queues\x1b[0m. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n\x1b[1mtemporal worker deployment version set-current [options]\x1b[0m\n\nFor example, to set the Current Version of a deployment\n\x1b[1mYourDeploymentName\x1b[0m, with a version with Build ID \x1b[1mYourBuildID\x1b[0m, and\nin the default namespace:\n\n\x1b[1mtemporal worker deployment version set-current \\\n --version YourDeploymentName.YourBuildID\x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSet the Current Version for a Deployment.\nWhen a Version is current, Workers of that Deployment Version will receive\ntasks from new Workflows, and from existing AutoUpgrade Workflows that\nare running on this Deployment.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Version the request will fail. To override this protection use\n\x1b[1m--ignore-missing-task-queues\x1b[0m. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n\x1b[1mtemporal worker deployment set-current-version [options]\x1b[0m\n\nFor example, to set the Current Version of a deployment\n\x1b[1mYourDeploymentName\x1b[0m, with a version with Build ID \x1b[1mYourBuildID\x1b[0m, and\nin the default namespace:\n\n\x1b[1mtemporal worker deployment set-current-version \\\n --version YourDeploymentName.YourBuildID\x1b[0m\n\nThe target of set-current-version can also be \x1b[1m__unversioned__\x1b[0m, which\nmoves tasks to unversioned workers, but in this case we also need to\nspecify the Deployment Name.\n\n\x1b[1mtemporal worker deployment set-current-version \\\n --version __unversioned__ \\\n --deployment-name YourDeploymentName\x1b[0m " } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSets the Current Version for a Deployment.\nWhen a Version is current, Workers of that Deployment Version will receive\ntasks from new Workflows and from existing AutoUpgrade Workflows that\nare running on this Deployment.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Version the request will fail. To override this protection use\n`--ignore-missing-task-queues`. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n```\ntemporal worker deployment version set-current [options]\n```\n\nFor example, to set the Current Version of a deployment\n`YourDeploymentName`, with a version with Build ID `YourBuildID`, and\nin the default namespace:\n\n```\ntemporal worker deployment version set-current \\\n --version YourDeploymentName.YourBuildID\n```" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSet the Current Version for a Deployment.\nWhen a Version is current, Workers of that Deployment Version will receive\ntasks from new Workflows, and from existing AutoUpgrade Workflows that\nare running on this Deployment.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Version the request will fail. To override this protection use\n`--ignore-missing-task-queues`. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n```\ntemporal worker deployment set-current-version [options]\n```\n\nFor example, to set the Current Version of a deployment\n`YourDeploymentName`, with a version with Build ID `YourBuildID`, and\nin the default namespace:\n\n```\ntemporal worker deployment set-current-version \\\n --version YourDeploymentName.YourBuildID\n```\n\nThe target of set-current-version can also be `__unversioned__`, which\nmoves tasks to unversioned workers, but in this case we also need to\nspecify the Deployment Name.\n\n```\ntemporal worker deployment set-current-version \\\n --version __unversioned__ \\\n --deployment-name YourDeploymentName\n``` " } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVar(&s.DeploymentName, "deployment-name", "", "Deployment name. Only needed when `--version` is `__unversioned__` or empty.") @@ -2780,8 +2761,8 @@ func NewTemporalWorkerDeploymentVersionSetCurrentCommand(cctx *CommandContext, p return &s } -type TemporalWorkerDeploymentVersionSetRampingCommand struct { - Parent *TemporalWorkerDeploymentVersionCommand +type TemporalWorkerDeploymentSetRampingVersionCommand struct { + Parent *TemporalWorkerDeploymentCommand Command cobra.Command DeploymentVersionOptions DeploymentName string @@ -2792,21 +2773,20 @@ type TemporalWorkerDeploymentVersionSetRampingCommand struct { Yes bool } -func NewTemporalWorkerDeploymentVersionSetRampingCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentVersionCommand) *TemporalWorkerDeploymentVersionSetRampingCommand { - var s TemporalWorkerDeploymentVersionSetRampingCommand +func NewTemporalWorkerDeploymentSetRampingVersionCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentSetRampingVersionCommand { + var s TemporalWorkerDeploymentSetRampingVersionCommand s.Parent = parent s.Command.DisableFlagsInUseLine = true - s.Command.Use = "set-ramping [flags]" + s.Command.Use = "set-ramping-version [flags]" s.Command.Short = "Change Version Ramping settings for a Worker Deployment" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSets the Ramping Version and Percentage for a Deployment.\n\nThe Ramping Version can be set to a fully-qualified Version of the form\n\x1b[1mYourDeploymentName.YourBuildID\x1b[0m, or set to \"__unversioned__\", a special\nvalue, which represents all the unversioned workers.\n\nThe Ramping Percentage is a float with values in the range [0, 100].\nA value of 100 does not make the Ramping Version Current, use\n\x1b[1mset-current\x1b[0m instead.\n\nTo remove a Ramping Version use the flag \x1b[1m--delete\x1b[0m and set Percentage\nto 0.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Ramping Version the request will fail. To override this protection use\n\x1b[1m--ignore-missing-task-queues\x1b[0m. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n\x1b[1mtemporal worker deployment version set-ramping [options]\x1b[0m\n\nFor example, to set the Ramping Version of a deployment\n\x1b[1mYourDeploymentName\x1b[0m, with a version with Build ID \x1b[1mYourBuildID\x1b[0m, with\n10 percent of tasks redirected to this version, and\nusing the default namespace:\n\n\x1b[1mtemporal worker deployment version set-ramping \\\n --version YourDeploymentName.YourBuildID\n --percentage 10.0\x1b[0m\n\nAnd to remove that ramping:\n \n\x1b[1mtemporal worker deployment version set-ramping \\\n --version YourDeploymentName.YourBuildID \\\n --percentage 0.0 \\\n --delete\x1b[0m " + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSet the Ramping Version and Percentage for a Deployment.\n\nThe Ramping Version can be set to a fully-qualified Version of the form\n\x1b[1mYourDeploymentName.YourBuildID\x1b[0m, or set to \"__unversioned__\", a special\nvalue that represents all the unversioned workers.\n\nThe Ramping Percentage is a float with values in the range [0, 100].\nA value of 100 does not make the Ramping Version Current, use\n\x1b[1mset-current-version\x1b[0m instead.\n\nTo remove a Ramping Version use the flag \x1b[1m--delete\x1b[0m.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Ramping Version the request will fail. To override this protection use\n\x1b[1m--ignore-missing-task-queues\x1b[0m. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n\x1b[1mtemporal worker deployment set-ramping-version [options]\x1b[0m\n\nFor example, to set the Ramping Version of a deployment\n\x1b[1mYourDeploymentName\x1b[0m, with a version with Build ID \x1b[1mYourBuildID\x1b[0m, with\n10 percent of tasks redirected to this version, and\nusing the default namespace:\n\n\x1b[1mtemporal worker deployment set-ramping-version \\\n --version YourDeploymentName.YourBuildID\n --percentage 10.0\x1b[0m\n\nAnd to remove that ramping:\n \n\x1b[1mtemporal worker deployment set-ramping-version \\\n --version YourDeploymentName.YourBuildID \\\n --delete\x1b[0m " } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSets the Ramping Version and Percentage for a Deployment.\n\nThe Ramping Version can be set to a fully-qualified Version of the form\n`YourDeploymentName.YourBuildID`, or set to \"__unversioned__\", a special\nvalue, which represents all the unversioned workers.\n\nThe Ramping Percentage is a float with values in the range [0, 100].\nA value of 100 does not make the Ramping Version Current, use\n`set-current` instead.\n\nTo remove a Ramping Version use the flag `--delete` and set Percentage\nto 0.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Ramping Version the request will fail. To override this protection use\n`--ignore-missing-task-queues`. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n```\ntemporal worker deployment version set-ramping [options]\n```\n\nFor example, to set the Ramping Version of a deployment\n`YourDeploymentName`, with a version with Build ID `YourBuildID`, with\n10 percent of tasks redirected to this version, and\nusing the default namespace:\n\n```\ntemporal worker deployment version set-ramping \\\n --version YourDeploymentName.YourBuildID\n --percentage 10.0\n```\n\nAnd to remove that ramping:\n \n```\ntemporal worker deployment version set-ramping \\\n --version YourDeploymentName.YourBuildID \\\n --percentage 0.0 \\\n --delete\n``` " + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\n\nSet the Ramping Version and Percentage for a Deployment.\n\nThe Ramping Version can be set to a fully-qualified Version of the form\n`YourDeploymentName.YourBuildID`, or set to \"__unversioned__\", a special\nvalue that represents all the unversioned workers.\n\nThe Ramping Percentage is a float with values in the range [0, 100].\nA value of 100 does not make the Ramping Version Current, use\n`set-current-version` instead.\n\nTo remove a Ramping Version use the flag `--delete`.\n\nIf not all the expected Task Queues are being polled by Workers in the\nnew Ramping Version the request will fail. To override this protection use\n`--ignore-missing-task-queues`. Note that this would ignore task queues\nin a deployment that are not yet discovered, leading to inconsistent task\nqueue configuration.\n\n```\ntemporal worker deployment set-ramping-version [options]\n```\n\nFor example, to set the Ramping Version of a deployment\n`YourDeploymentName`, with a version with Build ID `YourBuildID`, with\n10 percent of tasks redirected to this version, and\nusing the default namespace:\n\n```\ntemporal worker deployment set-ramping-version \\\n --version YourDeploymentName.YourBuildID\n --percentage 10.0\n```\n\nAnd to remove that ramping:\n \n```\ntemporal worker deployment set-ramping-version \\\n --version YourDeploymentName.YourBuildID \\\n --delete\n``` " } s.Command.Args = cobra.NoArgs - s.Command.Flags().StringVar(&s.DeploymentName, "deployment-name", "", "Deployment name. Only needed when `--version` is `__unversioned__` or empty.") - s.Command.Flags().Float32Var(&s.Percentage, "percentage", 0, "Percentage of tasks redirected to the Ramping Version. Valid range [0,100]. Required.") - _ = cobra.MarkFlagRequired(s.Command.Flags(), "percentage") + s.Command.Flags().StringVar(&s.DeploymentName, "deployment-name", "", "Deployment name. Only needed when `--version` is `__unversioned__`.") + s.Command.Flags().Float32Var(&s.Percentage, "percentage", 0, "Percentage of tasks redirected to the Ramping Version. Valid range [0,100].") s.Command.Flags().BoolVar(&s.Delete, "delete", false, "Delete the Ramping Version.") s.Command.Flags().StringVar(&s.Identity, "identity", "", "Identity of the user submitting this request.") s.Command.Flags().BoolVar(&s.IgnoreMissingTaskQueues, "ignore-missing-task-queues", false, "Override protection to accidentally remove task queues.") @@ -2820,6 +2800,37 @@ func NewTemporalWorkerDeploymentVersionSetRampingCommand(cctx *CommandContext, p return &s } +type TemporalWorkerDeploymentUpdateMetadataVersionCommand struct { + Parent *TemporalWorkerDeploymentCommand + Command cobra.Command + DeploymentVersionOptions + Metadata []string + RemoveEntries []string +} + +func NewTemporalWorkerDeploymentUpdateMetadataVersionCommand(cctx *CommandContext, parent *TemporalWorkerDeploymentCommand) *TemporalWorkerDeploymentUpdateMetadataVersionCommand { + var s TemporalWorkerDeploymentUpdateMetadataVersionCommand + s.Parent = parent + s.Command.DisableFlagsInUseLine = true + s.Command.Use = "update-metadata-version [flags]" + s.Command.Short = "Change user-provided metadata for a Version" + if hasHighlighting { + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\nUpdate metadata associated with a Worker Deployment Version.\n\nFor example:\n\n\x1b[1m temporal worker deployment update-metadata-version \\\n --version YourDeploymentName.YourBuildID \\\n --metadata bar=1 \\\n --metadata foo=true\x1b[0m\n\nThe current metadata is also returned with \x1b[1mdescribe-version\x1b[0m:\n \n\x1b[1m temporal worker deployment describe-version \\\n --version YourDeploymentName.YourBuildID \\\x1b[0m " + } else { + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worker Deployment is experimental. Deployment commands are |\n| subject to change. |\n+---------------------------------------------------------------------+\nUpdate metadata associated with a Worker Deployment Version.\n\nFor example:\n\n```\n temporal worker deployment update-metadata-version \\\n --version YourDeploymentName.YourBuildID \\\n --metadata bar=1 \\\n --metadata foo=true\n```\n\nThe current metadata is also returned with `describe-version`:\n \n```\n temporal worker deployment describe-version \\\n --version YourDeploymentName.YourBuildID \\\n``` " + } + s.Command.Args = cobra.NoArgs + s.Command.Flags().StringArrayVar(&s.Metadata, "metadata", nil, "Set deployment metadata using `KEY=\"VALUE\"` pairs. Keys must be identifiers, and values must be JSON values. For example: 'YourKey={\"your\": \"value\"}'. Can be passed multiple times.") + s.Command.Flags().StringArrayVar(&s.RemoveEntries, "remove-entries", nil, "Keys of entries to be deleted from metadata. Can be passed multiple times.") + s.DeploymentVersionOptions.buildFlags(cctx, s.Command.Flags()) + s.Command.Run = func(c *cobra.Command, args []string) { + if err := s.run(cctx, args); err != nil { + cctx.Options.Fail(err) + } + } + return &s +} + type TemporalWorkflowCommand struct { Parent *TemporalCommand Command cobra.Command @@ -3558,9 +3569,8 @@ type TemporalWorkflowUpdateOptionsCommand struct { Parent *TemporalWorkflowCommand Command cobra.Command SingleWorkflowOrBatchOptions - VersioningOverrideBehavior StringEnum - VersioningOverrideSeriesName string - VersioningOverrideBuildId string + VersioningOverrideBehavior StringEnum + VersioningOverridePinnedVersion string } func NewTemporalWorkflowUpdateOptionsCommand(cctx *CommandContext, parent *TemporalWorkflowCommand) *TemporalWorkflowUpdateOptionsCommand { @@ -3570,16 +3580,15 @@ func NewTemporalWorkflowUpdateOptionsCommand(cctx *CommandContext, parent *Tempo s.Command.Use = "update-options [flags]" s.Command.Short = "Change Workflow Execution Options" if hasHighlighting { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worflow update-options is experimental. Workflow Execution |\n| properties are subject to change. |\n+---------------------------------------------------------------------+\n\nModify properties of Workflow Executions:\n\n\x1b[1mtemporal workflow update-options [options]\x1b[0m\n\nIt can override the Worker Deployment configuration of a\nWorkflow Execution, which controls Worker Versioning.\n\nFor example, to force Workers in the current Deployment execute the\nnext Workflow Task change behavior to \x1b[1mauto_upgrade\x1b[0m:\n\n\x1b[1mtemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior auto_upgrade\x1b[0m\n\nor to pin the workflow execution to a Worker Deployment, set behavior\nto \x1b[1mpinned\x1b[0m:\n\n\x1b[1mtemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior pinned \\\n --versioning-override-series-name YourDeploymentSeriesName \\\n --versioning-override-build-id YourDeploymentBuildId\x1b[0m\n\nTo remove any previous overrides, set the behavior to\n\x1b[1munspecified\x1b[0m:\n\n\x1b[1mtemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior unspecified\x1b[0m\n\nTo see the current override use \x1b[1mtemporal workflow describe\x1b[0m" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worflow update-options is experimental. Workflow Execution |\n| properties are subject to change. |\n+---------------------------------------------------------------------+\n\nModify properties of Workflow Executions:\n\n\x1b[1mtemporal workflow update-options [options]\x1b[0m\n\nIt can override the Worker Deployment configuration of a\nWorkflow Execution, which controls Worker Versioning.\n\nFor example, to force Workers in the current Deployment execute the\nnext Workflow Task change behavior to \x1b[1mauto_upgrade\x1b[0m:\n\n\x1b[1mtemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior auto_upgrade\x1b[0m\n\nor to pin the workflow execution to a Worker Deployment, set behavior\nto \x1b[1mpinned\x1b[0m:\n\n\x1b[1mtemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior pinned \\\n --versioning-override-pinned-version \\\n YourDeploymentSeriesName.YourDeploymentBuildId\x1b[0m\n\nTo remove any previous overrides, set the behavior to\n\x1b[1munspecified\x1b[0m:\n\n\x1b[1mtemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior unspecified\x1b[0m\n\nTo see the current override use \x1b[1mtemporal workflow describe\x1b[0m" } else { - s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worflow update-options is experimental. Workflow Execution |\n| properties are subject to change. |\n+---------------------------------------------------------------------+\n\nModify properties of Workflow Executions:\n\n```\ntemporal workflow update-options [options]\n```\n\nIt can override the Worker Deployment configuration of a\nWorkflow Execution, which controls Worker Versioning.\n\nFor example, to force Workers in the current Deployment execute the\nnext Workflow Task change behavior to `auto_upgrade`:\n\n```\ntemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior auto_upgrade\n```\n\nor to pin the workflow execution to a Worker Deployment, set behavior\nto `pinned`:\n\n```\ntemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior pinned \\\n --versioning-override-series-name YourDeploymentSeriesName \\\n --versioning-override-build-id YourDeploymentBuildId\n```\n\nTo remove any previous overrides, set the behavior to\n`unspecified`:\n\n```\ntemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior unspecified\n```\n\nTo see the current override use `temporal workflow describe`" + s.Command.Long = "+---------------------------------------------------------------------+\n| CAUTION: Worflow update-options is experimental. Workflow Execution |\n| properties are subject to change. |\n+---------------------------------------------------------------------+\n\nModify properties of Workflow Executions:\n\n```\ntemporal workflow update-options [options]\n```\n\nIt can override the Worker Deployment configuration of a\nWorkflow Execution, which controls Worker Versioning.\n\nFor example, to force Workers in the current Deployment execute the\nnext Workflow Task change behavior to `auto_upgrade`:\n\n```\ntemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior auto_upgrade\n```\n\nor to pin the workflow execution to a Worker Deployment, set behavior\nto `pinned`:\n\n```\ntemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior pinned \\\n --versioning-override-pinned-version \\\n YourDeploymentSeriesName.YourDeploymentBuildId\n```\n\nTo remove any previous overrides, set the behavior to\n`unspecified`:\n\n```\ntemporal workflow update-options \\\n --workflow-id YourWorkflowId \\\n --versioning-override-behavior unspecified\n```\n\nTo see the current override use `temporal workflow describe`" } s.Command.Args = cobra.NoArgs s.VersioningOverrideBehavior = NewStringEnum([]string{"unspecified", "pinned", "auto_upgrade"}, "") s.Command.Flags().Var(&s.VersioningOverrideBehavior, "versioning-override-behavior", "Override the versioning behavior of a Workflow. Accepted values: unspecified, pinned, auto_upgrade. Required.") _ = cobra.MarkFlagRequired(s.Command.Flags(), "versioning-override-behavior") - s.Command.Flags().StringVar(&s.VersioningOverrideSeriesName, "versioning-override-series-name", "", "Override Series Name for a Worker Deployment (Only for pinned).") - s.Command.Flags().StringVar(&s.VersioningOverrideBuildId, "versioning-override-build-id", "", "Override Build ID for a Worker Deployment (Only for pinned).") + s.Command.Flags().StringVar(&s.VersioningOverridePinnedVersion, "versioning-override-pinned-version", "", "Override Pinned Version for a Worker Deployment (Only for pinned).") s.SingleWorkflowOrBatchOptions.buildFlags(cctx, s.Command.Flags()) s.Command.Run = func(c *cobra.Command, args []string) { if err := s.run(cctx, args); err != nil { diff --git a/temporalcli/commands.worker.deployment.go b/temporalcli/commands.worker.deployment.go index 87476b110..9e09ac343 100644 --- a/temporalcli/commands.worker.deployment.go +++ b/temporalcli/commands.worker.deployment.go @@ -2,10 +2,12 @@ package temporalcli import ( "fmt" + "strings" "time" "github.com/fatih/color" "github.com/temporalio/cli/temporalcli/internal/printer" + "go.temporal.io/api/common/v1" "go.temporal.io/sdk/client" ) @@ -28,19 +30,39 @@ type formattedWorkerDeploymentInfoType struct { Name string `json:"name"` CreateTime time.Time `json:"createTime"` LastModifierIdentity string `json:"lastModifierIdentity"` - RoutingConfig formattedRoutingConfigType `json:"routingConfig,omitempty"` - VersionSummaries []versionSummariesRowType `json:"versionSummaries,omitempty"` + RoutingConfig formattedRoutingConfigType `json:"routingConfig"` + VersionSummaries []versionSummariesRowType `json:"versionSummaries"` } type formattedWorkerDeploymentListEntryType struct { - Name string - CreateTime time.Time - CurrentVersion string `cli:",cardOmitEmpty"` - RampingVersion string `cli:",cardOmitEmpty"` - RampingVersionPercentage float32 `cli:",cardOmitEmpty"` - CurrentVersionChangedTime time.Time `cli:",cardOmitEmpty"` - RampingVersionChangedTime time.Time `cli:",cardOmitEmpty"` - RampingVersionPercentageChangedTime time.Time `cli:",cardOmitEmpty"` + Name string + CreateTime time.Time + CurrentVersion string `cli:",cardOmitEmpty"` + RampingVersion string + RampingVersionPercentage float32 `cli:",cardOmitEmpty"` +} + +type formattedDrainageInfo struct { + DrainageStatus string `json:"drainageStatus"` + LastChangedTime time.Time `json:"lastChangedTime"` + LastCheckedTime time.Time `json:"lastCheckedTime"` +} + +type formattedTaskQueueInfoRowType struct { + Name string `json:"name"` + Type string `json:"type"` +} + +type formattedWorkerDeploymentVersionInfoType struct { + Version string `json:"version"` + CreateTime time.Time `json:"createTime"` + RoutingChangedTime time.Time `json:"routingChangedTime"` + CurrentSinceTime time.Time `json:"currentSinceTime"` + RampingSinceTime time.Time `json:"rampingSinceTime"` + RampPercentage float32 `json:"rampPercentage"` + DrainageInfo formattedDrainageInfo `json:"drainageInfo"` + TaskQueuesInfos []formattedTaskQueueInfoRowType `json:"taskQueuesInfos"` + Metadata map[string]*common.Payload `json:"metadata"` } func drainageStatusToStr(drainage client.WorkerDeploymentVersionDrainageStatus) (string, error) { @@ -142,7 +164,7 @@ func printWorkerDeploymentInfo(cctx *CommandContext, deploymentInfo client.Worke cctx.Printer.Println() cctx.Printer.Println(color.MagentaString("Version Summaries:")) err := cctx.Printer.PrintStructured( - deploymentInfo.VersionSummaries, + fDeploymentInfo.VersionSummaries, printer.StructuredOptions{Table: &printer.TableOptions{}}, ) if err != nil { @@ -157,6 +179,197 @@ func printWorkerDeploymentInfo(cctx *CommandContext, deploymentInfo client.Worke return cctx.Printer.PrintStructured(fDeploymentInfo, printer.StructuredOptions{}) } +func extractDeploymentName(version string, deploymentName string, failNonQualified bool) (string, error) { + if version == "" || version == "__unversioned__" { + if failNonQualified { + return "", fmt.Errorf( + "invalid deployment version type for this operation, use a fully-qualified version", + ) + } + if deploymentName == "" { + return "", fmt.Errorf( + "specify the deployment name with `--deployment-name` with a non-fully-qualified version", + ) + } + return deploymentName, nil + } + splitVersion := strings.SplitN(version, ".", 2) + if len(splitVersion) != 2 { + return "", fmt.Errorf( + "invalid format for worker deployment version %v, not YourDeploymentName.YourBuildID", + version, + ) + } + return splitVersion[0], nil +} + +func formatDrainageInfo(drainageInfo *client.WorkerDeploymentVersionDrainageInfo) (formattedDrainageInfo, error) { + if drainageInfo == nil { + return formattedDrainageInfo{}, nil + } + + drainageStr, err := drainageStatusToStr(drainageInfo.DrainageStatus) + if err != nil { + return formattedDrainageInfo{}, err + } + + return formattedDrainageInfo{ + DrainageStatus: drainageStr, + LastChangedTime: drainageInfo.LastChangedTime, + LastCheckedTime: drainageInfo.LastCheckedTime, + }, nil +} + +func formatTaskQueuesInfos(tqis []client.WorkerDeploymentTaskQueueInfo) ([]formattedTaskQueueInfoRowType, error) { + var tqiRows []formattedTaskQueueInfoRowType + for _, tqi := range tqis { + tqTypeStr, err := taskQueueTypeToStr(tqi.Type) + if err != nil { + return tqiRows, err + } + tqiRows = append(tqiRows, formattedTaskQueueInfoRowType{ + Name: tqi.Name, + Type: tqTypeStr, + }) + } + return tqiRows, nil +} + +func workerDeploymentVersionInfoToRows(deploymentInfo client.WorkerDeploymentVersionInfo) (formattedWorkerDeploymentVersionInfoType, error) { + tqi, err := formatTaskQueuesInfos(deploymentInfo.TaskQueuesInfos) + if err != nil { + return formattedWorkerDeploymentVersionInfoType{}, err + } + + drainage, err := formatDrainageInfo(deploymentInfo.DrainageInfo) + if err != nil { + return formattedWorkerDeploymentVersionInfoType{}, err + } + + return formattedWorkerDeploymentVersionInfoType{ + Version: deploymentInfo.Version, + CreateTime: deploymentInfo.CreateTime, + RoutingChangedTime: deploymentInfo.RoutingChangedTime, + CurrentSinceTime: deploymentInfo.CurrentSinceTime, + RampingSinceTime: deploymentInfo.RampingSinceTime, + RampPercentage: deploymentInfo.RampPercentage, + DrainageInfo: drainage, + TaskQueuesInfos: tqi, + Metadata: deploymentInfo.Metadata, + }, nil +} + +func printWorkerDeploymentVersionInfo(cctx *CommandContext, deploymentInfo client.WorkerDeploymentVersionInfo, msg string) error { + fDeploymentInfo, err := workerDeploymentVersionInfoToRows(deploymentInfo) + if err != nil { + return err + } + + if !cctx.JSONOutput { + cctx.Printer.Println(color.MagentaString(msg)) + var drainageStr string + var drainageLastChangedTime time.Time + var drainageLastCheckedTime time.Time + if deploymentInfo.DrainageInfo != nil { + drainageStr, err = drainageStatusToStr(deploymentInfo.DrainageInfo.DrainageStatus) + if err != nil { + return err + } + drainageLastChangedTime = deploymentInfo.DrainageInfo.LastChangedTime + drainageLastCheckedTime = deploymentInfo.DrainageInfo.LastCheckedTime + } + + printMe := struct { + Version string + CreateTime time.Time + RoutingChangedTime time.Time `cli:",cardOmitEmpty"` + CurrentSinceTime time.Time `cli:",cardOmitEmpty"` + RampingSinceTime time.Time `cli:",cardOmitEmpty"` + RampPercentage float32 + DrainageStatus string `cli:",cardOmitEmpty"` + DrainageLastChangedTime time.Time `cli:",cardOmitEmpty"` + DrainageLastCheckedTime time.Time `cli:",cardOmitEmpty"` + Metadata map[string]*common.Payload `cli:",cardOmitEmpty"` + }{ + Version: deploymentInfo.Version, + CreateTime: deploymentInfo.CreateTime, + RoutingChangedTime: deploymentInfo.RoutingChangedTime, + CurrentSinceTime: deploymentInfo.CurrentSinceTime, + RampingSinceTime: deploymentInfo.RampingSinceTime, + RampPercentage: deploymentInfo.RampPercentage, + DrainageStatus: drainageStr, + DrainageLastChangedTime: drainageLastChangedTime, + DrainageLastCheckedTime: drainageLastCheckedTime, + Metadata: deploymentInfo.Metadata, + } + err := cctx.Printer.PrintStructured(printMe, printer.StructuredOptions{}) + if err != nil { + return fmt.Errorf("displaying worker deployment version info failed: %w", err) + } + + if len(deploymentInfo.TaskQueuesInfos) > 0 { + cctx.Printer.Println() + cctx.Printer.Println(color.MagentaString("Task Queues:")) + err := cctx.Printer.PrintStructured( + fDeploymentInfo.TaskQueuesInfos, + printer.StructuredOptions{Table: &printer.TableOptions{}}, + ) + if err != nil { + return fmt.Errorf("displaying task queues failed: %w", err) + } + } + + return nil + } + + // json output + return cctx.Printer.PrintStructured(fDeploymentInfo, printer.StructuredOptions{}) +} + +type getDeploymentConflictTokenOptions struct { + safeMode bool + safeModeMessage string + deploymentName string +} + +func (c *TemporalWorkerDeploymentCommand) getConflictToken(cctx *CommandContext, options *getDeploymentConflictTokenOptions) ([]byte, error) { + cl, err := c.Parent.ClientOptions.dialClient(cctx) + if err != nil { + return nil, err + } + defer cl.Close() + + dHandle := cl.WorkerDeploymentClient().GetHandle(options.deploymentName) + + resp, err := dHandle.Describe(cctx, client.WorkerDeploymentDescribeOptions{}) + if err != nil { + return nil, fmt.Errorf("unable to get deployment conflict token: %w", err) + } + + if options.safeMode { + // duplicate `cctx.promptYes` check to avoid printing deployment info with json + if cctx.JSONOutput { + return nil, fmt.Errorf("must bypass prompts when using JSON output") + } + err = printWorkerDeploymentInfo(cctx, resp.Info, "Worker Deployment Before Update:") + if err != nil { + return nil, fmt.Errorf("displaying deployment failed: %w", err) + } + + yes, err := cctx.promptYes( + fmt.Sprintf("Continue with set %v? y/N", options.safeModeMessage), + false, + ) + if err != nil { + return nil, err + } else if !yes { + return nil, fmt.Errorf("user denied confirmation") + } + } + + return resp.ConflictToken, nil +} + func (c *TemporalWorkerDeploymentDescribeCommand) run(cctx *CommandContext, args []string) error { cl, err := c.Parent.Parent.ClientOptions.dialClient(cctx) if err != nil { @@ -237,16 +450,17 @@ func (c *TemporalWorkerDeploymentListCommand) run(cctx *CommandContext, args []s // For JSON dump one line of JSON per deployment _ = cctx.Printer.PrintStructured(listEntry, printer.StructuredOptions{}) } else { + rampingVersion := "" + if listEntry.RoutingConfig.RampingVersion != "" { + rampingVersion = listEntry.RoutingConfig.RampingVersion + } // For non-JSON, we are doing a table for each page page = append(page, &formattedWorkerDeploymentListEntryType{ - Name: listEntry.Name, - CreateTime: listEntry.CreateTime, - CurrentVersion: listEntry.RoutingConfig.CurrentVersion, - RampingVersion: listEntry.RoutingConfig.RampingVersion, - RampingVersionPercentage: listEntry.RoutingConfig.RampingVersionPercentage, - CurrentVersionChangedTime: listEntry.RoutingConfig.CurrentVersionChangedTime, - RampingVersionChangedTime: listEntry.RoutingConfig.RampingVersionChangedTime, - RampingVersionPercentageChangedTime: listEntry.RoutingConfig.RampingVersionPercentageChangedTime, + Name: listEntry.Name, + CreateTime: listEntry.CreateTime, + CurrentVersion: listEntry.RoutingConfig.CurrentVersion, + RampingVersion: rampingVersion, + RampingVersionPercentage: listEntry.RoutingConfig.RampingVersionPercentage, }) if len(page) == cap(page) { _ = cctx.Printer.PrintStructured(page, printTableOpts) @@ -263,3 +477,185 @@ func (c *TemporalWorkerDeploymentListCommand) run(cctx *CommandContext, args []s return nil } + +func (c *TemporalWorkerDeploymentDeleteVersionCommand) run(cctx *CommandContext, args []string) error { + cl, err := c.Parent.Parent.ClientOptions.dialClient(cctx) + if err != nil { + return err + } + defer cl.Close() + + name, err := extractDeploymentName(c.Version, "", true) + if err != nil { + return err + } + + dHandle := cl.WorkerDeploymentClient().GetHandle(name) + _, err = dHandle.DeleteVersion(cctx, client.WorkerDeploymentDeleteVersionOptions{ + Version: c.Version, + SkipDrainage: c.SkipDrainage, + Identity: c.Identity, + }) + if err != nil { + return fmt.Errorf("error deleting worker deployment version: %w", err) + } + + cctx.Printer.Println("Successfully deleted worker deployment version") + return nil +} + +func (c *TemporalWorkerDeploymentDescribeVersionCommand) run(cctx *CommandContext, args []string) error { + cl, err := c.Parent.Parent.ClientOptions.dialClient(cctx) + if err != nil { + return err + } + defer cl.Close() + + name, err := extractDeploymentName(c.Version, "", true) + if err != nil { + return err + } + + dHandle := cl.WorkerDeploymentClient().GetHandle(name) + + resp, err := dHandle.DescribeVersion(cctx, client.WorkerDeploymentDescribeVersionOptions{ + Version: c.Version, + }) + if err != nil { + return fmt.Errorf("error describing worker deployment version: %w", err) + } + + err = printWorkerDeploymentVersionInfo(cctx, resp.Info, "Worker Deployment Version:") + if err != nil { + return err + } + + return nil +} + +func (c *TemporalWorkerDeploymentSetCurrentVersionCommand) run(cctx *CommandContext, args []string) error { + cl, err := c.Parent.Parent.dialClient(cctx) + if err != nil { + return err + } + defer cl.Close() + + name, err := extractDeploymentName(c.Version, c.DeploymentName, false) + if err != nil { + return err + } + + token, err := c.Parent.getConflictToken(cctx, &getDeploymentConflictTokenOptions{ + safeMode: !c.Yes, + safeModeMessage: "Current", + deploymentName: name, + }) + if err != nil { + return err + } + + dHandle := cl.WorkerDeploymentClient().GetHandle(name) + _, err = dHandle.SetCurrentVersion(cctx, client.WorkerDeploymentSetCurrentVersionOptions{ + Version: c.Version, + Identity: c.Identity, + IgnoreMissingTaskQueues: c.IgnoreMissingTaskQueues, + ConflictToken: token, + }) + if err != nil { + return fmt.Errorf("error setting the current worker deployment version: %w", err) + } + + cctx.Printer.Println("Successfully setting the current worker deployment version") + return nil +} + +func (c *TemporalWorkerDeploymentSetRampingVersionCommand) run(cctx *CommandContext, args []string) error { + cl, err := c.Parent.Parent.ClientOptions.dialClient(cctx) + if err != nil { + return err + } + defer cl.Close() + + name, err := extractDeploymentName(c.Version, c.DeploymentName, false) + if err != nil { + return err + } + + token, err := c.Parent.getConflictToken(cctx, &getDeploymentConflictTokenOptions{ + safeMode: !c.Yes, + safeModeMessage: "Ramping", + deploymentName: name, + }) + if err != nil { + return err + } + + version := c.Version + percentage := c.Percentage + if c.Delete { + version = "" + percentage = 0.0 + } + + dHandle := cl.WorkerDeploymentClient().GetHandle(name) + _, err = dHandle.SetRampingVersion(cctx, client.WorkerDeploymentSetRampingVersionOptions{ + Version: version, + Percentage: percentage, + ConflictToken: token, + Identity: c.Identity, + IgnoreMissingTaskQueues: c.IgnoreMissingTaskQueues, + }) + if err != nil { + return fmt.Errorf("error setting the ramping worker deployment version: %w", err) + } + + cctx.Printer.Println("Successfully setting the ramping worker deployment version") + return nil +} + +func (c *TemporalWorkerDeploymentUpdateMetadataVersionCommand) run(cctx *CommandContext, args []string) error { + cl, err := c.Parent.Parent.ClientOptions.dialClient(cctx) + if err != nil { + return err + } + defer cl.Close() + + name, err := extractDeploymentName(c.Version, "", true) + if err != nil { + return err + } + + metadata, err := stringKeysJSONValues(c.Metadata, false) + if err != nil { + return fmt.Errorf("invalid metadata values: %w", err) + } + + dHandle := cl.WorkerDeploymentClient().GetHandle(name) + response, err := dHandle.UpdateVersionMetadata(cctx, client.WorkerDeploymentUpdateVersionMetadataOptions{ + Version: c.Version, + MetadataUpdate: client.WorkerDeploymentMetadataUpdate{ + UpsertEntries: metadata, + RemoveEntries: c.RemoveEntries, + }, + }) + + if err != nil { + return err + } + + cctx.Printer.Println(color.MagentaString("Metadata:")) + printMe := struct { + Metadata map[string]*common.Payload `cli:",cardOmitEmpty"` + }{ + Metadata: response.Metadata, + } + + err = cctx.Printer.PrintStructured(printMe, printer.StructuredOptions{}) + if err != nil { + return fmt.Errorf("displaying metadata failed: %w", err) + } + + cctx.Printer.Println("Successfully updating metadata for worker deployment version") + + return nil +} diff --git a/temporalcli/commands.worker.deployment.version.go b/temporalcli/commands.worker.deployment.version.go deleted file mode 100644 index 4f4732946..000000000 --- a/temporalcli/commands.worker.deployment.version.go +++ /dev/null @@ -1,352 +0,0 @@ -package temporalcli - -import ( - "fmt" - "strings" - "time" - - "github.com/fatih/color" - "github.com/temporalio/cli/temporalcli/internal/printer" - "go.temporal.io/api/common/v1" - "go.temporal.io/sdk/client" -) - -type formattedDrainageInfo struct { - DrainageStatus string `json:"drainageStatus"` - LastChangedTime time.Time `json:"lastChangedTime"` - LastCheckedTime time.Time `json:"lastCheckedTime"` -} - -type formattedTaskQueueInfoRowType struct { - Name string `json:"name"` - Type string `json:"type"` -} - -type formattedWorkerDeploymentVersionInfoType struct { - Version string `json:"version"` - CreateTime time.Time `json:"createTime"` - RoutingChangedTime time.Time `json:"routingChangedTime"` - CurrentSinceTime time.Time `json:"currentSinceTime"` - RampingSinceTime time.Time `json:"rampingSinceTime"` - RampPercentage float32 `json:"rampPercentage"` - DrainageInfo formattedDrainageInfo `json:"drainageInfo,omitempty"` - TaskQueuesInfos []formattedTaskQueueInfoRowType `json:"taskQueuesInfos,omitempty"` - Metadata map[string]*common.Payload `json:"metadata,omitempty"` -} - -func extractDeploymentName(version string, deploymentName string, failNonQualified bool) (string, error) { - if version == "" || version == "__unversioned__" { - if failNonQualified { - return "", fmt.Errorf( - "invalid deployment version type for this operation, use a fully-qualified version", - ) - } - if deploymentName == "" { - return "", fmt.Errorf( - "specify the deployment name with `--deployment-name` with a non-fully-qualified version", - ) - } - return deploymentName, nil - } - splitVersion := strings.SplitN(version, ".", 2) - if len(splitVersion) != 2 { - return "", fmt.Errorf( - "invalid format for worker deployment version %v, not YourDeploymentName.YourBuildID", - version, - ) - } - return splitVersion[0], nil -} - -func formatDrainageInfo(drainageInfo *client.WorkerDeploymentVersionDrainageInfo) (formattedDrainageInfo, error) { - if drainageInfo == nil { - return formattedDrainageInfo{}, nil - } - - drainageStr, err := drainageStatusToStr(drainageInfo.DrainageStatus) - if err != nil { - return formattedDrainageInfo{}, err - } - - return formattedDrainageInfo{ - DrainageStatus: drainageStr, - LastChangedTime: drainageInfo.LastChangedTime, - LastCheckedTime: drainageInfo.LastCheckedTime, - }, nil -} - -func formatTaskQueuesInfos(tqis []client.WorkerDeploymentTaskQueueInfo) ([]formattedTaskQueueInfoRowType, error) { - var tqiRows []formattedTaskQueueInfoRowType - for _, tqi := range tqis { - tqTypeStr, err := taskQueueTypeToStr(tqi.Type) - if err != nil { - return tqiRows, err - } - tqiRows = append(tqiRows, formattedTaskQueueInfoRowType{ - Name: tqi.Name, - Type: tqTypeStr, - }) - } - return tqiRows, nil -} - -func workerDeploymentVersionInfoToRows(deploymentInfo client.WorkerDeploymentVersionInfo) (formattedWorkerDeploymentVersionInfoType, error) { - tqi, err := formatTaskQueuesInfos(deploymentInfo.TaskQueuesInfos) - if err != nil { - return formattedWorkerDeploymentVersionInfoType{}, err - } - - drainage, err := formatDrainageInfo(deploymentInfo.DrainageInfo) - if err != nil { - return formattedWorkerDeploymentVersionInfoType{}, err - } - - return formattedWorkerDeploymentVersionInfoType{ - Version: deploymentInfo.Version, - CreateTime: deploymentInfo.CreateTime, - RoutingChangedTime: deploymentInfo.RoutingChangedTime, - CurrentSinceTime: deploymentInfo.CurrentSinceTime, - RampingSinceTime: deploymentInfo.RampingSinceTime, - RampPercentage: deploymentInfo.RampPercentage, - DrainageInfo: drainage, - TaskQueuesInfos: tqi, - Metadata: deploymentInfo.Metadata, - }, nil -} - -func printWorkerDeploymentVersionInfo(cctx *CommandContext, deploymentInfo client.WorkerDeploymentVersionInfo, msg string) error { - fDeploymentInfo, err := workerDeploymentVersionInfoToRows(deploymentInfo) - if err != nil { - return err - } - - if !cctx.JSONOutput { - cctx.Printer.Println(color.MagentaString(msg)) - var drainageStr string - var drainageLastChangedTime time.Time - var drainageLastCheckedTime time.Time - if deploymentInfo.DrainageInfo != nil { - drainageStr, err = drainageStatusToStr(deploymentInfo.DrainageInfo.DrainageStatus) - if err != nil { - return err - } - drainageLastChangedTime = deploymentInfo.DrainageInfo.LastChangedTime - drainageLastCheckedTime = deploymentInfo.DrainageInfo.LastCheckedTime - } - - printMe := struct { - Version string - CreateTime time.Time - RoutingChangedTime time.Time `cli:",cardOmitEmpty"` - CurrentSinceTime time.Time `cli:",cardOmitEmpty"` - RampingSinceTime time.Time `cli:",cardOmitEmpty"` - RampPercentage float32 - DrainageStatus string `cli:",cardOmitEmpty"` - DrainageLastChangedTime time.Time `cli:",cardOmitEmpty"` - DrainageLastCheckedTime time.Time `cli:",cardOmitEmpty"` - }{ - Version: deploymentInfo.Version, - CreateTime: deploymentInfo.CreateTime, - RoutingChangedTime: deploymentInfo.RoutingChangedTime, - CurrentSinceTime: deploymentInfo.CurrentSinceTime, - RampingSinceTime: deploymentInfo.RampingSinceTime, - RampPercentage: deploymentInfo.RampPercentage, - DrainageStatus: drainageStr, - DrainageLastChangedTime: drainageLastChangedTime, - DrainageLastCheckedTime: drainageLastCheckedTime, - } - err := cctx.Printer.PrintStructured(printMe, printer.StructuredOptions{}) - if err != nil { - return fmt.Errorf("displaying worker deployment version info failed: %w", err) - } - - if len(deploymentInfo.TaskQueuesInfos) > 0 { - cctx.Printer.Println() - cctx.Printer.Println(color.MagentaString("Task Queues:")) - err := cctx.Printer.PrintStructured( - deploymentInfo.TaskQueuesInfos, - printer.StructuredOptions{Table: &printer.TableOptions{}}, - ) - if err != nil { - return fmt.Errorf("displaying task queues failed: %w", err) - } - } - - // TODO(antlai-temporal): Print metadata - - return nil - } - - // json output - return cctx.Printer.PrintStructured(fDeploymentInfo, printer.StructuredOptions{}) -} - -type getDeploymentConflictTokenOptions struct { - safeMode bool - safeModeMessage string - deploymentName string -} - -func (c *TemporalWorkerDeploymentVersionCommand) getConflictToken(cctx *CommandContext, options *getDeploymentConflictTokenOptions) ([]byte, error) { - cl, err := c.Parent.Parent.ClientOptions.dialClient(cctx) - if err != nil { - return nil, err - } - defer cl.Close() - - dHandle := cl.WorkerDeploymentClient().GetHandle(options.deploymentName) - - resp, err := dHandle.Describe(cctx, client.WorkerDeploymentDescribeOptions{}) - if err != nil { - return nil, fmt.Errorf("unable to get deployment conflict token: %w", err) - } - - if options.safeMode { - // duplicate `cctx.promptYes` check to avoid printing current rules with json - if cctx.JSONOutput { - return nil, fmt.Errorf("must bypass prompts when using JSON output") - } - err = printWorkerDeploymentInfo(cctx, resp.Info, "Worker Deployment Before Update:") - if err != nil { - return nil, fmt.Errorf("displaying deployment failed: %w", err) - } - - yes, err := cctx.promptYes( - fmt.Sprintf("Continue with set %v? y/N", options.safeModeMessage), false) - if err != nil { - return nil, err - } else if !yes { - return nil, fmt.Errorf("user denied confirmation") - } - } - - return resp.ConflictToken, nil -} - -func (c *TemporalWorkerDeploymentVersionDeleteCommand) run(cctx *CommandContext, args []string) error { - cl, err := c.Parent.Parent.Parent.ClientOptions.dialClient(cctx) - if err != nil { - return err - } - defer cl.Close() - - name, err := extractDeploymentName(c.Version, "", true) - if err != nil { - return err - } - - dHandle := cl.WorkerDeploymentClient().GetHandle(name) - _, err = dHandle.DeleteVersion(cctx, client.WorkerDeploymentDeleteVersionOptions{ - Version: c.Version, - SkipDrainage: c.SkipDrainage, - Identity: c.Identity, - }) - if err != nil { - return fmt.Errorf("error deleting worker deployment version: %w", err) - } - - cctx.Printer.Println("Successfully deleted worker deployment version") - return nil -} - -func (c *TemporalWorkerDeploymentVersionDescribeCommand) run(cctx *CommandContext, args []string) error { - cl, err := c.Parent.Parent.Parent.ClientOptions.dialClient(cctx) - if err != nil { - return err - } - defer cl.Close() - - name, err := extractDeploymentName(c.Version, "", true) - if err != nil { - return err - } - - dHandle := cl.WorkerDeploymentClient().GetHandle(name) - - resp, err := dHandle.DescribeVersion(cctx, client.WorkerDeploymentDescribeVersionOptions{ - Version: c.Version, - }) - if err != nil { - return fmt.Errorf("error describing worker deployment version: %w", err) - } - - err = printWorkerDeploymentVersionInfo(cctx, resp.Info, "Worker Deployment Version:") - if err != nil { - return err - } - - return nil -} - -func (c *TemporalWorkerDeploymentVersionSetCurrentCommand) run(cctx *CommandContext, args []string) error { - cl, err := c.Parent.Parent.Parent.dialClient(cctx) - if err != nil { - return err - } - defer cl.Close() - - name, err := extractDeploymentName(c.Version, c.DeploymentName, false) - if err != nil { - return err - } - - token, err := c.Parent.getConflictToken(cctx, &getDeploymentConflictTokenOptions{ - safeMode: !c.Yes, - safeModeMessage: "Current", - deploymentName: name, - }) - if err != nil { - return err - } - - dHandle := cl.WorkerDeploymentClient().GetHandle(name) - _, err = dHandle.SetCurrentVersion(cctx, client.WorkerDeploymentSetCurrentVersionOptions{ - Version: c.Version, - Identity: c.Identity, - IgnoreMissingTaskQueues: c.IgnoreMissingTaskQueues, - ConflictToken: token, - }) - if err != nil { - return fmt.Errorf("error setting the current worker deployment version: %w", err) - } - - cctx.Printer.Println("Successfully setting the current worker deployment version") - return nil -} - -func (c *TemporalWorkerDeploymentVersionSetRampingCommand) run(cctx *CommandContext, args []string) error { - cl, err := c.Parent.Parent.Parent.ClientOptions.dialClient(cctx) - if err != nil { - return err - } - defer cl.Close() - - name, err := extractDeploymentName(c.Version, c.DeploymentName, false) - if err != nil { - return err - } - - token, err := c.Parent.getConflictToken(cctx, &getDeploymentConflictTokenOptions{ - safeMode: !c.Yes, - safeModeMessage: "Ramping", - deploymentName: name, - }) - if err != nil { - return err - } - - dHandle := cl.WorkerDeploymentClient().GetHandle(name) - _, err = dHandle.SetRampingVersion(cctx, client.WorkerDeploymentSetRampingVersionOptions{ - Version: c.Version, - Percentage: c.Percentage, - ConflictToken: token, - Identity: c.Identity, - IgnoreMissingTaskQueues: c.IgnoreMissingTaskQueues, - }) - if err != nil { - return fmt.Errorf("error setting the ramping worker deployment version: %w", err) - } - - cctx.Printer.Println("Successfully setting the ramping worker deployment version") - return nil -} diff --git a/temporalcli/commands.worker.deployment_test.go b/temporalcli/commands.worker.deployment_test.go index c19eb5978..3ebdcbddc 100644 --- a/temporalcli/commands.worker.deployment_test.go +++ b/temporalcli/commands.worker.deployment_test.go @@ -1,30 +1,67 @@ package temporalcli_test import ( + "encoding/base64" + "encoding/json" + "fmt" + "sort" + "strings" "time" + "github.com/google/uuid" + "github.com/stretchr/testify/assert" "go.temporal.io/api/common/v1" + "go.temporal.io/sdk/worker" + "go.temporal.io/sdk/workflow" ) -type jsonTaskQueuesInfosRowType struct { - Name string `json:"name"` - Type string `json:"type"` - FirstPollerTime time.Time `json:"firstPollerTime"` +type jsonVersionSummariesRowType struct { + Version string `json:"version"` + DrainageStatus string `json:"drainageStatus"` + CreateTime time.Time `json:"createTime"` } -type jsonDeploymentType struct { - SeriesName string `json:"seriesName"` - BuildID string `json:"buildId"` +type jsonRoutingConfigType struct { + CurrentVersion string `json:"currentVersion"` + RampingVersion string `json:"rampingVersion"` + RampingVersionPercentage float32 `json:"rampingVersionPercentage"` + CurrentVersionChangedTime time.Time `json:"currentVersionChangedTime"` + RampingVersionChangedTime time.Time `json:"rampingVersionChangedTime"` + RampingVersionPercentageChangedTime time.Time `json:"rampingVersionPercentageChangedTime"` } type jsonDeploymentInfoType struct { - Deployment jsonDeploymentType `json:"deployment"` - CreateTime time.Time `json:"createTime"` - IsCurrent bool `json:"isCurrent"` - TaskQueuesInfos []jsonTaskQueuesInfosRowType `json:"taskQueuesInfos,omitempty"` - Metadata map[string]*common.Payload `json:"metadata,omitempty"` + Name string `json:"name"` + CreateTime time.Time `json:"createTime"` + LastModifierIdentity string `json:"lastModifierIdentity"` + RoutingConfig jsonRoutingConfigType `json:"routingConfig"` + VersionSummaries []jsonVersionSummariesRowType `json:"versionSummaries"` } +type jsonDrainageInfo struct { + DrainageStatus string `json:"drainageStatus"` + LastChangedTime time.Time `json:"lastChangedTime"` + LastCheckedTime time.Time `json:"lastCheckedTime"` +} + +type jsonTaskQueueInfoRowType struct { + Name string `json:"name"` + Type string `json:"type"` +} + +type jsonDeploymentVersionInfoType struct { + Version string `json:"version"` + CreateTime time.Time `json:"createTime"` + RoutingChangedTime time.Time `json:"routingChangedTime"` + CurrentSinceTime time.Time `json:"currentSinceTime"` + RampingSinceTime time.Time `json:"rampingSinceTime"` + RampPercentage float32 `json:"rampPercentage"` + DrainageInfo jsonDrainageInfo `json:"drainageInfo"` + TaskQueuesInfos []jsonTaskQueueInfoRowType `json:"taskQueuesInfos"` + Metadata map[string]*common.Payload `json:"metadata"` +} + +/* type jsonDeploymentReachabilityInfoType struct { DeploymentInfo jsonDeploymentInfoType `json:"deploymentInfo"` Reachability string `json:"reachability"` @@ -36,154 +73,480 @@ type jsonDeploymentListEntryType struct { CreateTime time.Time `json:"createTime"` IsCurrent bool `json:"isCurrent"` } +*/ -/* -func (s *SharedServerSuite) TestDeployment_Set_Current() { - seriesName := uuid.NewString() +func (s *SharedServerSuite) TestDeployment_Set_Current_Version() { + deploymentName := uuid.NewString() buildId := uuid.NewString() + version := deploymentName + "." + buildId + w := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: version, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + }, + }, + }) + defer w.Stop() + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "list", + "--address", s.Address(), + ) + assert.NoError(t, res.Err) + assert.Contains(t, res.Stdout.String(), deploymentName) + }, 30*time.Second, 100*time.Millisecond) + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version, + ) + assert.NoError(t, res.Err) + }, 30*time.Second, 100*time.Millisecond) res := s.Execute( - "worker", "deployment", "set-current", + "worker", "deployment", "set-current-version", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId, - "--metadata", "bar=1", + "--version", version, + "--yes", ) s.NoError(res.Err) res = s.Execute( - "worker", "deployment", "get-current", + "worker", "deployment", "describe", "--address", s.Address(), - "--series-name", seriesName, + "--name", deploymentName, ) s.NoError(res.Err) - s.ContainsOnSameLine(res.Stdout.String(), "SeriesName", seriesName) - s.ContainsOnSameLine(res.Stdout.String(), "BuildID", buildId) - s.ContainsOnSameLine(res.Stdout.String(), "IsCurrent", "true") - s.ContainsOnSameLine(res.Stdout.String(), "Metadata", "data:\"1\"") + s.ContainsOnSameLine(res.Stdout.String(), "Name", deploymentName) + s.ContainsOnSameLine(res.Stdout.String(), "CurrentVersion", version) // json res = s.Execute( - "worker", "deployment", "get-current", + "worker", "deployment", "describe", "--address", s.Address(), - "--series-name", seriesName, + "--name", deploymentName, "--output", "json", ) s.NoError(res.Err) var jsonOut jsonDeploymentInfoType s.NoError(json.Unmarshal(res.Stdout.Bytes(), &jsonOut)) - s.Equal(jsonDeploymentType{SeriesName: seriesName, BuildID: buildId}, jsonOut.Deployment) - s.True(jsonOut.IsCurrent) + s.Equal(deploymentName, jsonOut.Name) + s.Equal(version, jsonOut.RoutingConfig.CurrentVersion) + + // set metadata + res = s.Execute( + "worker", "deployment", "update-metadata-version", + "--address", s.Address(), + "--version", version, + "--metadata", "bar=1", + "--output", "json", + ) + s.NoError(res.Err) + var jsonVersionOut jsonDeploymentVersionInfoType + s.NoError(json.Unmarshal(res.Stdout.Bytes(), &jsonVersionOut)) + // "1" is "MQ==" - s.Equal("MQ==", base64.StdEncoding.EncodeToString(jsonOut.Metadata["bar"].GetData())) + s.Equal("MQ==", base64.StdEncoding.EncodeToString(jsonVersionOut.Metadata["bar"].GetData())) // "json/plain" is "anNvbi9wbGFpbg==" - s.Equal("anNvbi9wbGFpbg==", base64.StdEncoding.EncodeToString(jsonOut.Metadata["bar"].GetMetadata()["encoding"])) + s.Equal("anNvbi9wbGFpbg==", base64.StdEncoding.EncodeToString(jsonVersionOut.Metadata["bar"].GetMetadata()["encoding"])) + + // remove metadata + res = s.Execute( + "worker", "deployment", "update-metadata-version", + "--address", s.Address(), + "--version", version, + "--remove-entries", "bar", + "--output", "json", + ) + s.NoError(res.Err) + + res = s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version, + "--output", "json", + ) + s.NoError(res.Err) + s.NoError(json.Unmarshal(res.Stdout.Bytes(), &jsonVersionOut)) + s.Nil(jsonVersionOut.Metadata) +} + +func filterByNamePrefix(jsonOut []jsonDeploymentInfoType, prefix string) []jsonDeploymentInfoType { + result := []jsonDeploymentInfoType{} + for i := range jsonOut { + if strings.HasPrefix(jsonOut[i].Name, prefix) { + result = append(result, jsonOut[i]) + } + } + return result } func (s *SharedServerSuite) TestDeployment_List() { - seriesName := uuid.NewString() + prefix := uuid.NewString() + deploymentName1 := prefix + "a" + uuid.NewString() + deploymentName2 := prefix + "b" + uuid.NewString() buildId1 := uuid.NewString() buildId2 := uuid.NewString() + version1 := deploymentName1 + "." + buildId1 + version2 := deploymentName2 + "." + buildId2 + + w1 := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: version1, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + }, + }, + }) + defer w1.Stop() + + w2 := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: version2, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + }, + }, + }) + defer w2.Stop() + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "list", + "--address", s.Address(), + ) + assert.NoError(t, res.Err) + assert.Contains(t, res.Stdout.String(), deploymentName1) + assert.Contains(t, res.Stdout.String(), deploymentName2) + }, 30*time.Second, 100*time.Millisecond) + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version1, + ) + assert.NoError(t, res.Err) + res = s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version2, + ) + assert.NoError(t, res.Err) + }, 30*time.Second, 100*time.Millisecond) res := s.Execute( - "worker", "deployment", "set-current", + "worker", "deployment", "set-current-version", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId1, + "--version", version1, + "--yes", ) s.NoError(res.Err) res = s.Execute( - "worker", "deployment", "set-current", + "worker", "deployment", "set-current-version", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId2, + "--version", version2, + "--yes", ) s.NoError(res.Err) res = s.Execute( "worker", "deployment", "list", "--address", s.Address(), - "--series-name", seriesName, ) s.NoError(res.Err) - s.ContainsOnSameLine(res.Stdout.String(), seriesName, buildId1, "false") - s.ContainsOnSameLine(res.Stdout.String(), seriesName, buildId2, "true") + s.ContainsOnSameLine(res.Stdout.String(), deploymentName1, version1) + s.ContainsOnSameLine(res.Stdout.String(), deploymentName2, version2) // json res = s.Execute( "worker", "deployment", "list", "--address", s.Address(), - "--series-name", seriesName, "--output", "json", ) s.NoError(res.Err) - var jsonOut []jsonDeploymentListEntryType + var jsonOut []jsonDeploymentInfoType s.NoError(json.Unmarshal(res.Stdout.Bytes(), &jsonOut)) + jsonOut = filterByNamePrefix(jsonOut, prefix) sort.Slice(jsonOut, func(i, j int) bool { - return jsonOut[i].CreateTime.Before(jsonOut[j].CreateTime) + return jsonOut[i].Name < jsonOut[j].Name }) - s.Equal(len(jsonOut), 2) - s.Equal(jsonDeploymentType{SeriesName: seriesName, BuildID: buildId1}, jsonOut[0].Deployment) - s.True(!jsonOut[0].IsCurrent) - s.Equal(jsonDeploymentType{SeriesName: seriesName, BuildID: buildId2}, jsonOut[1].Deployment) - s.True(jsonOut[1].IsCurrent) + s.Equal(2, len(jsonOut)) + s.Equal(deploymentName1, jsonOut[0].Name) + s.Equal(version1, jsonOut[0].RoutingConfig.CurrentVersion) + s.Equal(deploymentName2, jsonOut[1].Name) + s.Equal(version2, jsonOut[1].RoutingConfig.CurrentVersion) } -func (s *SharedServerSuite) TestDeployment_Describe_Reachability() { - seriesName := uuid.NewString() - buildId1 := uuid.NewString() - buildId2 := uuid.NewString() +func (s *SharedServerSuite) TestDeployment_Describe_Drainage() { + deploymentName := uuid.NewString() + buildId1 := "a" + uuid.NewString() + buildId2 := "b" + uuid.NewString() + version1 := deploymentName + "." + buildId1 + version2 := deploymentName + "." + buildId2 + + w1 := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: version1, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + }, + }, + }) + defer w1.Stop() + + w2 := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: version2, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + }, + }, + }) + defer w2.Stop() + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "list", + "--address", s.Address(), + ) + assert.NoError(t, res.Err) + assert.Contains(t, res.Stdout.String(), deploymentName) + }, 30*time.Second, 100*time.Millisecond) + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version1, + ) + assert.NoError(t, res.Err) + res = s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version2, + ) + assert.NoError(t, res.Err) + }, 30*time.Second, 100*time.Millisecond) res := s.Execute( - "worker", "deployment", "set-current", + "worker", "deployment", "set-current-version", + "--address", s.Address(), + "--version", version1, + "--yes", + ) + s.NoError(res.Err) + + res = s.Execute( + "worker", "deployment", "describe", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId1, + "--name", deploymentName, ) s.NoError(res.Err) + s.ContainsOnSameLine(res.Stdout.String(), "CurrentVersion", version1) + fmt.Print("hello") res = s.Execute( - "worker", "deployment", "set-current", + "worker", "deployment", "set-current-version", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId2, + "--version", version2, + "--yes", ) s.NoError(res.Err) res = s.Execute( "worker", "deployment", "describe", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId1, - "--report-reachability", + "--name", deploymentName, ) s.NoError(res.Err) - s.ContainsOnSameLine(res.Stdout.String(), "SeriesName", seriesName) - s.ContainsOnSameLine(res.Stdout.String(), "BuildID", buildId1) - s.ContainsOnSameLine(res.Stdout.String(), "IsCurrent", "false") - s.ContainsOnSameLine(res.Stdout.String(), "Reachability", "unreachable") + s.ContainsOnSameLine(res.Stdout.String(), "CurrentVersion", version2) + s.ContainsOnSameLine(res.Stdout.String(), version1, "draining") + s.ContainsOnSameLine(res.Stdout.String(), version2, "unspecified") // json res = s.Execute( "worker", "deployment", "describe", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId2, - "--report-reachability", + "--name", deploymentName, "--output", "json", ) s.NoError(res.Err) - var jsonOut jsonDeploymentReachabilityInfoType + var jsonOut jsonDeploymentInfoType s.NoError(json.Unmarshal(res.Stdout.Bytes(), &jsonOut)) - s.Equal(jsonDeploymentType{SeriesName: seriesName, BuildID: buildId2}, jsonOut.DeploymentInfo.Deployment) - s.True(jsonOut.DeploymentInfo.IsCurrent) - s.Equal(jsonOut.Reachability, "reachable") + s.Equal(deploymentName, jsonOut.Name) + sort.Slice(jsonOut.VersionSummaries, func(i, j int) bool { + return jsonOut.VersionSummaries[i].Version < jsonOut.VersionSummaries[j].Version + }) + + s.Equal(2, len(jsonOut.VersionSummaries)) + s.Equal("draining", jsonOut.VersionSummaries[0].DrainageStatus) + s.Equal(version1, jsonOut.VersionSummaries[0].Version) + s.Equal("unspecified", jsonOut.VersionSummaries[1].DrainageStatus) + s.Equal(version2, jsonOut.VersionSummaries[1].Version) +} + +func (s *SharedServerSuite) TestDeployment_Ramping() { + deploymentName := uuid.NewString() + buildId1 := "a" + uuid.NewString() + buildId2 := "b" + uuid.NewString() + version1 := deploymentName + "." + buildId1 + version2 := deploymentName + "." + buildId2 + + w1 := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: version1, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + }, + }, + }) + defer w1.Stop() + + w2 := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: version2, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + }, + }, + }) + defer w2.Stop() + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "list", + "--address", s.Address(), + ) + assert.NoError(t, res.Err) + assert.Contains(t, res.Stdout.String(), deploymentName) + }, 30*time.Second, 100*time.Millisecond) + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version1, + ) + assert.NoError(t, res.Err) + res = s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version2, + ) + assert.NoError(t, res.Err) + }, 30*time.Second, 100*time.Millisecond) + + res := s.Execute( + "worker", "deployment", "set-current-version", + "--address", s.Address(), + "--version", version1, + "--yes", + ) + s.NoError(res.Err) + + res = s.Execute( + "worker", "deployment", "set-ramping-version", + "--address", s.Address(), + "--version", version2, + "--percentage", "12.5", + "--yes", + ) + s.NoError(res.Err) + + res = s.Execute( + "worker", "deployment", "describe", + "--address", s.Address(), + "--name", deploymentName, + ) + s.NoError(res.Err) + + s.ContainsOnSameLine(res.Stdout.String(), "CurrentVersion", version1) + s.ContainsOnSameLine(res.Stdout.String(), "RampingVersion", version2) + s.ContainsOnSameLine(res.Stdout.String(), "RampingVersionPercentage", "12.5") + + // setting version2 as current also removes the ramp + res = s.Execute( + "worker", "deployment", "set-current-version", + "--address", s.Address(), + "--version", version2, + "--yes", + ) + s.NoError(res.Err) + + res = s.Execute( + "worker", "deployment", "describe", + "--address", s.Address(), + "--name", deploymentName, + "--output", "json", + ) + s.NoError(res.Err) + + var jsonOut jsonDeploymentInfoType + s.NoError(json.Unmarshal(res.Stdout.Bytes(), &jsonOut)) + s.Equal(deploymentName, jsonOut.Name) + s.Empty(jsonOut.RoutingConfig.RampingVersion) + s.Equal(version2, jsonOut.RoutingConfig.CurrentVersion) + + //same with explicit delete + res = s.Execute( + "worker", "deployment", "set-ramping-version", + "--address", s.Address(), + "--version", version1, + "--percentage", "10.1", + "--yes", + ) + s.NoError(res.Err) + + res = s.Execute( + "worker", "deployment", "describe", + "--address", s.Address(), + "--name", deploymentName, + ) + s.NoError(res.Err) + + s.ContainsOnSameLine(res.Stdout.String(), "CurrentVersion", version2) + s.ContainsOnSameLine(res.Stdout.String(), "RampingVersion", version1) + s.ContainsOnSameLine(res.Stdout.String(), "RampingVersionPercentage", "10.1") + + res = s.Execute( + "worker", "deployment", "set-ramping-version", + "--address", s.Address(), + "--version", version1, + "--delete", + "--yes", + ) + s.NoError(res.Err) + + res = s.Execute( + "worker", "deployment", "describe", + "--address", s.Address(), + "--name", deploymentName, + "--output", "json", + ) + s.NoError(res.Err) + + s.NoError(json.Unmarshal(res.Stdout.Bytes(), &jsonOut)) + s.Equal(deploymentName, jsonOut.Name) + s.Empty(jsonOut.RoutingConfig.RampingVersion) + s.Equal(version2, jsonOut.RoutingConfig.CurrentVersion) + } -*/ diff --git a/temporalcli/commands.workflow.go b/temporalcli/commands.workflow.go index 421fa354b..ae189678d 100644 --- a/temporalcli/commands.workflow.go +++ b/temporalcli/commands.workflow.go @@ -15,7 +15,6 @@ import ( "github.com/temporalio/cli/temporalcli/internal/printer" "go.temporal.io/api/batch/v1" "go.temporal.io/api/common/v1" - deploymentpb "go.temporal.io/api/deployment/v1" "go.temporal.io/api/enums/v1" "go.temporal.io/api/query/v1" sdkpb "go.temporal.io/api/sdk/v1" @@ -103,20 +102,14 @@ func (c *TemporalWorkflowUpdateOptionsCommand) run(cctx *CommandContext, args [] defer cl.Close() if c.VersioningOverrideBehavior.Value == "unspecified" || c.VersioningOverrideBehavior.Value == "auto_upgrade" { - if c.VersioningOverrideSeriesName != "" { - return fmt.Errorf("cannot set deployment series name with %v behavior", c.VersioningOverrideBehavior) - } - if c.VersioningOverrideBuildId != "" { - return fmt.Errorf("cannot set deployment build ID with %v behavior", c.VersioningOverrideBehavior) + if c.VersioningOverridePinnedVersion != "" { + return fmt.Errorf("cannot set pinned version with %v behavior", c.VersioningOverrideBehavior) } } if c.VersioningOverrideBehavior.Value == "pinned" { - if c.VersioningOverrideSeriesName == "" { - return fmt.Errorf("missing deployment series name with 'pinned' behavior") - } - if c.VersioningOverrideBuildId == "" { - return fmt.Errorf("missing deployment build ID with 'pinned' behavior") + if c.VersioningOverridePinnedVersion == "" { + return fmt.Errorf("missing version with 'pinned' behavior") } } @@ -145,11 +138,8 @@ func (c *TemporalWorkflowUpdateOptionsCommand) run(cctx *CommandContext, args [] RunId: exec.RunId, WorkflowExecutionOptionsChanges: client.WorkflowExecutionOptionsChanges{ VersioningOverride: &client.VersioningOverride{ - Behavior: behavior, - Deployment: client.Deployment{ - SeriesName: c.VersioningOverrideSeriesName, - BuildID: c.VersioningOverrideBuildId, - }, + Behavior: behavior, + PinnedVersion: c.VersioningOverridePinnedVersion, }, }, }) @@ -178,22 +168,13 @@ func (c *TemporalWorkflowUpdateOptionsCommand) run(cctx *CommandContext, args [] ) } - deployment := &deploymentpb.Deployment{ - SeriesName: c.VersioningOverrideSeriesName, - BuildId: c.VersioningOverrideBuildId, - } - if c.VersioningOverrideSeriesName == "" && c.VersioningOverrideBuildId == "" { - // auto_upgrade needs a `nil` pointer - deployment = nil - } - batchReq.Operation = &workflowservice.StartBatchOperationRequest_UpdateWorkflowOptionsOperation{ UpdateWorkflowOptionsOperation: &batch.BatchOperationUpdateWorkflowExecutionOptions{ Identity: clientIdentity(), WorkflowExecutionOptions: &workflowpb.WorkflowExecutionOptions{ VersioningOverride: &workflowpb.VersioningOverride{ - Behavior: behavior, - Deployment: deployment, + Behavior: behavior, + PinnedVersion: c.VersioningOverridePinnedVersion, }, }, UpdateMask: protoMask, diff --git a/temporalcli/commands.workflow_test.go b/temporalcli/commands.workflow_test.go index 0f7a629bc..8e479c82f 100644 --- a/temporalcli/commands.workflow_test.go +++ b/temporalcli/commands.workflow_test.go @@ -11,9 +11,12 @@ import ( "time" "github.com/google/uuid" + "github.com/stretchr/testify/assert" + "github.com/temporalio/cli/temporalcli" "go.temporal.io/api/enums/v1" "go.temporal.io/api/workflowservice/v1" "go.temporal.io/sdk/client" + "go.temporal.io/sdk/worker" "go.temporal.io/sdk/workflow" "google.golang.org/grpc" ) @@ -423,194 +426,227 @@ func (s *SharedServerSuite) TestWorkflow_Cancel_SingleWorkflowSuccess() { s.Error(workflow.ErrCanceled, run.Get(s.Context, nil)) } -/* - func (s *SharedServerSuite) TestWorkflow_Batch_Update_Options_Versioning_Override() { - buildId1 := uuid.NewString() - buildId2 := uuid.NewString() - seriesName := uuid.NewString() - // Workflow that waits to be canceled. - waitingWorkflow := func(ctx workflow.Context) error { - ctx.Done().Receive(ctx, nil) - return ctx.Err() - } - w := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ - Worker: worker.Options{ - BuildID: buildId1, - UseBuildIDForVersioning: true, - DeploymentOptions: worker.DeploymentOptions{ - DeploymentSeriesName: seriesName, - DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, - }, +func (s *SharedServerSuite) TestWorkflow_Batch_Update_Options_Versioning_Override() { + buildId1 := uuid.NewString() + buildId2 := uuid.NewString() + deploymentName := uuid.NewString() + version1 := deploymentName + "." + buildId1 + version2 := deploymentName + "." + buildId2 + // Workflow that waits to be canceled. + waitingWorkflow := func(ctx workflow.Context) error { + ctx.Done().Receive(ctx, nil) + return ctx.Err() + } + w := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: version1, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, }, - Workflows: []any{waitingWorkflow}, - }) - defer w.Stop() + }, + Workflows: []any{waitingWorkflow}, + }) + defer w.Stop() + s.EventuallyWithT(func(t *assert.CollectT) { res := s.Execute( - "worker", "deployment", "set-current", + "worker", "deployment", "list", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId1, ) - s.NoError(res.Err) - - // Start workflows - numWorkflows := 5 - runs := make([]client.WorkflowRun, numWorkflows) - searchAttr := "keyword-" + uuid.NewString() - for i := range runs { - run, err := s.Client.ExecuteWorkflow( - s.Context, - client.StartWorkflowOptions{ - TaskQueue: w.Options.TaskQueue, - SearchAttributes: map[string]any{"CustomKeywordField": searchAttr}, - }, - waitingWorkflow, - ) - s.NoError(err) - runs[i] = run - } - - s.EventuallyWithT(func(t *assert.CollectT) { - for _, run := range runs { - res = s.Execute( - "workflow", "describe", - "--address", s.Address(), - "-w", run.GetID(), - ) - assert.NoError(t, res.Err) - assert.Contains(t, res.Stdout.String(), buildId1) - assert.Contains(t, res.Stdout.String(), "Pinned") - } - }, 30*time.Second, 100*time.Millisecond) - - s.CommandHarness.Stdin.WriteString("y\n") - res = s.Execute( - "workflow", "update-options", - "--address", s.Address(), - "--query", "CustomKeywordField = '"+searchAttr+"'", - "--versioning-override-behavior", "pinned", - "--versioning-override-series-name", seriesName, - "--versioning-override-build-id", buildId2, - ) - s.NoError(res.Err) - - s.EventuallyWithT(func(t *assert.CollectT) { - for _, run := range runs { - // json - res = s.Execute( - "workflow", "describe", - "--address", s.Address(), - "-w", run.GetID(), - "--output", "json", - ) - assert.NoError(t, res.Err) - - var jsonResp workflowservice.DescribeWorkflowExecutionResponse - assert.NoError(t, temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonResp, true)) - versioningInfo := jsonResp.WorkflowExecutionInfo.VersioningInfo - assert.NotNil(t, versioningInfo.VersioningOverride) - assert.Equal(t, seriesName+"."+buildId2, versioningInfo.VersioningOverride.PinnedVersion) - } - }, 30*time.Second, 100*time.Millisecond) - } - - func (s *SharedServerSuite) TestWorkflow_Update_Options_Versioning_Override() { - buildId1 := uuid.NewString() - buildId2 := uuid.NewString() - seriesName := uuid.NewString() - // Workflow that waits to be canceled. - waitingWorkflow := func(ctx workflow.Context) error { - ctx.Done().Receive(ctx, nil) - return ctx.Err() - } - w := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ - Worker: worker.Options{ - BuildID: buildId1, - UseBuildIDForVersioning: true, - DeploymentOptions: worker.DeploymentOptions{ - DeploymentSeriesName: seriesName, - DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, - }, - }, - Workflows: []any{waitingWorkflow}, - }) - defer w.Stop() + assert.NoError(t, res.Err) + assert.Contains(t, res.Stdout.String(), deploymentName) + }, 30*time.Second, 100*time.Millisecond) + s.EventuallyWithT(func(t *assert.CollectT) { res := s.Execute( - "worker", "deployment", "set-current", + "worker", "deployment", "describe-version", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId1, + "--version", version1, ) - s.NoError(res.Err) + assert.NoError(t, res.Err) + }, 30*time.Second, 100*time.Millisecond) - // Start the workflow and wait until the operation is started. + res := s.Execute( + "worker", "deployment", "set-current-version", + "--address", s.Address(), + "--version", version1, + "--yes", + ) + s.NoError(res.Err) + + // Start workflows + numWorkflows := 5 + runs := make([]client.WorkflowRun, numWorkflows) + searchAttr := "keyword-" + uuid.NewString() + for i := range runs { run, err := s.Client.ExecuteWorkflow( s.Context, - client.StartWorkflowOptions{TaskQueue: w.Options.TaskQueue}, + client.StartWorkflowOptions{ + TaskQueue: w.Options.TaskQueue, + SearchAttributes: map[string]any{"CustomKeywordField": searchAttr}, + }, waitingWorkflow, ) s.NoError(err) + runs[i] = run + } - s.EventuallyWithT(func(t *assert.CollectT) { + s.EventuallyWithT(func(t *assert.CollectT) { + for _, run := range runs { res = s.Execute( "workflow", "describe", "--address", s.Address(), "-w", run.GetID(), ) assert.NoError(t, res.Err) - assert.Contains(t, res.Stdout.String(), buildId1) + assert.Contains(t, res.Stdout.String(), version1) assert.Contains(t, res.Stdout.String(), "Pinned") - }, 30*time.Second, 100*time.Millisecond) + } + }, 30*time.Second, 100*time.Millisecond) - res = s.Execute( - "workflow", "update-options", + s.CommandHarness.Stdin.WriteString("y\n") + res = s.Execute( + "workflow", "update-options", + "--address", s.Address(), + "--query", "CustomKeywordField = '"+searchAttr+"'", + "--versioning-override-behavior", "pinned", + "--versioning-override-pinned-version", version2, + ) + s.NoError(res.Err) + + s.EventuallyWithT(func(t *assert.CollectT) { + for _, run := range runs { + // json + res = s.Execute( + "workflow", "describe", + "--address", s.Address(), + "-w", run.GetID(), + "--output", "json", + ) + assert.NoError(t, res.Err) + + var jsonResp workflowservice.DescribeWorkflowExecutionResponse + assert.NoError(t, temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonResp, true)) + versioningInfo := jsonResp.WorkflowExecutionInfo.VersioningInfo + assert.NotNil(t, versioningInfo.VersioningOverride) + assert.Equal(t, version2, versioningInfo.VersioningOverride.PinnedVersion) + } + }, 30*time.Second, 100*time.Millisecond) +} + +func (s *SharedServerSuite) TestWorkflow_Update_Options_Versioning_Override() { + buildId1 := uuid.NewString() + buildId2 := uuid.NewString() + deploymentName := uuid.NewString() + version1 := deploymentName + "." + buildId1 + version2 := deploymentName + "." + buildId2 + + // Workflow that waits to be canceled. + waitingWorkflow := func(ctx workflow.Context) error { + ctx.Done().Receive(ctx, nil) + return ctx.Err() + } + w := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: version1, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, + }, + }, + Workflows: []any{waitingWorkflow}, + }) + defer w.Stop() + + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "list", "--address", s.Address(), - "-w", run.GetID(), - "--versioning-override-behavior", "pinned", - "--versioning-override-series-name", seriesName, - "--versioning-override-build-id", buildId2, ) - s.NoError(res.Err) + assert.NoError(t, res.Err) + assert.Contains(t, res.Stdout.String(), deploymentName) + }, 30*time.Second, 100*time.Millisecond) - res = s.Execute( - "workflow", "describe", + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "describe-version", "--address", s.Address(), - "-w", run.GetID(), + "--version", version1, ) - s.NoError(res.Err) + assert.NoError(t, res.Err) + }, 30*time.Second, 100*time.Millisecond) - s.ContainsOnSameLine(res.Stdout.String(), "OverrideBehavior", "Pinned") - // TODO(antlai-temporal): replace by new Deployment API - // These fields are deprecated, and not populated in latest server - // s.ContainsOnSameLine(res.Stdout.String(), "OverrideDeploymentSeriesName", seriesName) - // s.ContainsOnSameLine(res.Stdout.String(), "OverrideDeploymentBuildID", buildId2) + res := s.Execute( + "worker", "deployment", "set-current-version", + "--address", s.Address(), + "--version", version1, + "--yes", + ) + s.NoError(res.Err) - // remove override - res = s.Execute( - "workflow", "update-options", - "--address", s.Address(), - "-w", run.GetID(), - "--versioning-override-behavior", "unspecified", - ) - s.NoError(res.Err) + // Start the workflow and wait until the operation is started. + run, err := s.Client.ExecuteWorkflow( + s.Context, + client.StartWorkflowOptions{TaskQueue: w.Options.TaskQueue}, + waitingWorkflow, + ) + s.NoError(err) - // json + s.EventuallyWithT(func(t *assert.CollectT) { res = s.Execute( "workflow", "describe", "--address", s.Address(), "-w", run.GetID(), - "--output", "json", ) - s.NoError(res.Err) + assert.NoError(t, res.Err) + assert.Contains(t, res.Stdout.String(), version1) + assert.Contains(t, res.Stdout.String(), "Pinned") + }, 30*time.Second, 100*time.Millisecond) + + res = s.Execute( + "workflow", "update-options", + "--address", s.Address(), + "-w", run.GetID(), + "--versioning-override-behavior", "pinned", + "--versioning-override-pinned-version", version2, + ) + s.NoError(res.Err) + + res = s.Execute( + "workflow", "describe", + "--address", s.Address(), + "-w", run.GetID(), + ) + s.NoError(res.Err) + + s.ContainsOnSameLine(res.Stdout.String(), "OverrideBehavior", "Pinned") + s.ContainsOnSameLine(res.Stdout.String(), "OverridePinnedVersion", version2) + + // remove override + res = s.Execute( + "workflow", "update-options", + "--address", s.Address(), + "-w", run.GetID(), + "--versioning-override-behavior", "unspecified", + ) + s.NoError(res.Err) + + // json + res = s.Execute( + "workflow", "describe", + "--address", s.Address(), + "-w", run.GetID(), + "--output", "json", + ) + s.NoError(res.Err) + + var jsonResp workflowservice.DescribeWorkflowExecutionResponse + s.NoError(temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonResp, true)) + versioningInfo := jsonResp.WorkflowExecutionInfo.VersioningInfo + s.Nil(versioningInfo.VersioningOverride) +} - var jsonResp workflowservice.DescribeWorkflowExecutionResponse - s.NoError(temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonResp, true)) - versioningInfo := jsonResp.WorkflowExecutionInfo.VersioningInfo - s.Nil(versioningInfo.VersioningOverride) - } -*/ func (s *SharedServerSuite) TestWorkflow_Update_Execute() { workflowUpdateTest{ s: s, diff --git a/temporalcli/commands.workflow_view.go b/temporalcli/commands.workflow_view.go index 3ca20cd37..f416a82aa 100644 --- a/temporalcli/commands.workflow_view.go +++ b/temporalcli/commands.workflow_view.go @@ -140,23 +140,17 @@ func (c *TemporalWorkflowDescribeCommand) run(cctx *CommandContext, args []strin cctx.Printer.Println() vInfo := info.VersioningInfo _ = cctx.Printer.PrintStructured(struct { - Behavior string - DeploymentSeriesName string - DeploymentBuildID string - OverrideBehavior string `cli:",cardOmitEmpty"` - OverrideDeploymentSeriesName string `cli:",cardOmitEmpty"` - OverrideDeploymentBuildID string `cli:",cardOmitEmpty"` - TransitionDeploymentSeriesName string `cli:",cardOmitEmpty"` - TransitionDeploymentBuildID string `cli:",cardOmitEmpty"` + Behavior string + Version string + OverrideBehavior string `cli:",cardOmitEmpty"` + OverridePinnedVersion string `cli:",cardOmitEmpty"` + TransitionVersion string `cli:",cardOmitEmpty"` }{ - Behavior: vInfo.Behavior.String(), - DeploymentSeriesName: vInfo.Deployment.GetSeriesName(), - DeploymentBuildID: vInfo.Deployment.GetBuildId(), - OverrideBehavior: vInfo.VersioningOverride.GetBehavior().String(), - OverrideDeploymentSeriesName: vInfo.VersioningOverride.GetDeployment().GetSeriesName(), - OverrideDeploymentBuildID: vInfo.VersioningOverride.GetDeployment().GetBuildId(), - TransitionDeploymentSeriesName: vInfo.DeploymentTransition.GetDeployment().GetSeriesName(), - TransitionDeploymentBuildID: vInfo.DeploymentTransition.GetDeployment().GetBuildId(), + Behavior: vInfo.Behavior.String(), + Version: vInfo.GetVersion(), + OverrideBehavior: vInfo.VersioningOverride.GetBehavior().String(), + OverridePinnedVersion: vInfo.VersioningOverride.GetPinnedVersion(), + TransitionVersion: vInfo.VersionTransition.GetVersion(), }, printer.StructuredOptions{}) } diff --git a/temporalcli/commands.workflow_view_test.go b/temporalcli/commands.workflow_view_test.go index b209bcfff..3348012c3 100644 --- a/temporalcli/commands.workflow_view_test.go +++ b/temporalcli/commands.workflow_view_test.go @@ -13,6 +13,7 @@ import ( "github.com/google/uuid" "github.com/nexus-rpc/sdk-go/nexus" + "github.com/stretchr/testify/assert" "github.com/temporalio/cli/temporalcli" "go.temporal.io/api/enums/v1" nexuspb "go.temporal.io/api/nexus/v1" @@ -21,6 +22,7 @@ import ( "go.temporal.io/sdk/client" "go.temporal.io/sdk/temporal" "go.temporal.io/sdk/temporalnexus" + "go.temporal.io/sdk/worker" "go.temporal.io/sdk/workflow" ) @@ -546,84 +548,94 @@ func (s *SharedServerSuite) TestWorkflow_Count() { s.Contains(out, `{"groupValues":["Completed"],"count":"3"}`) } -/* - func (s *SharedServerSuite) TestWorkflow_Describe_Deployment() { - buildId := uuid.NewString() - seriesName := uuid.NewString() - // Workflow that waits to be canceled. - waitingWorkflow := func(ctx workflow.Context) error { - ctx.Done().Receive(ctx, nil) - return ctx.Err() - } - w := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ - Worker: worker.Options{ - BuildID: buildId, - UseBuildIDForVersioning: true, - DeploymentOptions: worker.DeploymentOptions{ - DeploymentSeriesName: seriesName, - DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, - }, +func (s *SharedServerSuite) TestWorkflow_Describe_Deployment() { + buildId := uuid.NewString() + deploymentName := uuid.NewString() + // Workflow that waits to be canceled. + waitingWorkflow := func(ctx workflow.Context) error { + ctx.Done().Receive(ctx, nil) + return ctx.Err() + } + version := deploymentName + "." + buildId + w := s.DevServer.StartDevWorker(s.Suite.T(), DevWorkerOptions{ + Worker: worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: version, + DefaultVersioningBehavior: workflow.VersioningBehaviorPinned, }, - Workflows: []any{waitingWorkflow}, - }) - defer w.Stop() + }, + Workflows: []any{waitingWorkflow}, + }) + defer w.Stop() + s.EventuallyWithT(func(t *assert.CollectT) { res := s.Execute( - "worker", "deployment", "set-current", + "worker", "deployment", "list", "--address", s.Address(), - "--series-name", seriesName, - "--build-id", buildId, ) - s.NoError(res.Err) + assert.NoError(t, res.Err) + assert.Contains(t, res.Stdout.String(), deploymentName) + }, 30*time.Second, 100*time.Millisecond) - // Start the workflow and wait until the operation is started. - run, err := s.Client.ExecuteWorkflow( - s.Context, - client.StartWorkflowOptions{TaskQueue: w.Options.TaskQueue}, - waitingWorkflow, + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--version", version, ) - s.NoError(err) + assert.NoError(t, res.Err) + }, 30*time.Second, 100*time.Millisecond) - s.EventuallyWithT(func(t *assert.CollectT) { - res = s.Execute( - "workflow", "describe", - "--address", s.Address(), - "-w", run.GetID(), - ) - assert.NoError(t, res.Err) - assert.Contains(t, res.Stdout.String(), buildId) - assert.Contains(t, res.Stdout.String(), "Pinned") - }, 30*time.Second, 100*time.Millisecond) - - out := res.Stdout.String() - s.ContainsOnSameLine(out, "Behavior", "Pinned") - // TODO(antlai-temporal): replace by new Deployment API - // These fields are deprecated, and not populated in latest server - //s.ContainsOnSameLine(out, "DeploymentBuildID", buildId) - //s.ContainsOnSameLine(out, "DeploymentSeriesName", seriesName) - s.ContainsOnSameLine(out, "OverrideBehavior", "Unspecified") - - // json + res := s.Execute( + "worker", "deployment", "set-current-version", + "--address", s.Address(), + "--version", version, + "--yes", + ) + s.NoError(res.Err) + + // Start the workflow and wait until the operation is started. + run, err := s.Client.ExecuteWorkflow( + s.Context, + client.StartWorkflowOptions{TaskQueue: w.Options.TaskQueue}, + waitingWorkflow, + ) + s.NoError(err) + + s.EventuallyWithT(func(t *assert.CollectT) { res = s.Execute( "workflow", "describe", "--address", s.Address(), "-w", run.GetID(), - "--output", "json", ) - s.NoError(res.Err) - - var jsonResp workflowservice.DescribeWorkflowExecutionResponse - s.NoError(temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonResp, true)) - versioningInfo := jsonResp.WorkflowExecutionInfo.VersioningInfo - s.Equal("Pinned", versioningInfo.Behavior.String()) - // TODO(antlai-temporal): replace by new Deployment API - // These fields are deprecated, and not populated in latest server - // s.Equal(buildId, versioningInfo.Deployment.BuildId) - // s.Equal(seriesName, versioningInfo.Deployment.SeriesName) - s.Nil(versioningInfo.VersioningOverride) - s.Nil(versioningInfo.DeploymentTransition) - } -*/ + assert.NoError(t, res.Err) + assert.Contains(t, res.Stdout.String(), version) + assert.Contains(t, res.Stdout.String(), "Pinned") + }, 30*time.Second, 100*time.Millisecond) + + out := res.Stdout.String() + s.ContainsOnSameLine(out, "Behavior", "Pinned") + s.ContainsOnSameLine(out, "Version", version) + s.ContainsOnSameLine(out, "OverrideBehavior", "Unspecified") + + // json + res = s.Execute( + "workflow", "describe", + "--address", s.Address(), + "-w", run.GetID(), + "--output", "json", + ) + s.NoError(res.Err) + + var jsonResp workflowservice.DescribeWorkflowExecutionResponse + s.NoError(temporalcli.UnmarshalProtoJSONWithOptions(res.Stdout.Bytes(), &jsonResp, true)) + versioningInfo := jsonResp.WorkflowExecutionInfo.VersioningInfo + s.Equal("Pinned", versioningInfo.Behavior.String()) + s.Equal(version, versioningInfo.Version) + s.Nil(versioningInfo.VersioningOverride) +} + func (s *SharedServerSuite) TestWorkflow_Describe_NexusOperationAndCallback() { handlerWorkflowID := uuid.NewString() endpointName := validEndpointName(s.T()) diff --git a/temporalcli/commands_test.go b/temporalcli/commands_test.go index 467f2c9bb..74606eef2 100644 --- a/temporalcli/commands_test.go +++ b/temporalcli/commands_test.go @@ -371,6 +371,7 @@ func StartDevServer(t *testing.T, options DevServerOptions) *DevServer { d.Options.DynamicConfigValues["frontend.workerVersioningDataAPIs"] = true d.Options.DynamicConfigValues["frontend.workerVersioningWorkflowAPIs"] = true d.Options.DynamicConfigValues["system.enableDeployments"] = true + d.Options.DynamicConfigValues["system.enableDeploymentVersions"] = true d.Options.DynamicConfigValues["worker.buildIdScavengerEnabled"] = true d.Options.DynamicConfigValues["frontend.enableUpdateWorkflowExecution"] = true d.Options.DynamicConfigValues["frontend.MaxConcurrentBatchOperationPerNamespace"] = 1000 diff --git a/temporalcli/commandsgen/commands.yml b/temporalcli/commandsgen/commands.yml index 889525719..21e4b3c5e 100644 --- a/temporalcli/commandsgen/commands.yml +++ b/temporalcli/commandsgen/commands.yml @@ -690,17 +690,40 @@ commands: ``` temporal worker deployment list ``` + + Lists the Deployments in the client's namespace. + + Arguments can be Worker Deployment Versions associated with + a Deployment, using a fully qualified Version identifier that + concatenates the Deployment Name and the Build ID with the + reserved separator ".". + + For example: + + ``` + temporal worker deployment set-current-version \ + --version YourDeploymentName.YourBuildID + ``` + + Sets the current Deployment Version for a given Deployment. + docs: description-header: >- - Temporal Deployment commands enable operations on Worker Deployments, - such as describe, list, delete, and version, simplifying - versioning and management of workers. + Temporal Deployment commands enable operations on Worker Deployments + that simplify versioning and management of workers, + such as describe, list, delete, and also operations that refer to Worker + Deployment Versions within them, such as describe-version, + delete-version, set-current-version, or set-ramping-version. keywords: - worker deployment - worker deployment describe - worker deployment list - worker deployment delete - - worker deployment version + - worker deployment describe-version + - worker deployment set-current-version + - worker deployment set-ramping-version + - worker deployment delete-version + - worker deployment update-metadata-version - name: temporal worker deployment describe summary: Show properties of a Worker Deployment @@ -710,7 +733,7 @@ commands: | subject to change. | +---------------------------------------------------------------------+ - Describes properties of a Worker Deployment, such as the versions + Describe properties of a Worker Deployment, such as the versions associated with it, routing information of new or existing tasks executed by this deployment, or its creation time. @@ -729,14 +752,14 @@ commands: - deployment-name - name: temporal worker deployment delete - summary: Deletes a Worker Deployment + summary: Delete a Worker Deployment description: | +---------------------------------------------------------------------+ | CAUTION: Worker Deployment is experimental. Deployment commands are | | subject to change. | +---------------------------------------------------------------------+ - Removes a Worker Deployment given its Deployment Name. + Remove a Worker Deployment given its Deployment Name. A Deployment can only be deleted if it has no Version in it. ``` @@ -778,48 +801,8 @@ commands: temporal worker deployment list \ --namespace YourDeploymentNamespace ``` - - - name: temporal worker deployment version - summary: Describe, delete, setCurrent, or setRamping, a Deployment Version - description: | - +---------------------------------------------------------------------+ - | CAUTION: Worker deployment is experimental. Deployment commands are | - | subject to change. | - +---------------------------------------------------------------------+ - - Deployment commands to operate on Worker Deployment Versions: - - ``` - temporal worker deployment version [command] [options] - ``` - - For example, using a fully qualified Version identifier that - concatenates the Deployment Name with the Build ID using the - reserved separator ".": - - ``` - temporal worker deployment version setCurrent \ - --version YourDeploymentName.YourBuildID - ``` - Sets the current Deployment Version for a given Deployment. - When a Version is current, Workers of that Deployment Version will receive - tasks from new Workflows and from existing AutoUpgrade Workflows that - are running on this Deployment. - docs: - description-header: >- - Temporal Deployment Version commands enable operations on Worker - Deployments Versions, - such as describe, delete, set as Current, set as Ramping, simplifying - versioning and management of workers. - keywords: - - worker deployment version - - worker deployment version describe - - worker deployment version set-current - - worker deployment version set-ramping - - worker deployment version delete - - worker deployment version update-metadata - - - name: temporal worker deployment version describe + + - name: temporal worker deployment describe-version summary: Show properties of a Worker Deployment Version description: | +---------------------------------------------------------------------+ @@ -827,13 +810,13 @@ commands: | subject to change. | +---------------------------------------------------------------------+ - Describes properties of a Worker Deployment Version, such as the task + Describe properties of a Worker Deployment Version, such as the task queues polled by workers in this Deployment Version, or drainage information required to safely decommission workers, or user-provided metadata, or its creation/modification time. ``` - temporal worker deployment version describe [options] + temporal worker deployment describe-version [options] ``` For example, to describe a deployment version in a deployment @@ -841,21 +824,21 @@ commands: namespace: ``` - temporal worker deployment version describe \ + temporal worker deployment describe-version \ --version YourDeploymentName.YourBuildID ``` option-sets: - deployment-version - - name: temporal worker deployment version delete - summary: Deletes a Worker Deployment Version + - name: temporal worker deployment delete-version + summary: Delete a Worker Deployment Version description: | +---------------------------------------------------------------------+ | CAUTION: Worker Deployment is experimental. Deployment commands are | | subject to change. | +---------------------------------------------------------------------+ - Removes a Worker Deployment Version given its fully-qualified identifier. + Remove a Worker Deployment Version given its fully-qualified identifier. This is rarely needed during normal operation since unused Versions are eventually garbage collected. The client can delete a Version only when all of the following conditions @@ -864,16 +847,16 @@ commands: - It has no active pollers, i.e., none of the task queues in the Version have pollers. - It is not draining. This requirement can be ignored with the option - --skip-drainage. + `--skip-drainage`. ``` - temporal worker deployment version delete [options] + temporal worker deployment delete-version [options] ``` - For example, forcing to skip the drainage restriction: + For example, skipping the drainage restriction: ``` - temporal worker deployment version delete \ + temporal worker deployment delete-version \ --version YourDeploymentName.YourBuildID \ --skip-drainage ``` @@ -887,7 +870,7 @@ commands: type: bool description: Ignore the deletion requirement of not draining. - - name: temporal worker deployment version set-current + - name: temporal worker deployment set-current-version summary: Make a Worker Deployment Version Current for a Deployment description: | +---------------------------------------------------------------------+ @@ -895,9 +878,9 @@ commands: | subject to change. | +---------------------------------------------------------------------+ - Sets the Current Version for a Deployment. + Set the Current Version for a Deployment. When a Version is current, Workers of that Deployment Version will receive - tasks from new Workflows and from existing AutoUpgrade Workflows that + tasks from new Workflows, and from existing AutoUpgrade Workflows that are running on this Deployment. If not all the expected Task Queues are being polled by Workers in the @@ -907,7 +890,7 @@ commands: queue configuration. ``` - temporal worker deployment version set-current [options] + temporal worker deployment set-current-version [options] ``` For example, to set the Current Version of a deployment @@ -915,9 +898,19 @@ commands: in the default namespace: ``` - temporal worker deployment version set-current \ + temporal worker deployment set-current-version \ --version YourDeploymentName.YourBuildID ``` + + The target of set-current-version can also be `__unversioned__`, which + moves tasks to unversioned workers, but in this case we also need to + specify the Deployment Name. + + ``` + temporal worker deployment set-current-version \ + --version __unversioned__ \ + --deployment-name YourDeploymentName + ``` option-sets: - deployment-version options: @@ -937,7 +930,7 @@ commands: type: bool description: Don't prompt to confirm set Current Version. - - name: temporal worker deployment version set-ramping + - name: temporal worker deployment set-ramping-version summary: Change Version Ramping settings for a Worker Deployment description: | +---------------------------------------------------------------------+ @@ -945,18 +938,17 @@ commands: | subject to change. | +---------------------------------------------------------------------+ - Sets the Ramping Version and Percentage for a Deployment. + Set the Ramping Version and Percentage for a Deployment. The Ramping Version can be set to a fully-qualified Version of the form `YourDeploymentName.YourBuildID`, or set to "__unversioned__", a special - value, which represents all the unversioned workers. + value that represents all the unversioned workers. The Ramping Percentage is a float with values in the range [0, 100]. A value of 100 does not make the Ramping Version Current, use - `set-current` instead. + `set-current-version` instead. - To remove a Ramping Version use the flag `--delete` and set Percentage - to 0. + To remove a Ramping Version use the flag `--delete`. If not all the expected Task Queues are being polled by Workers in the new Ramping Version the request will fail. To override this protection use @@ -965,7 +957,7 @@ commands: queue configuration. ``` - temporal worker deployment version set-ramping [options] + temporal worker deployment set-ramping-version [options] ``` For example, to set the Ramping Version of a deployment @@ -974,7 +966,7 @@ commands: using the default namespace: ``` - temporal worker deployment version set-ramping \ + temporal worker deployment set-ramping-version \ --version YourDeploymentName.YourBuildID --percentage 10.0 ``` @@ -982,9 +974,8 @@ commands: And to remove that ramping: ``` - temporal worker deployment version set-ramping \ + temporal worker deployment set-ramping-version \ --version YourDeploymentName.YourBuildID \ - --percentage 0.0 \ --delete ``` option-sets: @@ -994,10 +985,9 @@ commands: type: string description: | Deployment name. - Only needed when `--version` is `__unversioned__` or empty. + Only needed when `--version` is `__unversioned__`. - name: percentage type: float - required: true description: | Percentage of tasks redirected to the Ramping Version. Valid range [0,100]. @@ -1014,7 +1004,47 @@ commands: short: y type: bool description: Don't prompt to confirm set Ramping Version. - + + - name: temporal worker deployment update-metadata-version + summary: Change user-provided metadata for a Version + description: | + +---------------------------------------------------------------------+ + | CAUTION: Worker Deployment is experimental. Deployment commands are | + | subject to change. | + +---------------------------------------------------------------------+ + Update metadata associated with a Worker Deployment Version. + + For example: + + ``` + temporal worker deployment update-metadata-version \ + --version YourDeploymentName.YourBuildID \ + --metadata bar=1 \ + --metadata foo=true + ``` + + The current metadata is also returned with `describe-version`: + + ``` + temporal worker deployment describe-version \ + --version YourDeploymentName.YourBuildID \ + ``` + option-sets: + - deployment-version + options: + - name: metadata + type: string[] + description: | + Set deployment metadata using `KEY="VALUE"` pairs. + Keys must be identifiers, and values must be JSON values. + For example: 'YourKey={"your": "value"}'. + Can be passed multiple times. + - name: remove-entries + type: string[] + description: | + Keys of entries to be deleted from metadata. + Can be passed multiple times. + - name: temporal env summary: Manage environments description: | @@ -2566,8 +2596,7 @@ commands: summary: Manage Task Queue Build ID handling (Experimental) description: | +---------------------------------------------------------------------+ - | CAUTION: Worker versioning is experimental. Versioning commands are | - | subject to change. | + | CAUTION: This API has been deprecated by Worker Deployment. | +---------------------------------------------------------------------+ Provides commands to add, list, remove, or replace Worker Build ID assignment @@ -2609,8 +2638,7 @@ commands: ``` +---------------------------------------------------------------------+ - | CAUTION: Worker versioning is experimental. Versioning commands are | - | subject to change. | + | CAUTION: This API has been deprecated by Worker Deployment. | +---------------------------------------------------------------------+ options: - name: source-build-id @@ -2651,8 +2679,7 @@ commands: override this validation. +---------------------------------------------------------------------+ - | CAUTION: Worker versioning is experimental. Versioning commands are | - | subject to change. | + | CAUTION: This API has been deprecated by Worker Deployment. | +---------------------------------------------------------------------+ options: - name: build-id @@ -2684,8 +2711,7 @@ commands: Use the `--force` option to override this validation. +---------------------------------------------------------------------+ - | CAUTION: Worker versioning is experimental. Versioning commands are | - | subject to change. | + | CAUTION: This API has been deprecated by Worker Deployment. | +---------------------------------------------------------------------+ options: - name: rule-index @@ -2715,8 +2741,7 @@ commands: ``` +---------------------------------------------------------------------+ - | CAUTION: Worker versioning is experimental. Versioning commands are | - | subject to change. | + | CAUTION: This API has been deprecated by Worker Deployment. | +---------------------------------------------------------------------+ options: - name: source-build-id @@ -2749,10 +2774,8 @@ commands: Build ID. You may add at most one redirect rule for each source Build ID. Redirect rules require that a target Build ID is fully compatible with the source Build ID. - +---------------------------------------------------------------------+ - | CAUTION: Worker versioning is experimental. Versioning commands are | - | subject to change. | + | CAUTION: This API has been deprecated by Worker Deployment. | +---------------------------------------------------------------------+ - name: temporal task-queue versioning insert-assignment-rule @@ -2771,8 +2794,7 @@ commands: If you do not specify a `--rule-index`, this command inserts at index 0. +---------------------------------------------------------------------+ - | CAUTION: Worker versioning is experimental. Versioning commands are | - | subject to change. | + | CAUTION: This API has been deprecated by Worker Deployment. | +---------------------------------------------------------------------+ options: - name: build-id @@ -2827,8 +2849,7 @@ commands: Percent may vary between 0 and 100 (default). +---------------------------------------------------------------------+ - | CAUTION: Worker versioning is experimental. Versioning commands are | - | subject to change. | + | CAUTION: This API has been deprecated by Worker Deployment. | +---------------------------------------------------------------------+ options: - name: build-id @@ -2869,8 +2890,7 @@ commands: ``` +---------------------------------------------------------------------+ - | CAUTION: Worker versioning is experimental. Versioning commands are | - | subject to change. | + | CAUTION: This API has been deprecated by Worker Deployment. | +---------------------------------------------------------------------+ options: - name: source-build-id @@ -3166,8 +3186,8 @@ commands: temporal workflow update-options \ --workflow-id YourWorkflowId \ --versioning-override-behavior pinned \ - --versioning-override-series-name YourDeploymentSeriesName \ - --versioning-override-build-id YourDeploymentBuildId + --versioning-override-pinned-version \ + YourDeploymentSeriesName.YourDeploymentBuildId ``` To remove any previous overrides, set the behavior to @@ -3193,12 +3213,9 @@ commands: - unspecified - pinned - auto_upgrade - - name: versioning-override-series-name - type: string - description: Override Series Name for a Worker Deployment (Only for pinned). - - name: versioning-override-build-id + - name: versioning-override-pinned-version type: string - description: Override Build ID for a Worker Deployment (Only for pinned). + description: Override Pinned Version for a Worker Deployment (Only for pinned). - name: temporal workflow query summary: Retrieve Workflow Execution state