From 6fa79bcf5118ed67b9610f30c5c1442b00b9ae16 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Fri, 28 Nov 2025 19:38:30 +0800 Subject: [PATCH 1/3] fix: skip connecting to database on link --- internal/link/link.go | 15 +++++---------- pkg/config/storage.go | 1 + 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/internal/link/link.go b/internal/link/link.go index 9c7d0ce97..8e3a38d3e 100644 --- a/internal/link/link.go +++ b/internal/link/link.go @@ -13,7 +13,6 @@ import ( "github.com/jackc/pgx/v4" "github.com/spf13/afero" "github.com/supabase/cli/internal/utils" - "github.com/supabase/cli/internal/utils/flags" "github.com/supabase/cli/internal/utils/tenant" "github.com/supabase/cli/pkg/api" "github.com/supabase/cli/pkg/cast" @@ -34,20 +33,13 @@ func Run(ctx context.Context, projectRef string, skipPooler bool, fsys afero.Fs, } LinkServices(ctx, projectRef, keys.ServiceRole, skipPooler, fsys) - // 2. Check database connection - if config, err := flags.NewDbConfigWithPassword(ctx, projectRef); err != nil { - fmt.Fprintln(os.Stderr, utils.Yellow("WARN:"), err) - } else if err := linkDatabase(ctx, config, fsys, options...); err != nil { - return err - } - - // 3. Save project ref + // 2. Save project ref if err := utils.WriteFile(utils.ProjectRefPath, []byte(projectRef), fsys); err != nil { return err } fmt.Fprintln(os.Stdout, "Finished "+utils.Aqua("supabase link")+".") - // 4. Suggest config update + // 3. Suggest config update if utils.Config.Db.MajorVersion != majorVersion { fmt.Fprintln(os.Stderr, utils.Yellow("WARNING:"), "Local database version differs from the linked project.") fmt.Fprintf(os.Stderr, `Update your %s to fix it: @@ -88,6 +80,9 @@ func LinkServices(ctx context.Context, projectRef, serviceKey string, skipPooler if err := jq.Collect(); err != nil { fmt.Fprintln(logger, err) } + if err := utils.WriteFile(utils.StorageMigrationPath, []byte(utils.Config.Storage.TargetMigration), fsys); err != nil { + fmt.Fprintln(logger, err) + } } func linkPostgrest(ctx context.Context, projectRef string) error { diff --git a/pkg/config/storage.go b/pkg/config/storage.go index a692d238e..cfd03e3d4 100644 --- a/pkg/config/storage.go +++ b/pkg/config/storage.go @@ -70,6 +70,7 @@ func (s *storage) ToUpdateStorageConfigBody() v1API.UpdateStorageConfigBody { func (s *storage) FromRemoteStorageConfig(remoteConfig v1API.StorageConfigResponse) { s.FileSizeLimit = sizeInBytes(remoteConfig.FileSizeLimit) + s.TargetMigration = remoteConfig.MigrationVersion // When local config is not set, we assume platform defaults should not change if s.ImageTransformation != nil { s.ImageTransformation.Enabled = remoteConfig.Features.ImageTransformation.Enabled From 0265082e868ec774b8a206041a74468f1c31eb21 Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Fri, 28 Nov 2025 20:07:05 +0800 Subject: [PATCH 2/3] Update link.go --- internal/link/link.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/internal/link/link.go b/internal/link/link.go index 8e3a38d3e..50ec1e95f 100644 --- a/internal/link/link.go +++ b/internal/link/link.go @@ -58,7 +58,7 @@ func LinkServices(ctx context.Context, projectRef, serviceKey string, skipPooler func() error { return linkNetworkRestrictions(ctx, projectRef) }, func() error { return linkPostgrest(ctx, projectRef) }, func() error { return linkGotrue(ctx, projectRef) }, - func() error { return linkStorage(ctx, projectRef) }, + func() error { return linkStorage(ctx, projectRef, fsys) }, func() error { if skipPooler { utils.Config.Db.Pooler.ConnectionString = "" @@ -80,9 +80,6 @@ func LinkServices(ctx context.Context, projectRef, serviceKey string, skipPooler if err := jq.Collect(); err != nil { fmt.Fprintln(logger, err) } - if err := utils.WriteFile(utils.StorageMigrationPath, []byte(utils.Config.Storage.TargetMigration), fsys); err != nil { - fmt.Fprintln(logger, err) - } } func linkPostgrest(ctx context.Context, projectRef string) error { @@ -123,7 +120,7 @@ func linkGotrueVersion(ctx context.Context, api tenant.TenantAPI, fsys afero.Fs) return utils.WriteFile(utils.GotrueVersionPath, []byte(version), fsys) } -func linkStorage(ctx context.Context, projectRef string) error { +func linkStorage(ctx context.Context, projectRef string, fsys afero.Fs) error { resp, err := utils.GetSupabase().V1GetStorageConfigWithResponse(ctx, projectRef) if err != nil { return errors.Errorf("failed to read Storage config: %w", err) @@ -131,7 +128,7 @@ func linkStorage(ctx context.Context, projectRef string) error { return errors.Errorf("unexpected Storage config status %d: %s", resp.StatusCode(), string(resp.Body)) } utils.Config.Storage.FromRemoteStorageConfig(*resp.JSON200) - return nil + return utils.WriteFile(utils.StorageMigrationPath, []byte(utils.Config.Storage.TargetMigration), fsys) } func linkStorageVersion(ctx context.Context, api tenant.TenantAPI, fsys afero.Fs) error { From caf44d2e01f3dd405a9d7667f991da25c269b4a7 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Mon, 1 Dec 2025 11:18:43 +0800 Subject: [PATCH 3/3] chore: refactor postgres version link --- cmd/link.go | 5 +++++ internal/link/link.go | 45 ++++++++++++++++++++++--------------------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/cmd/link.go b/cmd/link.go index f2422ff48..82b5f4ca3 100644 --- a/cmd/link.go +++ b/cmd/link.go @@ -1,6 +1,7 @@ package cmd import ( + "fmt" "os" "os/signal" @@ -8,6 +9,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/supabase/cli/internal/link" + "github.com/supabase/cli/internal/utils" "github.com/supabase/cli/internal/utils/flags" "golang.org/x/term" ) @@ -39,6 +41,9 @@ var ( cobra.CheckErr(viper.BindPFlag("DB_PASSWORD", cmd.Flags().Lookup("password"))) return link.Run(ctx, flags.ProjectRef, skipPooler, fsys) }, + PostRun: func(cmd *cobra.Command, args []string) { + fmt.Fprintln(os.Stdout, "Finished "+utils.Aqua("supabase link")+".") + }, } ) diff --git a/internal/link/link.go b/internal/link/link.go index 50ec1e95f..6832876ac 100644 --- a/internal/link/link.go +++ b/internal/link/link.go @@ -21,33 +21,18 @@ import ( ) func Run(ctx context.Context, projectRef string, skipPooler bool, fsys afero.Fs, options ...func(*pgx.ConnConfig)) error { - majorVersion := utils.Config.Db.MajorVersion + // 1. Link postgres version if err := checkRemoteProjectStatus(ctx, projectRef, fsys); err != nil { return err } - - // 1. Check service config + // 2. Check service config keys, err := tenant.GetApiKeys(ctx, projectRef) if err != nil { return err } LinkServices(ctx, projectRef, keys.ServiceRole, skipPooler, fsys) - - // 2. Save project ref - if err := utils.WriteFile(utils.ProjectRefPath, []byte(projectRef), fsys); err != nil { - return err - } - fmt.Fprintln(os.Stdout, "Finished "+utils.Aqua("supabase link")+".") - - // 3. Suggest config update - if utils.Config.Db.MajorVersion != majorVersion { - fmt.Fprintln(os.Stderr, utils.Yellow("WARNING:"), "Local database version differs from the linked project.") - fmt.Fprintf(os.Stderr, `Update your %s to fix it: -[db] -major_version = %d -`, utils.Bold(utils.ConfigPath), utils.Config.Db.MajorVersion) - } - return nil + // 3. Save project ref + return utils.WriteFile(utils.ProjectRefPath, []byte(projectRef), fsys) } func LinkServices(ctx context.Context, projectRef, serviceKey string, skipPooler bool, fsys afero.Fs) { @@ -245,8 +230,24 @@ func checkRemoteProjectStatus(ctx context.Context, projectRef string, fsys afero } // Update postgres image version to match the remote project - if version := resp.JSON200.Database.Version; len(version) > 0 { - return utils.WriteFile(utils.PostgresVersionPath, []byte(version), fsys) + return linkPostgresVersion(resp.JSON200.Database.Version, fsys) +} + +func linkPostgresVersion(version string, fsys afero.Fs) error { + if len(version) == 0 { + return nil } - return nil + majorVersion, err := strconv.ParseUint(strings.Split(version, ".")[0], 10, 7) + if err != nil { + return errors.Errorf("invalid major version: %w", err) + } + if uint64(utils.Config.Db.MajorVersion) != majorVersion { + fmt.Fprintln(os.Stderr, utils.Yellow("WARNING:"), "Local database version differs from the linked project.") + fmt.Fprintf(os.Stderr, `Update your %s to fix it: +[db] +major_version = %d +`, utils.Bold(utils.ConfigPath), majorVersion) + } + utils.Config.Db.MajorVersion = uint(majorVersion) + return utils.WriteFile(utils.PostgresVersionPath, []byte(version), fsys) }