github.com/orangenpresse/up@v0.6.0/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: 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_memory": c.Lambda.Memory, 106 "has_cors": c.CORS != nil, 107 "has_logs": !c.Logs.Disable, 108 "has_profile": c.Profile != "", 109 "has_error_pages": !c.ErrorPages.Disable, 110 "app_name_hash": util.Md5(c.Name), 111 "is_git": commit.Author.Name != "", 112 }) 113 114 stats.Flush() 115 return nil 116 } 117 118 // isMissingConfig returns true if the error represents a missing up.json. 119 func isMissingConfig(err error) bool { 120 err = errors.Cause(err) 121 e, ok := err.(*os.PathError) 122 return ok && e.Path == "up.json" 123 } 124 125 // getCommit returns the git information when available. 126 func getCommit() (git.Commit, error) { 127 c, err := git.GetCommit(".", "HEAD") 128 if err != nil && !isIgnorable(err) { 129 return git.Commit{}, err 130 } 131 132 if c == nil { 133 return git.Commit{}, nil 134 } 135 136 return *c, nil 137 } 138 139 // isIgnorable returns true if the GIT error is ignorable. 140 func isIgnorable(err error) bool { 141 switch err { 142 case git.ErrLookup, git.ErrNoRepo, git.ErrDirty: 143 return true 144 default: 145 return false 146 } 147 }