Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions cmd/commands/deploy/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,22 @@ import (
func NewFuncCmd(env deployaction.EnvConfig) *cobra.Command {
stage := env.Stage()
return &cobra.Command{
Use: fmt.Sprintf("deploy:func:%s <service|path> <function-name>", stage),
Short: fmt.Sprintf("Deploy a single Lambda function to %s", stage),
Long: fmt.Sprintf(`Package and deploy a single Lambda function to %s.
Use: fmt.Sprintf("deploy:func:%s <service|path> <function-name> [function-name...]", stage),
Short: fmt.Sprintf("Deploy one or more Lambda functions to %s", stage),
Long: fmt.Sprintf(`Package and deploy one or more Lambda functions to %s.

The service argument can be a service name (from serverless.yml) or a path.
All functions must belong to the same service; the service is packaged once.

Examples:
draft deploy:func:%s gamestats storegamestats
draft deploy:func:%s services/gamestats storegamestats`, stage, stage, stage),
Args: cobra.ExactArgs(2),
draft deploy:func:%s gamestats storegamestats otherlambda
draft deploy:func:%s services/gamestats storegamestats`, stage, stage, stage, stage),
Args: cobra.MinimumNArgs(2),
Run: func(c *cobra.Command, args []string) {
common.ChDir(c)

if err := deployaction.DeployFunction(env, args[0], args[1]); err != nil {
if err := deployaction.DeployFunction(env, args[0], args[1:]); err != nil {
log.Exitf(1, "deploy:func:%s failed: %v", stage, err)
}
},
Expand Down
49 changes: 45 additions & 4 deletions internal/actions/deploy/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"
"path/filepath"
"strings"
"sync"

"github.com/Drafteame/draft/internal/pkg/aws"
"github.com/Drafteame/draft/internal/pkg/exec"
Expand All @@ -14,9 +15,9 @@ import (

const deployRegion = "us-east-2"

// DeployFunction packages and deploys a single Lambda function using the given env config.
// serviceArg can be a service name or a path.
func DeployFunction(env EnvConfig, serviceArg, functionName string) error {
// DeployFunction packages and deploys one or more Lambda functions using the given env config.
// serviceArg can be a service name or a path. All functions must belong to the same service.
func DeployFunction(env EnvConfig, serviceArg string, functionNames []string) error {
absPath, err := resolveService(serviceArg)
if err != nil {
return err
Expand Down Expand Up @@ -62,6 +63,47 @@ func DeployFunction(env EnvConfig, serviceArg, functionName string) error {
return err
}

type result struct {
name string
err error
}

results := make([]result, len(functionNames))
var wg sync.WaitGroup

for i, functionName := range functionNames {
wg.Add(1)
go func(i int, functionName string) {
defer wg.Done()
results[i] = result{
name: functionName,
err: deployOneFunction(env, absPath, serviceName, stage, functionName),
}
}(i, functionName)
}

wg.Wait()

hasError := false
if len(functionNames) > 1 {
log.Info("\n─── Deploy Summary ───")
}
for _, r := range results {
if r.err != nil {
log.Errorf("✗ %s: %v", r.name, r.err)
hasError = true
} else {
log.Successf("✓ %s", r.name)
}
}

if hasError {
return fmt.Errorf("one or more function deploys failed")
}
return nil
}

func deployOneFunction(env EnvConfig, absPath, serviceName, stage, functionName string) error {
fullLambdaName := fmt.Sprintf("%s-%s-%s", serviceName, stage, functionName)
log.Infof("Lambda function: %s", fullLambdaName)

Expand All @@ -80,7 +122,6 @@ func DeployFunction(env EnvConfig, serviceArg, functionName string) error {
return fmt.Errorf("lambda update failed: %w\n%s", err, out)
}

log.Success("✓ Lambda deployed: ", fullLambdaName)
return nil
}

Expand Down