diff --git a/frontend/cli/cmd_deploy.go b/frontend/cli/cmd_deploy.go index fc32fbca4..3bd4d9601 100644 --- a/frontend/cli/cmd_deploy.go +++ b/frontend/cli/cmd_deploy.go @@ -2,6 +2,8 @@ package main import ( "context" + "fmt" + "time" "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/ftlv1connect" "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1beta1/provisioner/provisionerconnect" @@ -11,10 +13,11 @@ import ( ) type deployCmd struct { - Replicas int32 `short:"n" help:"Number of replicas to deploy." default:"1"` - NoWait bool `help:"Do not wait for deployment to complete." default:"false"` - UseProvisioner bool `help:"Use the ftl-provisioner to deploy the application." default:"false" hidden:"true"` - Build buildCmd `embed:""` + Replicas int32 `short:"n" help:"Number of replicas to deploy." default:"1"` + NoWait bool `help:"Do not wait for deployment to complete." default:"false"` + UseProvisioner bool `help:"Use the ftl-provisioner to deploy the application." default:"false" hidden:"true"` + Build buildCmd `embed:""` + Timeout time.Duration `short:"t" help:"Timeout for the deployment."` } func (d *deployCmd) Run(ctx context.Context, projConfig projectconfig.Config) error { @@ -24,18 +27,28 @@ func (d *deployCmd) Run(ctx context.Context, projConfig projectconfig.Config) er } else { client = rpc.ClientFromContext[ftlv1connect.ControllerServiceClient](ctx) } - bindAllocator, err := bindAllocatorWithoutController() if err != nil { return err } // Cancel build engine context to ensure all language plugins are killed. - ctx, cancel := context.WithCancel(ctx) + var cancel context.CancelFunc + if d.Timeout > 0 { + ctx, cancel = context.WithTimeout(ctx, d.Timeout) + defer cancel() + } else { + ctx, cancel = context.WithCancel(ctx) + } defer cancel() engine, err := buildengine.New(ctx, client, projConfig, d.Build.Dirs, bindAllocator, buildengine.BuildEnv(d.Build.BuildEnv), buildengine.Parallelism(d.Build.Parallelism)) if err != nil { return err } - return engine.BuildAndDeploy(ctx, d.Replicas, !d.NoWait) + + err = engine.BuildAndDeploy(ctx, d.Replicas, !d.NoWait) + if err != nil { + return fmt.Errorf("failed to deploy: %w", err) + } + return nil } diff --git a/internal/integration/actions.go b/internal/integration/actions.go index 909f4b866..ac1d00348 100644 --- a/internal/integration/actions.go +++ b/internal/integration/actions.go @@ -224,7 +224,7 @@ func ExpectError(action Action, expectedErrorMsg ...string) Action { func Deploy(module string) Action { return Chain( func(t testing.TB, ic TestContext) { - args := []string{"deploy"} + args := []string{"deploy", "-t", "4m"} if ic.Provisioner != nil { args = append(args, "--use-provisioner", "--provisioner-endpoint=http://localhost:8893") }