github.com/webonyx/up@v0.7.4-0.20180808230834-91b94e551323/internal/cli/deploy/deploy.go (about) 1 package deploy 2 3 import ( 4 "os" 5 "time" 6 7 "github.com/pkg/errors" 8 "github.com/tj/go/git" 9 "github.com/tj/go/term" 10 "github.com/tj/kingpin" 11 12 "github.com/apex/up" 13 "github.com/apex/up/internal/cli/root" 14 "github.com/apex/up/internal/setup" 15 "github.com/apex/up/internal/stats" 16 "github.com/apex/up/internal/util" 17 "github.com/apex/up/internal/validate" 18 ) 19 20 func init() { 21 cmd := root.Command("deploy", "Deploy the project.").Default() 22 stage := cmd.Arg("stage", "Target stage name.").Default("staging").String() 23 cmd.Example(`up deploy`, "Deploy the project the staging environment.") 24 cmd.Example(`up deploy production`, "Deploy the project to the production environment.") 25 26 cmd.Action(func(_ *kingpin.ParseContext) error { 27 return deploy(*stage) 28 }) 29 } 30 31 func deploy(stage string) error { 32 retry: 33 c, p, err := root.Init() 34 35 // missing up.json non-interactive 36 if isMissingConfig(err) && !term.IsTerminal(os.Stdin.Fd()) { 37 return errors.New("Cannot find ./up.json configuration file.") 38 } 39 40 // missing up.json interactive 41 if isMissingConfig(err) { 42 err := setup.Create() 43 44 if err == setup.ErrNoCredentials { 45 return errors.New("Cannot find credentials, visit https://up.docs.apex.sh/#aws_credentials for help.") 46 } 47 48 if err != nil { 49 return errors.Wrap(err, "setup") 50 } 51 52 util.Log("Deploying the project and creating resources.") 53 goto retry 54 } 55 56 // unrelated error 57 if err != nil { 58 return errors.Wrap(err, "initializing") 59 } 60 61 // validate stage name 62 if err := validate.List(stage, c.Stages.RemoteNames()); err != nil { 63 return err 64 } 65 66 // stage overrides 67 if err := c.Override(stage); err != nil { 68 return errors.Wrap(err, "overriding") 69 } 70 71 // git information 72 commit, err := getCommit() 73 if err != nil { 74 return errors.Wrap(err, "fetching git commit") 75 } 76 77 defer util.Pad()() 78 start := time.Now() 79 80 if err := p.Init(stage); err != nil { 81 return errors.Wrap(err, "initializing") 82 } 83 84 if err := p.Deploy(up.Deploy{ 85 Stage: stage, 86 Commit: util.StripLerna(commit.Describe()), 87 Author: commit.Author.Name, 88 }); err != nil { 89 return err 90 } 91 92 stats.Track("Deploy", map[string]interface{}{ 93 "duration": util.MillisecondsSince(start), 94 "type": c.Type, 95 "regions": c.Regions, 96 "stage": stage, 97 "proxy_timeout": c.Proxy.Timeout, 98 "header_rules_count": len(c.Headers), 99 "redirect_rules_count": len(c.Redirects), 100 "inject_rules_count": len(c.Inject), 101 "environment_count": len(c.Environment), 102 "dns_zone_count": len(c.DNS.Zones), 103 "stage_count": len(c.Stages.List()), 104 "stage_domain_count": len(c.Stages.Domains()), 105 "lambda_accelerate": c.Lambda.Accelerate, 106 "lambda_memory": c.Lambda.Memory, 107 "has_cors": c.CORS != nil, 108 "has_logs": !c.Logs.Disable, 109 "has_profile": c.Profile != "", 110 "has_error_pages": !c.ErrorPages.Disable, 111 "app_name_hash": util.Md5(c.Name), 112 "is_git": commit.Author.Name != "", 113 "alerts_count": len(c.Alerts), 114 "actions_count": len(c.Actions), 115 }) 116 117 stats.Flush() 118 return nil 119 } 120 121 // isMissingConfig returns true if the error represents a missing up.json. 122 func isMissingConfig(err error) bool { 123 err = errors.Cause(err) 124 e, ok := err.(*os.PathError) 125 return ok && e.Path == "up.json" 126 } 127 128 // getCommit returns the git information when available. 129 func getCommit() (git.Commit, error) { 130 c, err := git.GetCommit(".", "HEAD") 131 if err != nil && !isIgnorable(err) { 132 return git.Commit{}, err 133 } 134 135 if c == nil { 136 return git.Commit{}, nil 137 } 138 139 return *c, nil 140 } 141 142 // isIgnorable returns true if the GIT error is ignorable. 143 func isIgnorable(err error) bool { 144 switch err { 145 case git.ErrLookup, git.ErrNoRepo, git.ErrDirty: 146 return true 147 default: 148 return false 149 } 150 }