Skip to content
Draft
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
7 changes: 4 additions & 3 deletions src/cmd/cli/command/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/DefangLabs/defang/src/pkg/clouds/aws"
pcluster "github.com/DefangLabs/defang/src/pkg/cluster"
"github.com/DefangLabs/defang/src/pkg/dryrun"
"github.com/DefangLabs/defang/src/pkg/github"
"github.com/DefangLabs/defang/src/pkg/login"
"github.com/DefangLabs/defang/src/pkg/logs"
"github.com/DefangLabs/defang/src/pkg/mcp"
Expand Down Expand Up @@ -127,7 +128,7 @@ func Execute(ctx context.Context) error {
}

if hasTty && !hideUpdate && pkg.RandomIndex(10) == 0 {
if latest, err := GetLatestVersion(ctx); err == nil && isNewer(GetCurrentVersion(), latest) {
if latest, err := github.GetLatestReleaseTag(ctx); err == nil && isNewer(GetCurrentVersion(), latest) {
term.Debug("Latest Version:", latest, "Current Version:", GetCurrentVersion())
fmt.Println("A newer version of the CLI is available at https://github.com/DefangLabs/defang/releases/latest")
if pkg.RandomIndex(10) == 0 && !pkg.GetenvBool("DEFANG_HIDE_HINTS") {
Expand Down Expand Up @@ -620,7 +621,7 @@ var getVersionCmd = &cobra.Command{
fmt.Println(GetCurrentVersion())

term.Printc(term.BrightCyan, "Latest CLI: ")
ver, err := GetLatestVersion(cmd.Context())
ver, err := github.GetLatestReleaseTag(cmd.Context())
fmt.Println(ver)

term.Printc(term.BrightCyan, "Defang Fabric: ")
Expand Down Expand Up @@ -698,7 +699,7 @@ var configSetCmd = &cobra.Command{
value = strings.TrimSuffix(string(bytes), "\n")
} else if random {
// Generate a random value for the config
value = CreateRandomConfigValue()
value = cli.CreateRandomConfigValue()
term.Info("Generated random value: " + value)
} else {
// Prompt for sensitive value
Expand Down
16 changes: 15 additions & 1 deletion src/cmd/cli/command/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
cliClient "github.com/DefangLabs/defang/src/pkg/cli/client"
"github.com/DefangLabs/defang/src/pkg/cli/client/byoc"
"github.com/DefangLabs/defang/src/pkg/cli/compose"
pcluster "github.com/DefangLabs/defang/src/pkg/cluster"
"github.com/DefangLabs/defang/src/pkg/dryrun"
"github.com/DefangLabs/defang/src/pkg/logs"
"github.com/DefangLabs/defang/src/pkg/modes"
Expand All @@ -26,6 +27,19 @@ import (
"github.com/spf13/cobra"
)

const DEFANG_PORTAL_HOST = "portal.defang.io"
const SERVICE_PORTAL_URL = "https://" + DEFANG_PORTAL_HOST + "/service"

func printPlaygroundPortalServiceURLs(serviceInfos []*defangv1.ServiceInfo) {
// We can only show services deployed to the prod1 defang SaaS environment.
if providerID == cliClient.ProviderDefang && cluster == pcluster.DefaultCluster {
term.Info("Monitor your services' status in the defang portal")
for _, serviceInfo := range serviceInfos {
term.Println(" -", SERVICE_PORTAL_URL+"/"+serviceInfo.Service.Name)
}
}
}

var logType = logs.LogTypeAll

func makeComposeUpCmd() *cobra.Command {
Expand Down Expand Up @@ -170,7 +184,7 @@ func makeComposeUpCmd() *cobra.Command {
}

// Print the current service states of the deployment
err = printServiceStatesAndEndpoints(deploy.Services)
err = cli.PrintServiceStatesAndEndpoints(ctx, deploy.Services)
if err != nil {
return err
}
Expand Down
30 changes: 30 additions & 0 deletions src/cmd/cli/command/compose_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package command

import (
"bytes"
"os"
"testing"

cliClient "github.com/DefangLabs/defang/src/pkg/cli/client"
pcluster "github.com/DefangLabs/defang/src/pkg/cluster"
"github.com/DefangLabs/defang/src/pkg/term"
defangv1 "github.com/DefangLabs/defang/src/protos/io/defang/v1"
)

func TestInitializeTailCmd(t *testing.T) {
Expand All @@ -14,3 +21,26 @@ func TestInitializeTailCmd(t *testing.T) {
}
})
}

func TestPrintPlaygroundPortalServiceURLs(t *testing.T) {
defaultTerm := term.DefaultTerm
t.Cleanup(func() {
term.DefaultTerm = defaultTerm
})

var stdout, stderr bytes.Buffer
term.DefaultTerm = term.NewTerm(os.Stdin, &stdout, &stderr)

providerID = cliClient.ProviderDefang
cluster = pcluster.DefaultCluster
printPlaygroundPortalServiceURLs([]*defangv1.ServiceInfo{
{
Service: &defangv1.Service{Name: "service1"},
}})
const want = ` * Monitor your services' status in the defang portal
- https://portal.defang.io/service/service1
`
if got := stdout.String(); got != want {
t.Errorf("got %q, want %q", got, want)
}
}
86 changes: 0 additions & 86 deletions src/cmd/cli/command/deploymentinfo.go

This file was deleted.

47 changes: 0 additions & 47 deletions src/cmd/cli/command/version.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
package command

import (
"context"
"encoding/json"
"fmt"
"os"
"strings"

"github.com/DefangLabs/defang/src/pkg/http"
"github.com/DefangLabs/defang/src/pkg/term"
"golang.org/x/mod/semver"
)

Expand Down Expand Up @@ -36,44 +30,3 @@ func GetCurrentVersion() string {
version, _ := normalizeVersion(RootCmd.Version)
return version
}

type githubError struct {
Message string
Status string
DocumentationUrl string
}

func GetLatestVersion(ctx context.Context) (string, error) {
// Anonymous API request to GitHub are rate limited to 60 requests per hour per IP.
// Check whether the user has set a GitHub token to increase the rate limit. (Copied from the install script.)
githubToken := os.Getenv("GITHUB_TOKEN")
if githubToken == "" {
githubToken = os.Getenv("GH_TOKEN")
}
header := http.Header{}
if githubToken != "" {
header["Authorization"] = []string{"Bearer " + githubToken}
}
resp, err := http.GetWithHeader(ctx, "https://api.github.com/repos/DefangLabs/defang/releases/latest", header)
if err != nil {
return "", err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
term.Debug(resp.Header)
// The primary rate limit for unauthenticated requests is 60 requests per hour, per IP.
// The API returns a 403 status code when the rate limit is exceeded.
githubError := githubError{Message: resp.Status}
if err := json.NewDecoder(resp.Body).Decode(&githubError); err != nil {
term.Debugf("Failed to decode GitHub response: %v", err)
}
return "", fmt.Errorf("error fetching release info from GitHub: %s", githubError.Message)
}
var release struct {
TagName string `json:"tag_name"`
}
if err = json.NewDecoder(resp.Body).Decode(&release); err != nil {
return "", err
}
return release.TagName, nil
}
40 changes: 0 additions & 40 deletions src/cmd/cli/command/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ package command
import (
"fmt"
"net/http"
"net/http/httptest"
"testing"

ourHttp "github.com/DefangLabs/defang/src/pkg/http"
)

func TestIsNewer(t *testing.T) {
Expand Down Expand Up @@ -67,40 +64,3 @@ func (rt *mockRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)
}
return rt.resp, nil
}

func TestGetLatestVersion(t *testing.T) {
if testing.Short() {
t.Skip("skipping GitHub HTTP test in short mode to avoid rate limits.")
}

ctx := t.Context()

const version = "v1.2.3"
rec := httptest.NewRecorder()
rec.Header().Add("Content-Type", "application/json")
rec.WriteString(fmt.Sprintf(`{"tag_name":"%v"}`, version))
response := rec.Result()

client := ourHttp.DefaultClient
t.Cleanup(func() {
ourHttp.DefaultClient = client
response.Body.Close()
})

ourHttp.DefaultClient = &http.Client{Transport: &mockRoundTripper{
method: http.MethodGet,
url: "https://api.github.com/repos/DefangLabs/defang/releases/latest",
resp: response,
}}

v, err := GetLatestVersion(ctx)
if err != nil {
t.Fatalf("GetLatestVersion() error = %v; want nil", err)
}
if v == "" {
t.Fatalf("GetLatestVersion() = %v; want non-empty", v)
}
if v != version {
t.Errorf("GetLatestVersion() = %v; want %v", v, version)
}
}
Loading
Loading