Repository: supabase/cli
Pull request #2665 (2024-09-09 23:02:59)

feat: db reset skip seed flag
## What kind of change does this PR introduce?

feature add `--skip-seed` flag to `db reset` command

## What is the current behavior?

Currently, when resetting the local database using supabase db reset, the command always applies the seed data from seed.sql. There's no option to skip the seeding process, which can be inconvenient when users want to reset the database structure without populating it with seed data.

See: #2534 

## What is the new behavior?

This PR introduces a new `--skip-seed` flag for the supabase db reset command. When this flag is used, the reset process will recreate the database and apply migrations, but it will skip the seeding step. This allows users to reset their database structure without automatically populating it with seed data.



coveralls: ## Pull Request Test Coverage Report for [Build 10782632217](https://coveralls.io/builds/69698190)


### Details

* **14** of **20**   **(70.0%)**  changed or added relevant lines in **4** files are covered.
* **1** unchanged line in **1** file lost coverage.
* Overall coverage increased (+**0.04%**) to **60.026%**

---

|  Changes Missing Coverage | Covered Lines | Changed/Added Lines | % |
| :-----|--------------|--------|---: |
| [cmd/db.go](https://coveralls.io/builds/69698190/source?filename=cmd%2Fdb.go#L190) | 1 | 3 | 33.33%
| [internal/db/reset/reset.go](https://coveralls.io/builds/69698190/source?filename=internal%2Fdb%2Freset%2Freset.go#L73) | 8 | 12 | 66.67%
<!-- | **Total:** | **14** | **20** | **70.0%** | -->

|  Files with Coverage Reduction | New Missed Lines | % |
| :-----|--------------|--: |
| [cmd/db.go](https://coveralls.io/builds/69698190/source?filename=cmd%2Fdb.go#L192) | 1 | 59.41% |
<!-- | **Total:** | **1** |  | -->

|  Totals | [![Coverage Status](https://coveralls.io/builds/69698190/badge)](https://coveralls.io/builds/69698190) |
| :-- | --: |
| Change from base [Build 10777010816](https://coveralls.io/builds/69689425): |  0.04% |
| Covered Lines: | 6367 |
| Relevant Lines: | 10607 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b107b1cf..0f407815 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -18,6 +18,8 @@ jobs:
           go-version-file: go.mod
           cache: true
 
+      # Required by: internal/utils/credentials/keyring_test.go
+      - uses: t1m0thyj/unlock-keyring@v1
       - run: |
           go run gotest.tools/gotestsum -- ./... -race -v -count=1 \
           -coverpkg ./cmd/...,./internal/... -coverprofile=coverage.out
diff --git a/cmd/db.go b/cmd/db.go
index e2b109a2..2ddb4072 100644
--- a/cmd/db.go
+++ b/cmd/db.go
@@ -183,10 +183,15 @@ var (
 		},
 	}
 
+	noSeed bool
+
 	dbResetCmd = &cobra.Command{
 		Use:   "reset",
 		Short: "Resets the local database to current migrations",
 		RunE: func(cmd *cobra.Command, args []string) error {
+			if noSeed {
+				utils.Config.Db.Seed.Enabled = false
+			}
 			return reset.Run(cmd.Context(), migrationVersion, flags.DbConfig, afero.NewOsFs())
 		},
 	}
@@ -196,11 +201,16 @@ var (
 		Value:   lint.AllowedLevels[0],
 	}
 
+	lintFailOn = utils.EnumFlag{
+		Allowed: append([]string{"none"}, lint.AllowedLevels...),
+		Value:   "none",
+	}
+
 	dbLintCmd = &cobra.Command{
 		Use:   "lint",
 		Short: "Checks local database for typing error",
 		RunE: func(cmd *cobra.Command, args []string) error {
-			return lint.Run(cmd.Context(), schema, level.Value, flags.DbConfig, afero.NewOsFs())
+			return lint.Run(cmd.Context(), schema, level.Value, lintFailOn.Value, flags.DbConfig, afero.NewOsFs())
 		},
 	}
 
@@ -299,6 +309,7 @@ func init() {
 	resetFlags.String("db-url", "", "Resets the database specified by the connection string (must be percent-encoded).")
 	resetFlags.Bool("linked", false, "Resets the linked project with local migrations.")
 	resetFlags.Bool("local", true, "Resets the local database with local migrations.")
+	resetFlags.BoolVar(&noSeed, "no-seed", false, "Skip running the seed script after reset.")
 	dbResetCmd.MarkFlagsMutuallyExclusive("db-url", "linked", "local")
 	resetFlags.StringVar(&migrationVersion, "version", "", "Reset up to the specified version.")
 	dbCmd.AddCommand(dbResetCmd)
@@ -310,6 +321,7 @@ func init() {
 	dbLintCmd.MarkFlagsMutuallyExclusive("db-url", "linked", "local")
 	lintFlags.StringSliceVarP(&schema, "schema", "s", []string{}, "Comma separated list of schema to include.")
 	lintFlags.Var(&level, "level", "Error level to emit.")
+	lintFlags.Var(&lintFailOn, "fail-on", "Error level to exit with non-zero status.")
 	dbCmd.AddCommand(dbLintCmd)
 	// Build start command
 	dbCmd.AddCommand(dbStartCmd)
diff --git a/docs/supabase/db/lint.md b/docs/supabase/db/lint.md
index 33415dc2..3718d2d3 100644
--- a/docs/supabase/db/lint.md
+++ b/docs/supabase/db/lint.md
@@ -7,3 +7,11 @@ Requires the local development stack to be running when linting against the loca
 Runs `plpgsql_check` extension in the local Postgres container to check for errors in all schemas. The default lint level is `warning` and can be raised to error via the `--level` flag.
 
 To lint against specific schemas only, pass in the `--schema` flag.
+
+The `--fail-on` flag can be used to control when the command should exit with a non-zero status code. The possible values are:
+
+- `none` (default): Always exit with a zero status code, regardless of lint results.
+- `warning`: Exit with a non-zero status code if any warnings or errors are found.
+- `error`: Exit with a non-zero status code only if errors are found.
+
+This flag is particularly useful in CI/CD pipelines where you want to fail the build based on certain lint conditions.
\ No newline at end of file
diff --git a/go.mod b/go.mod
index fe4ede74..09427dee 100644
--- a/go.mod
+++ b/go.mod
@@ -12,6 +12,7 @@ require (
 	github.com/charmbracelet/glamour v0.7.0
 	github.com/charmbracelet/lipgloss v0.12.1
 	github.com/containers/common v0.59.2
+	github.com/danieljoos/wincred v1.2.1
 	github.com/deepmap/oapi-codegen/v2 v2.2.0
 	github.com/docker/cli v26.1.5+incompatible
 	github.com/docker/docker v26.1.5+incompatible
@@ -114,7 +115,6 @@ require (
 	github.com/curioswitch/go-reassign v0.2.0 // indirect
 	github.com/cyphar/filepath-securejoin v0.2.5 // indirect
 	github.com/daixiang0/gci v0.13.4 // indirect
-	github.com/danieljoos/wincred v1.2.1 // indirect
 	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
 	github.com/denis-tingaikin/go-header v0.5.0 // indirect
 	github.com/distribution/reference v0.6.0 // indirect
diff --git a/internal/db/lint/lint.go b/internal/db/lint/lint.go
index dc302600..5701d89b 100644
--- a/internal/db/lint/lint.go
+++ b/internal/db/lint/lint.go
@@ -39,7 +39,7 @@ func toEnum(level string) LintLevel {
 	return -1
 }
 
-func Run(ctx context.Context, schema []string, level string, config pgconn.Config, fsys afero.Fs, options ...func(*pgx.ConnConfig)) error {
+func Run(ctx context.Context, schema []string, level string, failOn string, config pgconn.Config, fsys afero.Fs, options ...func(*pgx.ConnConfig)) error {
 	// Sanity checks.
 	conn, err := utils.ConnectByConfig(ctx, config, options...)
 	if err != nil {
@@ -55,7 +55,26 @@ func Run(ctx context.Context, schema []string, level string, config pgconn.Confi
 		fmt.Fprintln(os.Stderr, "\nNo schema errors found")
 		return nil
 	}
-	return printResultJSON(result, toEnum(level), os.Stdout)
+
+	// Apply filtering based on the minimum level
+	minLevel := toEnum(level)
+	filtered := filterResult(result, minLevel)
+	err = printResultJSON(filtered, os.Stdout)
+	if err != nil {
+		return err
+	}
+	// Check for fail-on condition
+	failOnLevel := toEnum(failOn)
+	if failOnLevel != -1 {
+		for _, r := range filtered {
+			for _, issue := range r.Issues {
+				if toEnum(issue.Level) >= failOnLevel {
+					return fmt.Errorf("fail-on is set to %s, non-zero exit", AllowedLevels[failOnLevel])
+				}
+			}
+		}
+	}
+	return nil
 }
 
 func filterResult(result []Result, minLevel LintLevel) (filtered []Result) {
@@ -73,15 +92,14 @@ func filterResult(result []Result, minLevel LintLevel) (filtered []Result) {
 	return filtered
 }
 
-func printResultJSON(result []Result, minLevel LintLevel, stdout io.Writer) error {
-	filtered := filterResult(result, minLevel)
-	if len(filtered) == 0 {
+func printResultJSON(result []Result, stdout io.Writer) error {
+	if len(result) == 0 {
 		return nil
 	}
 	// Pretty print output
 	enc := json.NewEncoder(stdout)
 	enc.SetIndent("", "  ")
-	if err := enc.Encode(filtered); err != nil {
+	if err := enc.Encode(result); err != nil {
 		return errors.Errorf("failed to print result json: %w", err)
 	}
 	return nil
diff --git a/internal/migration/apply/apply.go b/internal/migration/apply/apply.go
index c9df3cac..44195297 100644
--- a/internal/migration/apply/apply.go
+++ b/internal/migration/apply/apply.go
@@ -20,6 +20,9 @@ func MigrateAndSeed(ctx context.Context, version string, conn *pgx.Conn, fsys af
 	if err := migration.ApplyMigrations(ctx, migrations, conn, afero.NewIOFS(fsys)); err != nil {
 		return err
 	}
+	if !utils.Config.Db.Seed.Enabled {
+		return nil
+	}
 	return SeedDatabase(ctx, conn, fsys)
 }
 
diff --git a/internal/utils/credentials/keyring_darwin.go b/internal/utils/credentials/keyring_darwin.go
new file mode 100644
index 00000000..cca5d72f
--- /dev/null
+++ b/internal/utils/credentials/keyring_darwin.go
@@ -0,0 +1,34 @@
+//go:build darwin
+
+package credentials
+
+import (
+	"os/exec"
+
+	"github.com/go-errors/errors"
+)
+
+const execPathKeychain = "/usr/bin/security"
+
+func deleteAll(service string) error {
+	if len(service) == 0 {
+		return errors.New("missing service name")
+	}
+	// Delete each secret in a while loop until there is no more left
+	for {
+		if err := exec.Command(
+			execPathKeychain,
+			"delete-generic-password",
+			"-s", service,
+		).Run(); err == nil {
+			continue
+		} else if errors.Is(err, exec.ErrNotFound) {
+			return errors.New(ErrNotSupported)
+		} else if exitError, ok := err.(*exec.ExitError); ok && exitError.ExitCode() == 44 {
+			// Exit 44 means no item exists for this service name
+			return nil
+		} else {
+			return errors.Errorf("failed to delete all credentials: %w", err)
+		}
+	}
+}
diff --git a/internal/utils/credentials/keyring_linux.go b/internal/utils/credentials/keyring_linux.go
new file mode 100644
index 00000000..08095cfb
--- /dev/null
+++ b/internal/utils/credentials/keyring_linux.go
@@ -0,0 +1,33 @@
+//go:build linux
+
+package credentials
+
+import (
+	"github.com/go-errors/errors"
+	ss "github.com/zalando/go-keyring/secret_service"
+)
+
+func deleteAll(service string) error {
+	svc, err := ss.NewSecretService()
+	if err != nil {
+		return errors.Errorf("failed to create secret service: %w", err)
+	}
+
+	collection := svc.GetLoginCollection()
+	if err := svc.Unlock(collection.Path()); err != nil {
+		return errors.Errorf("failed to unlock collection: %w", err)
+	}
+
+	search := map[string]string{"service": service}
+	results, err := svc.SearchItems(collection, search)
+	if err != nil {
+		return errors.Errorf("failed to search items: %w", err)
+	}
+
+	for _, item := range results {
+		if err := svc.Delete(item); err != nil {
+			return errors.Errorf("failed to delete all credentials: %w", err)
+		}
+	}
+	return nil
+}
diff --git a/internal/utils/credentials/keyring_windows.go b/internal/utils/credentials/keyring_windows.go
new file mode 100644
index 00000000..0366a686
--- /dev/null
+++ b/internal/utils/credentials/keyring_windows.go
@@ -0,0 +1,25 @@
+//go:build windows
+
+package credentials
+
+import (
+	"github.com/danieljoos/wincred"
+	"github.com/go-errors/errors"
+)
+
+func deleteAll(service string) error {
+	if err := assertKeyringSupported(); err != nil {
+		return err
+	}
+	creds, err := wincred.FilteredList(service + ":")
+	if err != nil {
+		return errors.Errorf("failed to list credentials: %w", err)
+	}
+	for _, c := range creds {
+		gc := wincred.GenericCredential{Credential: *c}
+		if err := gc.Delete(); err != nil {
+			return errors.Errorf("failed to delete all credentials: %w", err)
+		}
+	}
+	return nil
+}
diff --git a/internal/utils/credentials/store.go b/internal/utils/credentials/store.go
index 32a2abd2..ac7f0186 100644
--- a/internal/utils/credentials/store.go
+++ b/internal/utils/credentials/store.go
@@ -53,6 +53,11 @@ func Delete(project string) error {
 	return nil
 }
 
+// Deletes all stored credentials for the namespace
+func DeleteAll() error {
+	return deleteAll(namespace)
+}
+
 func assertKeyringSupported() error {
 	// Suggested check: https://github.com/microsoft/WSL/issues/423
 	if f, err := os.ReadFile("/proc/sys/kernel/osrelease"); err == nil {
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 4340b48f..a116b3ad 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -160,6 +160,11 @@ type (
 		Password     string `toml:"-"`
 		RootKey      string `toml:"-" mapstructure:"root_key"`
 		Pooler       pooler `toml:"pooler"`
+		Seed         seed   `toml:"seed"`
+	}
+
+	seed struct {
+		Enabled bool `toml:"enabled"`
 	}
 
 	pooler struct {
@@ -457,6 +462,9 @@ func NewConfig(editors ...ConfigEditor) config {
 				EncryptionKey: "12345678901234567890123456789032",
 				SecretKeyBase: "EAx3IQ/wRG1v47ZD4NE4/9RzBI8Jmil3x0yhcW4V2NHBP6c2iPIzwjofi2Ep4HIG",
 			},
+			Seed: seed{
+				Enabled: true,
+			},
 		},
 		Realtime: realtime{
 			Image:           realtimeImage,


Test patch:
diff --git a/internal/db/lint/lint_test.go b/internal/db/lint/lint_test.go
index 40ce0503..8d7abef8 100644
--- a/internal/db/lint/lint_test.go
+++ b/internal/db/lint/lint_test.go
@@ -65,7 +65,7 @@ func TestLintCommand(t *testing.T) {
 		Reply("SELECT 1", []interface{}{"f1", string(data)}).
 		Query("rollback").Reply("ROLLBACK")
 	// Run test
-	err = Run(context.Background(), []string{"public"}, "warning", dbConfig, fsys, conn.Intercept)
+	err = Run(context.Background(), []string{"public"}, "warning", "none", dbConfig, fsys, conn.Intercept)
 	// Check error
 	assert.NoError(t, err)
 	assert.Empty(t, apitest.ListUnmatchedRequests())
@@ -221,7 +221,8 @@ func TestPrintResult(t *testing.T) {
 	t.Run("filters warning level", func(t *testing.T) {
 		// Run test
 		var out bytes.Buffer
-		assert.NoError(t, printResultJSON(result, toEnum("warning"), &out))
+		filtered := filterResult(result, toEnum("warning"))
+		assert.NoError(t, printResultJSON(filtered, &out))
 		// Validate output
 		var actual []Result
 		assert.NoError(t, json.Unmarshal(out.Bytes(), &actual))
@@ -231,7 +232,8 @@ func TestPrintResult(t *testing.T) {
 	t.Run("filters error level", func(t *testing.T) {
 		// Run test
 		var out bytes.Buffer
-		assert.NoError(t, printResultJSON(result, toEnum("error"), &out))
+		filtered := filterResult(result, toEnum("error"))
+		assert.NoError(t, printResultJSON(filtered, &out))
 		// Validate output
 		var actual []Result
 		assert.NoError(t, json.Unmarshal(out.Bytes(), &actual))
@@ -240,4 +242,58 @@ func TestPrintResult(t *testing.T) {
 			Issues:   []Issue{result[0].Issues[1]},
 		}}, actual)
 	})
+
+	t.Run("exits with non-zero status on warning", func(t *testing.T) {
+		// Setup in-memory fs
+		fsys := afero.NewMemMapFs()
+		// Setup mock postgres
+		conn := pgtest.NewConn()
+		defer conn.Close(t)
+		conn.Query("begin").Reply("BEGIN").
+			Query(ENABLE_PGSQL_CHECK).
+			Reply("CREATE EXTENSION").
+			Query(checkSchemaScript, "public").
+			Reply("SELECT 1", []interface{}{"f1", `{"function":"22751","issues":[{"level":"warning","message":"test warning"}]}`}).
+			Query("rollback").Reply("ROLLBACK")
+		// Run test
+		err := Run(context.Background(), []string{"public"}, "warning", "warning", dbConfig, fsys, conn.Intercept)
+		// Check error
+		assert.ErrorContains(t, err, "fail-on is set to warning, non-zero exit")
+	})
+
+	t.Run("exits with non-zero status on error", func(t *testing.T) {
+		// Setup in-memory fs
+		fsys := afero.NewMemMapFs()
+		// Setup mock postgres
+		conn := pgtest.NewConn()
+		defer conn.Close(t)
+		conn.Query("begin").Reply("BEGIN").
+			Query(ENABLE_PGSQL_CHECK).
+			Reply("CREATE EXTENSION").
+			Query(checkSchemaScript, "public").
+			Reply("SELECT 1", []interface{}{"f1", `{"function":"22751","issues":[{"level":"error","message":"test error"}]}`}).
+			Query("rollback").Reply("ROLLBACK")
+		// Run test
+		err := Run(context.Background(), []string{"public"}, "warning", "error", dbConfig, fsys, conn.Intercept)
+		// Check error
+		assert.ErrorContains(t, err, "fail-on is set to error, non-zero exit")
+	})
+
+	t.Run("does not exit with non-zero status when fail-on is none", func(t *testing.T) {
+		// Setup in-memory fs
+		fsys := afero.NewMemMapFs()
+		// Setup mock postgres
+		conn := pgtest.NewConn()
+		defer conn.Close(t)
+		conn.Query("begin").Reply("BEGIN").
+			Query(ENABLE_PGSQL_CHECK).
+			Reply("CREATE EXTENSION").
+			Query(checkSchemaScript, "public").
+			Reply("SELECT 1", []interface{}{"f1", `{"function":"22751","issues":[{"level":"error","message":"test error"}]}`}).
+			Query("rollback").Reply("ROLLBACK")
+		// Run test
+		err := Run(context.Background(), []string{"public"}, "warning", "none", dbConfig, fsys, conn.Intercept)
+		// Check error
+		assert.NoError(t, err)
+	})
 }
diff --git a/internal/db/reset/reset_test.go b/internal/db/reset/reset_test.go
index 38fef4b9..03da968c 100644
--- a/internal/db/reset/reset_test.go
+++ b/internal/db/reset/reset_test.go
@@ -357,6 +357,33 @@ func TestResetRemote(t *testing.T) {
 		assert.NoError(t, err)
 	})
 
+	t.Run("resets remote database with seed config disabled", func(t *testing.T) {
+		// Setup in-memory fs
+		fsys := afero.NewMemMapFs()
+		path := filepath.Join(utils.MigrationsDir, "0_schema.sql")
+		require.NoError(t, afero.WriteFile(fsys, path, nil, 0644))
+		seedPath := filepath.Join(utils.SeedDataPath)
+		// Will raise an error when seeding
+		require.NoError(t, afero.WriteFile(fsys, seedPath, []byte("INSERT INTO test_table;"), 0644))
+		// Setup mock postgres
+		conn := pgtest.NewConn()
+		defer conn.Close(t)
+		conn.Query(migration.ListSchemas, escapedSchemas).
+			Reply("SELECT 1", []interface{}{"private"}).
+			Query("DROP SCHEMA IF EXISTS private CASCADE").
+			Reply("DROP SCHEMA").
+			Query(migration.DropObjects).
+			Reply("INSERT 0")
+		helper.MockMigrationHistory(conn).
+			Query(migration.INSERT_MIGRATION_VERSION, "0", "schema", nil).
+			Reply("INSERT 0 1")
+		utils.Config.Db.Seed.Enabled = false
+		// Run test
+		err := resetRemote(context.Background(), "", dbConfig, fsys, conn.Intercept)
+		// No error should be raised since we're skipping the seed
+		assert.NoError(t, err)
+	})
+
 	t.Run("throws error on connect failure", func(t *testing.T) {
 		// Setup in-memory fs
 		fsys := afero.NewMemMapFs()
diff --git a/internal/migration/apply/apply_test.go b/internal/migration/apply/apply_test.go
index 7150f626..b8c04174 100644
--- a/internal/migration/apply/apply_test.go
+++ b/internal/migration/apply/apply_test.go
@@ -38,6 +38,30 @@ func TestMigrateDatabase(t *testing.T) {
 		assert.NoError(t, err)
 	})
 
+	t.Run("skip seeding when seed config is disabled", func(t *testing.T) {
+		// Setup in-memory fs
+		fsys := afero.NewMemMapFs()
+		path := filepath.Join(utils.MigrationsDir, "0_test.sql")
+		sql := "create schema public"
+		require.NoError(t, afero.WriteFile(fsys, path, []byte(sql), 0644))
+		seedPath := filepath.Join(utils.SeedDataPath)
+		// This will raise an error when seeding
+		require.NoError(t, afero.WriteFile(fsys, seedPath, []byte("INSERT INTO test_table;"), 0644))
+		// Setup mock postgres
+		conn := pgtest.NewConn()
+		defer conn.Close(t)
+		helper.MockMigrationHistory(conn).
+			Query(sql).
+			Reply("CREATE SCHEMA").
+			Query(migration.INSERT_MIGRATION_VERSION, "0", "test", []string{sql}).
+			Reply("INSERT 0 1")
+		utils.Config.Db.Seed.Enabled = false
+		// Run test
+		err := MigrateAndSeed(context.Background(), "", conn.MockClient(t), fsys)
+		// No error should be returned since seeding is skipped
+		assert.NoError(t, err)
+	})
+
 	t.Run("ignores empty local directory", func(t *testing.T) {
 		assert.NoError(t, MigrateAndSeed(context.Background(), "", nil, afero.NewMemMapFs()))
 	})
diff --git a/internal/utils/credentials/keyring_test.go b/internal/utils/credentials/keyring_test.go
new file mode 100644
index 00000000..0569276a
--- /dev/null
+++ b/internal/utils/credentials/keyring_test.go
@@ -0,0 +1,28 @@
+package credentials
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/zalando/go-keyring"
+)
+
+func TestDeleteAll(t *testing.T) {
+	service := "test-cli"
+	// Nothing to delete
+	err := deleteAll(service)
+	assert.NoError(t, err)
+	// Setup 2 items
+	err = keyring.Set(service, "key1", "value")
+	assert.NoError(t, err)
+	err = keyring.Set(service, "key2", "value")
+	assert.NoError(t, err)
+	// Delete all items
+	err = deleteAll(service)
+	assert.NoError(t, err)
+	// Check items are gone
+	_, err = keyring.Get(service, "key1")
+	assert.ErrorIs(t, err, keyring.ErrNotFound)
+	_, err = keyring.Get(service, "key2")
+	assert.ErrorIs(t, err, keyring.ErrNotFound)
+}
diff --git a/test/login_test.go b/test/login_test.go
index 81f9cb89..2f1e018f 100644
--- a/test/login_test.go
+++ b/test/login_test.go
@@ -5,7 +5,6 @@ import (
 	"context"
 	"net/http"
 	"os"
-	"path/filepath"
 	"sync"
 	"testing"
 
@@ -57,13 +56,13 @@ func (suite *LoginTestSuite) TestLink() {
 	require.NoError(suite.T(), login.RunE(login, []string{}))
 
 	// check token is saved
-	home, err := os.UserHomeDir()
-	require.NoError(suite.T(), err)
-	_, err = os.Stat(filepath.Join(home, ".supabase/access-token"))
-	require.NoError(suite.T(), err)
-	token, err := os.ReadFile(filepath.Join(home, ".supabase/access-token"))
-	require.NoError(suite.T(), err)
-	require.Equal(suite.T(), key, string(token))
+	// home, err := os.UserHomeDir()
+	// require.NoError(suite.T(), err)
+	// _, err = os.Stat(filepath.Join(home, ".supabase/access-token"))
+	// require.NoError(suite.T(), err)
+	// token, err := os.ReadFile(filepath.Join(home, ".supabase/access-token"))
+	// require.NoError(suite.T(), err)
+	// require.Equal(suite.T(), key, string(token))
 }
 
 // hooks