Skip to content

Commit

Permalink
cli: Add alpha support for triggering deploys from cli
Browse files Browse the repository at this point in the history
  • Loading branch information
ekerfelt committed Sep 25, 2024
1 parent 4bc8592 commit ccf6d98
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 0 deletions.
88 changes: 88 additions & 0 deletions cli/cmd/encore/deploy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package main

import (
"encoding/hex"
"encoding/json"
"fmt"
"strings"

"github.com/cockroachdb/errors"
"github.com/logrusorgru/aurora/v3"
"github.com/spf13/cobra"

"encr.dev/cli/cmd/encore/cmdutil"
"encr.dev/cli/internal/platform"
"encr.dev/pkg/appfile"
)

var (
appSlug string
envName string
commit string
branch string
)

var deployAppCmd = &cobra.Command{
Use: "deploy --commit COMMIT_SHA_OR_BRANCH [flags]",
Short: "Deploy an Encore app to a cloud environment",
DisableFlagsInUseLine: true,
Hidden: true,
Run: func(c *cobra.Command, args []string) {
if commit != "" {
hb, err := hex.DecodeString(commit)
if err != nil || len(hb) != 20 {
cmdutil.Fatalf("invalid commit: %s", commit)
}
}
if appSlug == "" {
appRoot, _, err := cmdutil.MaybeAppRoot()
if err != nil {
cmdutil.Fatalf("no app found. Run deploy inside an encore app directory or specify the app with --app")
}
appSlug, err = appfile.Slug(appRoot)
if err != nil {
cmdutil.Fatalf("no app found. Run deploy inside an encore app directory or specify the app with --app")
}
}
if envName == "" {
envName = "@primary"
}
rollout, err := platform.Deploy(c.Context(), appSlug, envName, commit, branch)
var pErr platform.Error
if ok := errors.As(err, &pErr); ok {
switch pErr.Code {
case "app_not_found":
cmdutil.Fatalf("app not found: %s", appSlug)
case "validation":
var details platform.ValidationDetails
err := json.Unmarshal(pErr.Detail, &details)
if err != nil {
cmdutil.Fatalf("failed to deploy: %v", err)
}
switch details.Field {
case "commit":
cmdutil.Fatalf("could not find commit: %s. Is it pushed to the remote repository?", commit)
case "branch":
cmdutil.Fatalf("could not find branch: %s. Is it pushed to the remote repository?", branch)
case "env":
cmdutil.Fatalf("could not find environment: %s/%s", appSlug, envName)
}
}
}
if err != nil {
cmdutil.Fatalf("failed to deploy: %v", err)
}
url := fmt.Sprintf("https://app.encore.dev/%s/deploys/%s/%s", appSlug, rollout.EnvName, strings.TrimPrefix(rollout.ID, "roll_"))
fmt.Println(aurora.Sprintf("\n%s %s\n", aurora.Bold("Started Deploy:"), url))
},
}

func init() {
alphaCmd.AddCommand(deployAppCmd)
deployAppCmd.Flags().StringVar(&appSlug, "app", "", "app slug to deploy to. Defaults to the app defined in encore.app.")
deployAppCmd.Flags().StringVarP(&envName, "env", "e", "", "the environment to deploy to. Defaults to primary environment.")
deployAppCmd.Flags().StringVarP(&commit, "commit", "c", "", "commit to deploy.")
deployAppCmd.Flags().StringVarP(&branch, "branch", "b", "", "branch to deploy.")
deployAppCmd.MarkFlagsMutuallyExclusive("commit", "branch")
deployAppCmd.MarkFlagsOneRequired("commit", "branch")
}
23 changes: 23 additions & 0 deletions cli/internal/platform/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ type App struct {
MainBranch *string `json:"main_branch"` // nil if not set
}

type Rollout struct {
ID string `json:"id"`
EnvName string `json:"env_name"`
}

type Env struct {
ID string `json:"id"`
Slug string `json:"slug"`
Expand All @@ -42,6 +47,24 @@ func CreateApp(ctx context.Context, p *CreateAppParams) (*App, error) {
return &resp, err
}

func Deploy(ctx context.Context, appSlug, env, sha, branch string) (*Rollout, error) {
var resp Rollout
err := call(
ctx,
"POST",
fmt.Sprintf(
"/apps/%s/envs/%s/rollouts",
url.PathEscape(appSlug),
url.PathEscape(env),
), map[string]string{
"sha": sha,
"branch": branch,
},
&resp,
true)
return &resp, err
}

func ListApps(ctx context.Context) ([]*App, error) {
var resp []*App
err := call(ctx, "GET", "/user/apps", nil, &resp, true)
Expand Down
5 changes: 5 additions & 0 deletions cli/internal/platform/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ type Error struct {
Detail json.RawMessage
}

type ValidationDetails struct {
Field string `json:"field"`
Type string `json:"type"`
}

func (e Error) Error() string {
if len(e.Detail) > 0 {
return fmt.Sprintf("http %s: code=%s detail=%s", e.HTTPStatus, e.Code, e.Detail)
Expand Down

0 comments on commit ccf6d98

Please sign in to comment.