From 1e3734bcfb7b604b93b2b27d282c2356c351bc2d Mon Sep 17 00:00:00 2001 From: Jay Pipes Date: Thu, 11 Jun 2026 11:12:54 -0400 Subject: [PATCH] prevent create of "empty" WorkerDeploymentVersions Some customers were confused with the ability to create an "empty" WorkerDeploymentVersion with the `temporal worker deployment create-version` CLI command. This PR removes the ability to create a WDV that does not have any compute configuration associated with it. As we add support for non-Lambda compute providers like Google Cloud Run, we will update the conditional check in the CLI command implementation to verify that at least one "set" of compute provider configuration CLI options has been specified. Signed-off-by: Jay Pipes --- internal/temporalcli/commands.gen.go | 4 +- .../temporalcli/commands.worker.deployment.go | 3 + .../commands.worker.deployment_test.go | 76 ++++++++++++------- internal/temporalcli/commands.yaml | 2 + 4 files changed, 54 insertions(+), 31 deletions(-) diff --git a/internal/temporalcli/commands.gen.go b/internal/temporalcli/commands.gen.go index cfaa5e4d4..78dc8e9e6 100644 --- a/internal/temporalcli/commands.gen.go +++ b/internal/temporalcli/commands.gen.go @@ -3635,9 +3635,9 @@ func NewTemporalWorkerDeploymentCreateVersionCommand(cctx *CommandContext, paren s.Command.Use = "create-version [flags]" s.Command.Short = "Create a new Worker Deployment Version" if hasHighlighting { - s.Command.Long = "\nCreate a new Worker Deployment Version:\n\n\x1b[1mtemporal worker deployment create-version [options]\x1b[0m\n\nConfigure a Worker Deployment Version's compute configuration as needed.\nFor example, pass compute provider information for an AWS Lambda function\nthat spawns a Worker in the Worker Deployment:\n\n\x1b[1mtemporal worker deployment create-version \\\n --namespace YourNamespaceName \\\n --deployment-name YourDeploymentName \\\n --build-id YourBuildID \\\n --aws-lambda-function-arn LambdaFunctionARN \\\n --aws-lambda-assume-role-arn LambdaAssumeRoleARN \\\n --aws-lambda-assume-role-external-id LambdaAssumeRoleExternalID\x1b[0m\n\nIf a Worker Deployment Version with the supplied BuildID already exists,\nthis command will return an error.\n\nNote: This is an experimental feature and may change in the future." + s.Command.Long = "\nCreate a new Worker Deployment Version:\n\n\x1b[1mtemporal worker deployment create-version [options]\x1b[0m\n\nConfigure a Worker Deployment Version's compute configuration as needed.\nFor example, pass compute provider information for an AWS Lambda function\nthat spawns a Worker in the Worker Deployment:\n\n\x1b[1mtemporal worker deployment create-version \\\n --namespace YourNamespaceName \\\n --deployment-name YourDeploymentName \\\n --build-id YourBuildID \\\n --aws-lambda-function-arn LambdaFunctionARN \\\n --aws-lambda-assume-role-arn LambdaAssumeRoleARN \\\n --aws-lambda-assume-role-external-id LambdaAssumeRoleExternalID\x1b[0m\n\nIf a Worker Deployment Version with the supplied BuildID already exists,\nthis command will return an error.\n\nReturns an error if all compute configuration fields are empty.\n\nNote: This is an experimental feature and may change in the future." } else { - s.Command.Long = "\nCreate a new Worker Deployment Version:\n\n```\ntemporal worker deployment create-version [options]\n```\n\nConfigure a Worker Deployment Version's compute configuration as needed.\nFor example, pass compute provider information for an AWS Lambda function\nthat spawns a Worker in the Worker Deployment:\n\n```\ntemporal worker deployment create-version \\\n --namespace YourNamespaceName \\\n --deployment-name YourDeploymentName \\\n --build-id YourBuildID \\\n --aws-lambda-function-arn LambdaFunctionARN \\\n --aws-lambda-assume-role-arn LambdaAssumeRoleARN \\\n --aws-lambda-assume-role-external-id LambdaAssumeRoleExternalID\n```\n\nIf a Worker Deployment Version with the supplied BuildID already exists,\nthis command will return an error.\n\nNote: This is an experimental feature and may change in the future." + s.Command.Long = "\nCreate a new Worker Deployment Version:\n\n```\ntemporal worker deployment create-version [options]\n```\n\nConfigure a Worker Deployment Version's compute configuration as needed.\nFor example, pass compute provider information for an AWS Lambda function\nthat spawns a Worker in the Worker Deployment:\n\n```\ntemporal worker deployment create-version \\\n --namespace YourNamespaceName \\\n --deployment-name YourDeploymentName \\\n --build-id YourBuildID \\\n --aws-lambda-function-arn LambdaFunctionARN \\\n --aws-lambda-assume-role-arn LambdaAssumeRoleARN \\\n --aws-lambda-assume-role-external-id LambdaAssumeRoleExternalID\n```\n\nIf a Worker Deployment Version with the supplied BuildID already exists,\nthis command will return an error.\n\nReturns an error if all compute configuration fields are empty.\n\nNote: This is an experimental feature and may change in the future." } s.Command.Args = cobra.NoArgs s.Command.Flags().StringVar(&s.AwsLambdaFunctionArn, "aws-lambda-function-arn", "", "Qualified (contains version suffix) or unqualified AWS Lambda function ARN to invoke when there are no active pollers for task queue targets in the Worker Deployment.") diff --git a/internal/temporalcli/commands.worker.deployment.go b/internal/temporalcli/commands.worker.deployment.go index f82db4a6c..3dc25be79 100644 --- a/internal/temporalcli/commands.worker.deployment.go +++ b/internal/temporalcli/commands.worker.deployment.go @@ -957,6 +957,9 @@ func (c *TemporalWorkerDeploymentCreateVersionCommand) run(cctx *CommandContext, }, }, } + } else { + // We do not allow creation of an "empty" WDV. + return fmt.Errorf("missing configuration for compute provider") } request := &workflowservice.CreateWorkerDeploymentVersionRequest{ Namespace: ns, diff --git a/internal/temporalcli/commands.worker.deployment_test.go b/internal/temporalcli/commands.worker.deployment_test.go index 7c6400179..b1323532f 100644 --- a/internal/temporalcli/commands.worker.deployment_test.go +++ b/internal/temporalcli/commands.worker.deployment_test.go @@ -1153,49 +1153,67 @@ func (s *SharedServerSuite) TestCreateWorkerDeploymentVersion_EmptyComputeConfig // worker deployment create-version` CLI command. noComputeConfigBuildID := uuid.NewString() + // Attempting to create a WDV with no compute provider configuration should + // fail. res := s.Execute( "worker", "deployment", "create-version", "--address", s.Address(), "--deployment-name", deploymentName, "--build-id", noComputeConfigBuildID, ) - s.NoError(res.Err) - s.Contains(res.Stdout.String(), "Successfully created worker deployment version") + s.Error(res.Err) + s.ErrorContains(res.Err, "missing configuration for compute provider") - // Wait for the deployment version to appear - s.EventuallyWithT(func(t *assert.CollectT) { + // TODO(jaypipes): Uncomment the test block below once support for Cloud + // Run is added. When we add another compute provider, we can test for the + // return of a duplicate WDV. Until that point, we cannot create an "empty" + // WDV to test the build ID existence. + + /* res := s.Execute( - "worker", "deployment", "describe-version", + "worker", "deployment", "create-version", "--address", s.Address(), "--deployment-name", deploymentName, "--build-id", noComputeConfigBuildID, ) - assert.NoError(t, res.Err) - }, 30*time.Second, 100*time.Millisecond) + s.NoError(res.Err) + s.Contains(res.Stdout.String(), "Successfully created worker deployment version") + + // Wait for the deployment version to appear + s.EventuallyWithT(func(t *assert.CollectT) { + res := s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--deployment-name", deploymentName, + "--build-id", noComputeConfigBuildID, + ) + assert.NoError(t, res.Err) + }, 30*time.Second, 100*time.Millisecond) - // Check that there is no compute config returned for this WDV - res = s.Execute( - "worker", "deployment", "describe-version", - "--address", s.Address(), - "--deployment-name", deploymentName, - "--build-id", noComputeConfigBuildID, - "--output", "json", - ) - s.NoError(res.Err) - var jsonOut jsonDeploymentVersionInfoType - s.NoError(json.Unmarshal(res.Stdout.Bytes(), &jsonOut)) - s.Nil(jsonOut.ComputeConfig, "ComputeConfig should be nil.") + // Check that there is no compute config returned for this WDV + res = s.Execute( + "worker", "deployment", "describe-version", + "--address", s.Address(), + "--deployment-name", deploymentName, + "--build-id", noComputeConfigBuildID, + "--output", "json", + ) + s.NoError(res.Err) + var jsonOut jsonDeploymentVersionInfoType + s.NoError(json.Unmarshal(res.Stdout.Bytes(), &jsonOut)) + s.Nil(jsonOut.ComputeConfig, "ComputeConfig should be nil.") - // Attempting to create a WDV with the same BuildID should fail with a - // conflict error. - res = s.Execute( - "worker", "deployment", "create-version", - "--address", s.Address(), - "--deployment-name", deploymentName, - "--build-id", noComputeConfigBuildID, - ) - s.Error(res.Err) - s.ErrorContains(res.Err, "already exists") + // Attempting to create a WDV with the same BuildID should fail with a + // conflict error. + res = s.Execute( + "worker", "deployment", "create-version", + "--address", s.Address(), + "--deployment-name", deploymentName, + "--build-id", noComputeConfigBuildID, + ) + s.Error(res.Err) + s.ErrorContains(res.Err, "already exists") + */ } func (s *SharedServerSuite) TestCreateWorkerDeploymentVersion_Errors() { diff --git a/internal/temporalcli/commands.yaml b/internal/temporalcli/commands.yaml index 3d60e1c56..ea8501725 100644 --- a/internal/temporalcli/commands.yaml +++ b/internal/temporalcli/commands.yaml @@ -1092,6 +1092,8 @@ commands: If a Worker Deployment Version with the supplied BuildID already exists, this command will return an error. + Returns an error if all compute configuration fields are empty. + Note: This is an experimental feature and may change in the future. option-sets: - deployment-version