-
Notifications
You must be signed in to change notification settings - Fork 434
Add apps detect command #1227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add apps detect command #1227
Changes from all commits
e7068a8
8bdde7c
7fdb711
5053433
64fe585
d38d83c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -22,6 +22,7 @@ import ( | |||||
"net/http" | ||||||
"net/url" | ||||||
"os" | ||||||
"strconv" | ||||||
"strings" | ||||||
"time" | ||||||
|
||||||
|
@@ -113,6 +114,15 @@ This permanently deletes the app and all its associated deployments.`, | |||||
) | ||||||
AddBoolFlag(deleteApp, doctl.ArgForce, doctl.ArgShortForce, false, "Delete the App without a confirmation prompt") | ||||||
|
||||||
// output is global flag | ||||||
detect := CmdBuilder(cmd, | ||||||
RunAppsDetect, "detect", "Detect functions", "Detect functions project and convert it into apps project by adding the AppSpec.", Writer, aliasOpt("dt")) | ||||||
AddStringFlag(detect, doctl.ArgProjectSource, "", "", `Project source.`) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should check if we are currently in a git project directory and attempt to default to that source repo. |
||||||
AddStringFlag(detect, doctl.ArgCommitHash, "", "", `Git commit hash`) // not sure if need to support commit hash? | ||||||
AddStringFlag(detect, doctl.ArgProjectName, "", "", `App name to be used`) | ||||||
AddStringFlag(detect, doctl.ArgProjectBrach, "", "", `Project branch to be used`) | ||||||
AddBoolFlag(detect, doctl.ArgDeployOnPush, "", *boolPtr(true), `Auto deploy on project update.`) | ||||||
|
||||||
deploymentCreate := CmdBuilder( | ||||||
cmd, | ||||||
RunAppsCreateDeployment, | ||||||
|
@@ -393,6 +403,69 @@ func RunAppsDelete(c *CmdConfig) error { | |||||
return nil | ||||||
} | ||||||
|
||||||
// RunAppsDetect detects an function project and converts it into apps project. | ||||||
func RunAppsDetect(c *CmdConfig) error { | ||||||
source, err := c.Doit.GetString(c.NS, doctl.ArgProjectSource) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
if len(source) == 0 { | ||||||
return fmt.Errorf("source cannot be empty") | ||||||
} | ||||||
|
||||||
sha, err := c.Doit.GetString(c.NS, doctl.ArgCommitHash) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
|
||||||
name, err := c.Doit.GetString(c.NS, doctl.ArgProjectName) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
if len(name) == 0 { | ||||||
return fmt.Errorf("name cannot be empty") | ||||||
} | ||||||
|
||||||
branch, err := c.Doit.GetString(c.NS, doctl.ArgProjectBrach) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
if len(branch) == 0 { | ||||||
return fmt.Errorf("branch cannot be empty") | ||||||
} | ||||||
|
||||||
// Need to check, How user value will be overrided | ||||||
autoDeploy, err := c.Doit.GetBool(c.NS, doctl.ArgDeployOnPush) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
if len(c.Args) > 0 { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we need argument parsing here if we are including |
||||||
fmt.Println(c.Args[0]) | ||||||
x, err := strconv.ParseBool(c.Args[0]) | ||||||
if err == nil { | ||||||
autoDeploy = x | ||||||
} else { | ||||||
return fmt.Errorf("expected true/false for deploy-on-push, received : %s", c.Args[0]) | ||||||
} | ||||||
} | ||||||
|
||||||
spec, err := c.Apps().Detect(source, sha, name, branch, autoDeploy) | ||||||
if err != nil { | ||||||
return err | ||||||
} | ||||||
|
||||||
switch Output { | ||||||
case "json": | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should support YAML here as well |
||||||
e := json.NewEncoder(c.Out) | ||||||
e.SetIndent("", " ") | ||||||
return e.Encode(spec) | ||||||
case "text": | ||||||
return nil | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (assuming this is just not implemented yet) just a reminder to either error out if not supported or implemented output support |
||||||
default: | ||||||
return fmt.Errorf("unknown output type") | ||||||
} | ||||||
} | ||||||
|
||||||
// RunAppsCreateDeployment creates a deployment for an app. | ||||||
func RunAppsCreateDeployment(c *CmdConfig) error { | ||||||
if len(c.Args) < 1 { | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ package do | |
|
||
import ( | ||
"context" | ||
"strings" | ||
|
||
"github.com/digitalocean/godo" | ||
) | ||
|
@@ -26,6 +27,7 @@ type AppsService interface { | |
List() ([]*godo.App, error) | ||
Update(appID string, req *godo.AppUpdateRequest) (*godo.App, error) | ||
Delete(appID string) error | ||
Detect(source string, sha string, name string, branch string, autoDeploy bool) (*godo.AppSpec, error) | ||
Propose(req *godo.AppProposeRequest) (*godo.AppProposeResponse, error) | ||
|
||
CreateDeployment(appID string, forceRebuild bool) (*godo.Deployment, error) | ||
|
@@ -119,6 +121,86 @@ func (s *appsService) Delete(appID string) error { | |
return err | ||
} | ||
|
||
func (s *appsService) Detect(source string, sha string, name string, branch string, autoDeploy bool) (*godo.AppSpec, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should consider changing this signature to only inline required parameters and put the rest in an options struct. e.g.:
|
||
var dr godo.DetectRequest | ||
if strings.Contains(source, "github") { | ||
dr.GitHub = &godo.GitHubSourceSpec{ | ||
Repo: verifyGitSource(source, "github"), | ||
Branch: branch, | ||
DeployOnPush: autoDeploy, | ||
} | ||
} else if strings.Contains(source, "gitlab") { | ||
dr.GitLab = &godo.GitLabSourceSpec{ | ||
Repo: verifyGitSource(source, "gitlab"), | ||
Branch: branch, | ||
DeployOnPush: autoDeploy, | ||
} | ||
} else { | ||
dr.Git = &godo.GitSourceSpec{ | ||
RepoCloneURL: source, | ||
Branch: branch, | ||
} | ||
} | ||
dr.SourceDir = "/" | ||
dr.CommitSHA = sha | ||
|
||
resp, _, err := s.client.Apps.Detect(context.Background(), &dr) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var appSpec godo.AppSpec | ||
|
||
appSpec.Name = name | ||
var funcSpecArray []*godo.AppFunctionsSpec | ||
for _, component := range resp.Components { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should add a warning message stating other component types are not yet supported if we encounter them in the spec. |
||
|
||
if component.Strategy == "SERVERLESS" { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should print out a warning if we detect non serverless component strategies for now until we support them. |
||
for _, serverlessPackage := range component.ServerlessPackages { | ||
var functionSpec godo.AppFunctionsSpec | ||
functionSpec.Name = serverlessPackage.Name | ||
if strings.Contains(source, "github") { | ||
functionSpec.GitHub = &godo.GitHubSourceSpec{ | ||
Repo: verifyGitSource(source, "github"), | ||
Branch: branch, | ||
DeployOnPush: autoDeploy, | ||
} | ||
} else if strings.Contains(source, "gitlab") { | ||
functionSpec.GitLab = &godo.GitLabSourceSpec{ | ||
Repo: verifyGitSource(source, "gitlab"), | ||
Branch: branch, | ||
DeployOnPush: autoDeploy, | ||
} | ||
} else { | ||
functionSpec.Git = &godo.GitSourceSpec{ | ||
RepoCloneURL: source, | ||
Branch: branch, | ||
} | ||
} | ||
functionSpec.SourceDir = "/" | ||
functionSpec.Routes = []*godo.AppRouteSpec{ | ||
{ | ||
Path: "/", | ||
PreservePathPrefix: false, | ||
}, | ||
} | ||
funcSpecArray = append(funcSpecArray, &functionSpec) | ||
|
||
} | ||
} | ||
appSpec.Functions = funcSpecArray | ||
} | ||
return &appSpec, nil | ||
} | ||
|
||
func verifyGitSource(s string, splitter string) string { | ||
x := strings.Split(s, splitter+".com/") | ||
if strings.Contains(x[1], ".git") { | ||
x = strings.Split(x[1], ".") | ||
} | ||
return x[0] | ||
} | ||
|
||
func (s *appsService) Propose(req *godo.AppProposeRequest) (*godo.AppProposeResponse, error) { | ||
res, _, err := s.client.Apps.Propose(s.ctx, req) | ||
if err != nil { | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.