From 4f0e7de5965d2091d1372e7bece82ca5e708f680 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 12:27:53 +0800 Subject: [PATCH 01/54] chore(deps): bump golang.org/x/oauth2 from 0.26.0 to 0.27.0 (#3203) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 7d18dd2cd..05d8d25b7 100644 --- a/go.mod +++ b/go.mod @@ -50,7 +50,7 @@ require ( github.com/zalando/go-keyring v0.2.6 go.opentelemetry.io/otel v1.34.0 golang.org/x/mod v0.23.0 - golang.org/x/oauth2 v0.26.0 + golang.org/x/oauth2 v0.27.0 golang.org/x/term v0.29.0 google.golang.org/grpc v1.70.0 gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index e6bcbdda3..f3aff5d69 100644 --- a/go.sum +++ b/go.sum @@ -1214,8 +1214,8 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE= -golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= +golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= From d958f7d7f4ccb19d18650fae5d1b3c1cce530d20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 07:46:31 +0000 Subject: [PATCH 02/54] chore(deps): bump supabase/realtime from v2.34.31 to v2.34.33 in /pkg/config/templates (#3204) chore(deps): bump supabase/realtime in /pkg/config/templates Bumps supabase/realtime from v2.34.31 to v2.34.33. --- updated-dependencies: - dependency-name: supabase/realtime dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Han Qiao --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 124332e82..575671292 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -11,7 +11,7 @@ FROM supabase/edge-runtime:v1.67.2 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.3.9 AS supavisor FROM supabase/gotrue:v2.169.0 AS gotrue -FROM supabase/realtime:v2.34.31 AS realtime +FROM supabase/realtime:v2.34.33 AS realtime FROM supabase/storage-api:v1.19.1 AS storage FROM supabase/logflare:1.11.0 AS logflare # Append to JobImages when adding new dependencies below From 460ee2542670d2bcfd71d9ff8a70209c1a98684f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 07:50:46 +0000 Subject: [PATCH 03/54] chore(deps): bump supabase/supavisor from 2.3.9 to 2.3.10 in /pkg/config/templates (#3205) chore(deps): bump supabase/supavisor in /pkg/config/templates Bumps supabase/supavisor from 2.3.9 to 2.3.10. --- updated-dependencies: - dependency-name: supabase/supavisor dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 575671292..6efa9f6cc 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -9,7 +9,7 @@ FROM supabase/studio:20250224-d10db0f AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy FROM supabase/edge-runtime:v1.67.2 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector -FROM supabase/supavisor:2.3.9 AS supavisor +FROM supabase/supavisor:2.3.10 AS supavisor FROM supabase/gotrue:v2.169.0 AS gotrue FROM supabase/realtime:v2.34.33 AS realtime FROM supabase/storage-api:v1.19.1 AS storage From bff16cc51eeef4cecd477b2e7d64cdfec4d5b47b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 04:23:38 +0000 Subject: [PATCH 04/54] chore(deps): bump supabase/supavisor from 2.3.10 to 2.4.2 in /pkg/config/templates (#3209) chore(deps): bump supabase/supavisor in /pkg/config/templates Bumps supabase/supavisor from 2.3.10 to 2.4.2. --- updated-dependencies: - dependency-name: supabase/supavisor dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 6efa9f6cc..12db74631 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -9,7 +9,7 @@ FROM supabase/studio:20250224-d10db0f AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy FROM supabase/edge-runtime:v1.67.2 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector -FROM supabase/supavisor:2.3.10 AS supavisor +FROM supabase/supavisor:2.4.2 AS supavisor FROM supabase/gotrue:v2.169.0 AS gotrue FROM supabase/realtime:v2.34.33 AS realtime FROM supabase/storage-api:v1.19.1 AS storage From 6ccc4fd006ed1d298de6deabcd6e634cdc0ff568 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 04:27:44 +0000 Subject: [PATCH 05/54] chore(deps): bump supabase/realtime from v2.34.33 to v2.34.34 in /pkg/config/templates (#3210) chore(deps): bump supabase/realtime in /pkg/config/templates Bumps supabase/realtime from v2.34.33 to v2.34.34. --- updated-dependencies: - dependency-name: supabase/realtime dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 12db74631..0ebd669c8 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -11,7 +11,7 @@ FROM supabase/edge-runtime:v1.67.2 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.4.2 AS supavisor FROM supabase/gotrue:v2.169.0 AS gotrue -FROM supabase/realtime:v2.34.33 AS realtime +FROM supabase/realtime:v2.34.34 AS realtime FROM supabase/storage-api:v1.19.1 AS storage FROM supabase/logflare:1.11.0 AS logflare # Append to JobImages when adding new dependencies below From a1aab111d715634e1e1a5f3bec7fd874e98dc3ce Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Wed, 26 Feb 2025 14:31:35 +0800 Subject: [PATCH 06/54] fix: append config.toml when creating new function (#3212) * fix: append config.toml when creating new function * chore: update unit tests * chore: remove unnecessary comments from config template --- internal/functions/new/new.go | 89 ++++++++++++-------- internal/functions/new/new_test.go | 4 + internal/functions/new/templates/config.toml | 11 +++ pkg/config/templates/config.toml | 12 --- 4 files changed, 68 insertions(+), 48 deletions(-) create mode 100644 internal/functions/new/templates/config.toml diff --git a/internal/functions/new/new.go b/internal/functions/new/new.go index 67a9893e2..f41097cfd 100644 --- a/internal/functions/new/new.go +++ b/internal/functions/new/new.go @@ -21,8 +21,11 @@ var ( denoEmbed string //go:embed templates/.npmrc npmrcEmbed string + //go:embed templates/config.toml + configEmbed string - indexTemplate = template.Must(template.New("index").Parse(indexEmbed)) + indexTemplate = template.Must(template.New("index").Parse(indexEmbed)) + configTemplate = template.Must(template.New("config").Parse(configEmbed)) ) type indexConfig struct { @@ -32,49 +35,63 @@ type indexConfig struct { func Run(ctx context.Context, slug string, fsys afero.Fs) error { // 1. Sanity checks. - funcDir := filepath.Join(utils.FunctionsDir, slug) - { - if err := utils.ValidateFunctionSlug(slug); err != nil { - return err - } + if err := utils.ValidateFunctionSlug(slug); err != nil { + return err } - // 2. Create new function. - { - if err := utils.MkdirIfNotExistFS(fsys, funcDir); err != nil { - return err - } - - // Load config if available - if err := flags.LoadConfig(fsys); err != nil { - utils.CmdSuggestion = "" - } - - if err := createTemplateFile(fsys, filepath.Join(funcDir, "index.ts"), indexTemplate, indexConfig{ - URL: utils.GetApiUrl("/functions/v1/" + slug), - Token: utils.Config.Auth.AnonKey, - }); err != nil { - return errors.Errorf("failed to create function entrypoint: %w", err) - } - - if err := afero.WriteFile(fsys, filepath.Join(funcDir, "deno.json"), []byte(denoEmbed), 0644); err != nil { - return errors.Errorf("failed to create deno.json config: %w", err) - } - - if err := afero.WriteFile(fsys, filepath.Join(funcDir, ".npmrc"), []byte(npmrcEmbed), 0644); err != nil { - return errors.Errorf("failed to create .npmrc config: %w", err) - } + funcDir := filepath.Join(utils.FunctionsDir, slug) + if err := utils.MkdirIfNotExistFS(fsys, funcDir); err != nil { + return err + } + // Load config if available + if err := flags.LoadConfig(fsys); err != nil { + utils.CmdSuggestion = "" + } + if err := createEntrypointFile(slug, fsys); err != nil { + return err + } + if err := appendConfigFile(slug, fsys); err != nil { + return err + } + // 3. Create optional files + if err := afero.WriteFile(fsys, filepath.Join(funcDir, "deno.json"), []byte(denoEmbed), 0644); err != nil { + return errors.Errorf("failed to create deno.json config: %w", err) + } + if err := afero.WriteFile(fsys, filepath.Join(funcDir, ".npmrc"), []byte(npmrcEmbed), 0644); err != nil { + return errors.Errorf("failed to create .npmrc config: %w", err) } - fmt.Println("Created new Function at " + utils.Bold(funcDir)) return nil } -func createTemplateFile(fsys afero.Fs, path string, tmpl *template.Template, data interface{}) error { - f, err := fsys.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644) +func createEntrypointFile(slug string, fsys afero.Fs) error { + entrypointPath := filepath.Join(utils.FunctionsDir, slug, "index.ts") + f, err := fsys.OpenFile(entrypointPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644) if err != nil { - return err + return errors.Errorf("failed to create entrypoint: %w", err) + } + defer f.Close() + if err := indexTemplate.Option("missingkey=error").Execute(f, indexConfig{ + URL: utils.GetApiUrl("/functions/v1/" + slug), + Token: utils.Config.Auth.AnonKey, + }); err != nil { + return errors.Errorf("failed to write entrypoint: %w", err) + } + return nil +} + +func appendConfigFile(slug string, fsys afero.Fs) error { + if _, exists := utils.Config.Functions[slug]; exists { + fmt.Fprintf(os.Stderr, "[functions.%s] is already declared in %s\n", slug, utils.Bold(utils.ConfigPath)) + return nil + } + f, err := fsys.OpenFile(utils.ConfigPath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) + if err != nil { + return errors.Errorf("failed to append config: %w", err) } defer f.Close() - return tmpl.Option("missingkey=error").Execute(f, data) + if err := configTemplate.Option("missingkey=error").Execute(f, slug); err != nil { + return errors.Errorf("failed to append template: %w", err) + } + return nil } diff --git a/internal/functions/new/new_test.go b/internal/functions/new/new_test.go index 8e00fa656..df082d0d0 100644 --- a/internal/functions/new/new_test.go +++ b/internal/functions/new/new_test.go @@ -25,6 +25,10 @@ func TestNewCommand(t *testing.T) { "curl -i --location --request POST 'http://127.0.0.1:54321/functions/v1/test-func'", ) + // Verify config.toml is updated + _, err = afero.ReadFile(fsys, utils.ConfigPath) + assert.NoError(t, err, "config.toml should be created") + // Verify deno.json exists denoPath := filepath.Join(utils.FunctionsDir, "test-func", "deno.json") _, err = afero.ReadFile(fsys, denoPath) diff --git a/internal/functions/new/templates/config.toml b/internal/functions/new/templates/config.toml new file mode 100644 index 000000000..9b3b19709 --- /dev/null +++ b/internal/functions/new/templates/config.toml @@ -0,0 +1,11 @@ + +[functions.{{ . }}] +enabled = true +verify_jwt = true +import_map = "./functions/{{ . }}/deno.json" +# Uncomment to specify a custom file path to the entrypoint. +# Supported file extensions are: .ts, .js, .mjs, .jsx, .tsx +entrypoint = "./functions/{{ . }}/index.ts" +# Specifies static files to be bundled with the function. Supports glob patterns. +# For example, if you want to serve static HTML pages in your function: +# static_files = [ "./functions/{{ . }}/*.html" ] diff --git a/pkg/config/templates/config.toml b/pkg/config/templates/config.toml index 842be7128..8e84899a2 100644 --- a/pkg/config/templates/config.toml +++ b/pkg/config/templates/config.toml @@ -263,18 +263,6 @@ policy = "oneshot" # Port to attach the Chrome inspector for debugging edge functions. inspector_port = 8083 -# Use these configurations to customize your Edge Function. -# [functions.MY_FUNCTION_NAME] -# enabled = true -# verify_jwt = true -# import_map = "./functions/MY_FUNCTION_NAME/deno.json" -# Uncomment to specify a custom file path to the entrypoint. -# Supported file extensions are: .ts, .js, .mjs, .jsx, .tsx -# entrypoint = "./functions/MY_FUNCTION_NAME/index.ts" -# Specifies static files to be bundled with the function. Supports glob patterns. -# For example, if you want to serve static HTML pages in your function: -# static_files = [ "./functions/MY_FUNCTION_NAME/*.html" ] - [analytics] enabled = true port = 54327 From 6e53df93e21000351b6ca1dc8d01c681e2565379 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Feb 2025 04:58:31 +0000 Subject: [PATCH 07/54] chore(deps): bump supabase/postgres from 15.8.1.044 to 15.8.1.045 in /pkg/config/templates (#3219) chore(deps): bump supabase/postgres in /pkg/config/templates Bumps supabase/postgres from 15.8.1.044 to 15.8.1.045. --- updated-dependencies: - dependency-name: supabase/postgres dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 0ebd669c8..d8f04db3b 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -1,5 +1,5 @@ # Exposed for updates by .github/dependabot.yml -FROM supabase/postgres:15.8.1.044 AS pg15 +FROM supabase/postgres:15.8.1.045 AS pg15 # Append to ServiceImages when adding new dependencies below FROM library/kong:2.8.1 AS kong FROM inbucket/inbucket:3.0.3 AS inbucket From 55907360cc1235d0813796c08832e09c68d98fb8 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Thu, 27 Feb 2025 17:50:27 +0800 Subject: [PATCH 08/54] fix: output standard env vars from branches get --- internal/branches/get/get.go | 110 +++++++++++++++++++------- internal/projects/apiKeys/api_keys.go | 5 +- internal/utils/connect.go | 23 ++++-- 3 files changed, 98 insertions(+), 40 deletions(-) diff --git a/internal/branches/get/get.go b/internal/branches/get/get.go index 387e4ab79..23967acfc 100644 --- a/internal/branches/get/get.go +++ b/internal/branches/get/get.go @@ -4,24 +4,61 @@ import ( "context" "fmt" "os" + "strings" "github.com/go-errors/errors" "github.com/jackc/pgconn" "github.com/spf13/afero" "github.com/supabase/cli/internal/migration/list" + "github.com/supabase/cli/internal/projects/apiKeys" "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/pkg/api" "github.com/supabase/cli/pkg/cast" ) func Run(ctx context.Context, branchId string, fsys afero.Fs) error { - resp, err := utils.GetSupabase().V1GetABranchConfigWithResponse(ctx, branchId) + detail, err := getBranchDetail(ctx, branchId) if err != nil { - return errors.Errorf("failed to retrieve preview branch: %w", err) + return err } - if resp.JSON200 == nil { - return errors.New("Unexpected error retrieving preview branch: " + string(resp.Body)) + + if utils.OutputFormat.Value != utils.OutputPretty { + keys, err := apiKeys.RunGetApiKeys(ctx, detail.Ref) + if err != nil { + return err + } + pooler, err := getPoolerConfig(ctx, detail.Ref) + if err != nil { + return err + } + envs := toStandardEnvs(detail, pooler, keys) + return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, envs) } + table := `|HOST|PORT|USER|PASSWORD|JWT SECRET|POSTGRES VERSION|STATUS| +|-|-|-|-|-|-|-| +` + fmt.Sprintf( + "|`%s`|`%d`|`%s`|`%s`|`%s`|`%s`|`%s`|\n", + detail.DbHost, + detail.DbPort, + *detail.DbUser, + *detail.DbPass, + *detail.JwtSecret, + detail.PostgresVersion, + detail.Status, + ) + + return list.RenderTable(table) +} + +func getBranchDetail(ctx context.Context, branchId string) (api.BranchDetailResponse, error) { + var result api.BranchDetailResponse + resp, err := utils.GetSupabase().V1GetABranchConfigWithResponse(ctx, branchId) + if err != nil { + return result, errors.Errorf("failed to get branch: %w", err) + } else if resp.JSON200 == nil { + return result, errors.Errorf("unexpected get branch status %d: %s", resp.StatusCode(), string(resp.Body)) + } masked := "******" if resp.JSON200.DbUser == nil { resp.JSON200.DbUser = &masked @@ -32,35 +69,48 @@ func Run(ctx context.Context, branchId string, fsys afero.Fs) error { if resp.JSON200.JwtSecret == nil { resp.JSON200.JwtSecret = &masked } + return *resp.JSON200, nil +} - config := pgconn.Config{ - Host: resp.JSON200.DbHost, - Port: cast.UIntToUInt16(cast.IntToUint(resp.JSON200.DbPort)), - User: *resp.JSON200.DbUser, - Password: *resp.JSON200.DbPass, +func getPoolerConfig(ctx context.Context, ref string) (api.SupavisorConfigResponse, error) { + var result api.SupavisorConfigResponse + resp, err := utils.GetSupabase().V1GetSupavisorConfigWithResponse(ctx, ref) + if err != nil { + return result, errors.Errorf("failed to get pooler: %w", err) + } else if resp.JSON200 == nil { + return result, errors.Errorf("unexpected get pooler status %d: %s", resp.StatusCode(), string(resp.Body)) } - - postgresConnectionString := utils.ToPostgresURL(config) - if utils.OutputFormat.Value != utils.OutputPretty { - envs := map[string]string{ - "POSTGRES_URL": postgresConnectionString, + for _, config := range *resp.JSON200 { + if config.DatabaseType == api.PRIMARY { + return config, nil } - return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, envs) } + return result, errors.Errorf("primary database not found: %s", ref) +} - table := `|HOST|PORT|USER|PASSWORD|JWT SECRET|POSTGRES VERSION|STATUS|POSTGRES URL| -|-|-|-|-|-|-|-|-| -` + fmt.Sprintf( - "|`%s`|`%d`|`%s`|`%s`|`%s`|`%s`|`%s`|`%s`|\n", - resp.JSON200.DbHost, - resp.JSON200.DbPort, - *resp.JSON200.DbUser, - *resp.JSON200.DbPass, - *resp.JSON200.JwtSecret, - resp.JSON200.PostgresVersion, - resp.JSON200.Status, - postgresConnectionString, - ) - - return list.RenderTable(table) +func toStandardEnvs(detail api.BranchDetailResponse, pooler api.SupavisorConfigResponse, keys []api.ApiKeyResponse) map[string]string { + direct := pgconn.Config{ + Host: detail.DbHost, + Port: cast.UIntToUInt16(cast.IntToUint(detail.DbPort)), + User: *detail.DbUser, + Password: *detail.DbPass, + } + config, err := utils.ParsePoolerURL(pooler.ConnectionString) + if err != nil { + fmt.Fprintln(os.Stderr, utils.Yellow("WARNING:"), err) + config = &direct + } else { + config.Password = direct.Password + } + envs := map[string]string{ + "POSTGRES_URL": utils.ToPostgresURL(*config), + "POSTGRES_URL_NON_POOLING": utils.ToPostgresURL(direct), + "SUPABASE_URL": "https://" + utils.GetSupabaseHost(detail.Ref), + } + for _, entry := range keys { + name := strings.ToUpper(entry.Name) + key := fmt.Sprintf("SUPABASE_%s_KEY", name) + envs[key] = entry.ApiKey + } + return envs } diff --git a/internal/projects/apiKeys/api_keys.go b/internal/projects/apiKeys/api_keys.go index 7daddce21..8d26d540d 100644 --- a/internal/projects/apiKeys/api_keys.go +++ b/internal/projects/apiKeys/api_keys.go @@ -37,9 +37,8 @@ func RunGetApiKeys(ctx context.Context, projectRef string) ([]api.ApiKeyResponse resp, err := utils.GetSupabase().V1GetProjectApiKeysWithResponse(ctx, projectRef, &api.V1GetProjectApiKeysParams{}) if err != nil { return nil, errors.Errorf("failed to get api keys: %w", err) - } - if resp.JSON200 == nil { - return nil, errors.New("Unexpected error retrieving project api-keys: " + string(resp.Body)) + } else if resp.JSON200 == nil { + return nil, errors.Errorf("unexpected get api keys status %d: %s", resp.StatusCode(), string(resp.Body)) } return *resp.JSON200, nil } diff --git a/internal/utils/connect.go b/internal/utils/connect.go index 9479d4e4f..c7c4124e5 100644 --- a/internal/utils/connect.go +++ b/internal/utils/connect.go @@ -10,6 +10,7 @@ import ( "strings" "time" + "github.com/go-errors/errors" "github.com/jackc/pgconn" "github.com/jackc/pgx/v4" "github.com/spf13/viper" @@ -47,13 +48,9 @@ func GetPoolerConfig(projectRef string) *pgconn.Config { fmt.Fprintln(logger, "Pooler URL is not configured") return nil } - // Remove password from pooler connection string because the placeholder text - // [YOUR-PASSWORD] messes up pgconn.ParseConfig. The password must be percent - // escaped so we cannot simply call strings.Replace with actual password. - poolerUrl := strings.ReplaceAll(Config.Db.Pooler.ConnectionString, "[YOUR-PASSWORD]", "") - poolerConfig, err := pgconn.ParseConfig(poolerUrl) + poolerConfig, err := ParsePoolerURL(Config.Db.Pooler.ConnectionString) if err != nil { - fmt.Fprintln(logger, "Failed to parse pooler URL:", poolerUrl) + fmt.Fprintln(logger, err) return nil } if poolerConfig.RuntimeParams == nil { @@ -77,12 +74,24 @@ func GetPoolerConfig(projectRef string) *pgconn.Config { fmt.Fprintln(logger, "Pooler hostname does not belong to Supabase domain:", poolerConfig.Host) return nil } - fmt.Fprintln(logger, "Using connection pooler:", poolerUrl) + fmt.Fprintln(logger, "Using connection pooler:", Config.Db.Pooler.ConnectionString) // Supavisor transaction mode does not support prepared statement poolerConfig.Port = 5432 return poolerConfig } +func ParsePoolerURL(connString string) (*pgconn.Config, error) { + // Remove password from pooler connection string because the placeholder text + // [YOUR-PASSWORD] messes up pgconn.ParseConfig. The password must be percent + // escaped so we cannot simply call strings.Replace with actual password. + poolerUrl := strings.ReplaceAll(connString, "[YOUR-PASSWORD]", "") + poolerConfig, err := pgconn.ParseConfig(poolerUrl) + if err != nil { + return nil, errors.Errorf("failed to parse pooler URL: %w", err) + } + return poolerConfig, nil +} + func isSupabaseDomain(host string) bool { switch GetSupabaseAPIHost() { case "https://api.supabase.green": From 34e02d58e1272a61091ab49e028ad3c68354dddc Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Thu, 27 Feb 2025 17:54:21 +0800 Subject: [PATCH 09/54] fix: filters should break to outer loop --- pkg/function/batch.go | 3 ++- pkg/migration/list.go | 6 ++++-- pkg/storage/batch.go | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/pkg/function/batch.go b/pkg/function/batch.go index 739d8f84d..e5400efbc 100644 --- a/pkg/function/batch.go +++ b/pkg/function/batch.go @@ -34,6 +34,7 @@ func (s *EdgeRuntimeAPI) UpsertFunctions(ctx context.Context, functionConfig con for _, f := range result { exists[f.Slug] = struct{}{} } +OUTER: for slug, function := range functionConfig { if !function.Enabled { fmt.Fprintln(os.Stderr, "Skipped deploying Function:", slug) @@ -41,7 +42,7 @@ func (s *EdgeRuntimeAPI) UpsertFunctions(ctx context.Context, functionConfig con } for _, keep := range filter { if !keep(slug) { - continue + continue OUTER } } var body bytes.Buffer diff --git a/pkg/migration/list.go b/pkg/migration/list.go index ec8bf2ac8..af76430df 100644 --- a/pkg/migration/list.go +++ b/pkg/migration/list.go @@ -39,6 +39,7 @@ func ListLocalMigrations(migrationsDir string, fsys fs.FS, filter ...func(string filter = append(filter, func(string) bool { return true }) } var clean []string +OUTER: for i, migration := range localMigrations { filename := migration.Name() if i == 0 && shouldSkip(filename) { @@ -52,10 +53,11 @@ func ListLocalMigrations(migrationsDir string, fsys fs.FS, filter ...func(string } path := filepath.Join(migrationsDir, filename) for _, keep := range filter { - if version := matches[1]; keep(version) { - clean = append(clean, path) + if version := matches[1]; !keep(version) { + continue OUTER } } + clean = append(clean, path) } return clean, nil } diff --git a/pkg/storage/batch.go b/pkg/storage/batch.go index 63638e9a9..2e62774e1 100644 --- a/pkg/storage/batch.go +++ b/pkg/storage/batch.go @@ -22,12 +22,13 @@ func (s *StorageAPI) UpsertBuckets(ctx context.Context, bucketConfig config.Buck for _, b := range buckets { exists[b.Name] = b.Id } +OUTER: for name, bucket := range bucketConfig { // Update bucket properties if already exists if bucketId, ok := exists[name]; ok { for _, keep := range filter { if !keep(bucketId) { - continue + continue OUTER } } fmt.Fprintln(os.Stderr, "Updating Storage bucket:", bucketId) From e7e1126fd4056898b011c8e13dcd90677b8faab1 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Thu, 27 Feb 2025 17:58:46 +0800 Subject: [PATCH 10/54] chore: update unit tests --- internal/projects/apiKeys/api_keys_test.go | 36 ++++++++++++---------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/internal/projects/apiKeys/api_keys_test.go b/internal/projects/apiKeys/api_keys_test.go index 57130f158..48730a0a7 100644 --- a/internal/projects/apiKeys/api_keys_test.go +++ b/internal/projects/apiKeys/api_keys_test.go @@ -3,6 +3,7 @@ package apiKeys import ( "context" "errors" + "net/http" "testing" "github.com/h2non/gock" @@ -14,14 +15,15 @@ import ( ) func TestProjectApiKeysCommand(t *testing.T) { + // Setup valid project ref + project := apitest.RandomProjectRef() + // Setup valid access token + token := apitest.RandomAccessToken(t) + t.Setenv("SUPABASE_ACCESS_TOKEN", string(token)) + t.Run("lists all api-keys", func(t *testing.T) { // Setup in-memory fs fsys := afero.NewMemMapFs() - // Setup valid project ref - project := apitest.RandomProjectRef() - // Setup valid access token - token := apitest.RandomAccessToken(t) - t.Setenv("SUPABASE_ACCESS_TOKEN", string(token)) // Flush pending mocks after test execution defer gock.OffAll() gock.New(utils.DefaultApiHost). @@ -38,32 +40,32 @@ func TestProjectApiKeysCommand(t *testing.T) { assert.Empty(t, apitest.ListUnmatchedRequests()) }) - t.Run("throws error on missing access token", func(t *testing.T) { + t.Run("throws error on network error", func(t *testing.T) { // Setup in-memory fs fsys := afero.NewMemMapFs() + // Flush pending mocks after test execution + defer gock.OffAll() + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + project + "/api-keys"). + ReplyError(errors.New("network error")) // Run test - err := Run(context.Background(), "", fsys) + err := Run(context.Background(), project, fsys) // Check error - assert.ErrorContains(t, err, "Unexpected error retrieving project api-keys") + assert.ErrorContains(t, err, "network error") + assert.Empty(t, apitest.ListUnmatchedRequests()) }) - t.Run("throws error on network error", func(t *testing.T) { + t.Run("throws error on service unavailable", func(t *testing.T) { // Setup in-memory fs fsys := afero.NewMemMapFs() - // Setup valid project ref - project := apitest.RandomProjectRef() - // Setup valid access token - token := apitest.RandomAccessToken(t) - t.Setenv("SUPABASE_ACCESS_TOKEN", string(token)) // Flush pending mocks after test execution defer gock.OffAll() gock.New(utils.DefaultApiHost). Get("/v1/projects/" + project + "/api-keys"). - ReplyError(errors.New("network error")) + Reply(http.StatusServiceUnavailable) // Run test err := Run(context.Background(), project, fsys) // Check error - assert.ErrorContains(t, err, "network error") - assert.Empty(t, apitest.ListUnmatchedRequests()) + assert.ErrorContains(t, err, "unexpected get api keys status 503:") }) } From aacc914a6a53a2b7c0efbb30c0a0b20e9fb6e285 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Thu, 27 Feb 2025 18:14:37 +0800 Subject: [PATCH 11/54] fix: accept both branch ID and name --- cmd/branches.go | 93 ++++++++++++++++------------------ internal/branches/list/list.go | 39 +++++++++++--- 2 files changed, 76 insertions(+), 56 deletions(-) diff --git a/cmd/branches.go b/cmd/branches.go index b541704bf..d9d2513c9 100644 --- a/cmd/branches.go +++ b/cmd/branches.go @@ -6,6 +6,7 @@ import ( "os" "github.com/go-errors/errors" + "github.com/google/uuid" "github.com/spf13/afero" "github.com/spf13/cobra" "github.com/supabase/cli/internal/branches/create" @@ -75,14 +76,11 @@ var ( Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() - if len(args) == 0 { - if err := promptBranchId(ctx, flags.ProjectRef); err != nil { - return err - } - } else { - branchId = args[0] + fsys := afero.NewOsFs() + if err := promptBranchId(ctx, args, fsys); err != nil { + return err } - return get.Run(ctx, branchId, afero.NewOsFs()) + return get.Run(ctx, branchId, fsys) }, } @@ -101,7 +99,7 @@ var ( branchUpdateCmd = &cobra.Command{ Use: "update [branch-id]", Short: "Update a preview branch", - Long: "Update a preview branch by its ID.", + Long: "Update a preview branch by its name or ID.", Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { cmdFlags := cmd.Flags() @@ -119,30 +117,24 @@ var ( body.Status = (*api.UpdateBranchBodyStatus)(&branchStatus.Value) } ctx := cmd.Context() - if len(args) == 0 { - if err := promptBranchId(ctx, flags.ProjectRef); err != nil { - return err - } - } else { - branchId = args[0] + fsys := afero.NewOsFs() + if err := promptBranchId(ctx, args, fsys); err != nil { + return err } - return update.Run(cmd.Context(), branchId, body, afero.NewOsFs()) + return update.Run(cmd.Context(), branchId, body, fsys) }, } branchDeleteCmd = &cobra.Command{ Use: "delete [branch-id]", Short: "Delete a preview branch", - Long: "Delete a preview branch by its ID.", + Long: "Delete a preview branch by its name or ID.", Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() - if len(args) == 0 { - if err := promptBranchId(ctx, flags.ProjectRef); err != nil { - return err - } - } else { - branchId = args[0] + fsys := afero.NewOsFs() + if err := promptBranchId(ctx, args, fsys); err != nil { + return err } return delete.Run(ctx, branchId) }, @@ -181,40 +173,43 @@ func init() { rootCmd.AddCommand(branchesCmd) } -func promptBranchId(ctx context.Context, ref string) error { - resp, err := utils.GetSupabase().V1ListAllBranchesWithResponse(ctx, ref) - if err != nil { - return errors.Errorf("failed to list preview branches: %w", err) - } - if resp.JSON200 == nil { - return errors.New("Unexpected error listing preview branches: " + string(resp.Body)) - } - console := utils.NewConsole() - if !console.IsTTY { - // Fallback to current git branch on GHA - gitBranch := keys.GetGitBranch(afero.NewOsFs()) - title := "Enter the name of your branch: " - if len(gitBranch) > 0 { - title = fmt.Sprintf("%-2s (or leave blank to use %s): ", title, utils.Aqua(gitBranch)) +func promptBranchId(ctx context.Context, args []string, fsys afero.Fs) error { + var filter []list.BranchFilter + if len(args) > 0 { + if branchId = args[0]; uuid.Validate(branchId) == nil { + return nil + } + // Try resolving as branch name + filter = append(filter, list.FilterByName(branchId)) + } else if console := utils.NewConsole(); !console.IsTTY { + // Only read from stdin if the terminal is non-interactive + title := "Enter the name of your branch" + if branchId = keys.GetGitBranch(fsys); len(branchId) > 0 { + title += fmt.Sprintf(" (or leave blank to use %s)", utils.Aqua(branchId)) } + title += ": " if name, err := console.PromptText(ctx, title); err != nil { return err } else if len(name) > 0 { - gitBranch = name + branchId = name } - if len(gitBranch) == 0 { - return errors.New("git branch cannot be empty") + if len(branchId) == 0 { + return errors.New("branch name cannot be empty") } - for _, branch := range *resp.JSON200 { - if branch.Name == gitBranch { - branchId = branch.Id - return nil - } - } - return errors.Errorf("Branch not found: %s", gitBranch) + filter = append(filter, list.FilterByName(branchId)) + } + branches, err := list.ListBranch(ctx, flags.ProjectRef, filter...) + if err != nil { + return err + } else if len(branches) == 0 { + return errors.Errorf("branch not found: %s", branchId) + } else if len(branches) == 1 { + branchId = branches[0].Id + return nil } - items := make([]utils.PromptItem, len(*resp.JSON200)) - for i, branch := range *resp.JSON200 { + // Let user choose from a list of branches + items := make([]utils.PromptItem, len(branches)) + for i, branch := range branches { items[i] = utils.PromptItem{ Summary: branch.Name, Details: branch.Id, diff --git a/internal/branches/list/list.go b/internal/branches/list/list.go index 79eb75e2a..fd40da97c 100644 --- a/internal/branches/list/list.go +++ b/internal/branches/list/list.go @@ -10,22 +10,19 @@ import ( "github.com/supabase/cli/internal/migration/list" "github.com/supabase/cli/internal/utils" "github.com/supabase/cli/internal/utils/flags" + "github.com/supabase/cli/pkg/api" ) func Run(ctx context.Context, fsys afero.Fs) error { - resp, err := utils.GetSupabase().V1ListAllBranchesWithResponse(ctx, flags.ProjectRef) + branches, err := ListBranch(ctx, flags.ProjectRef) if err != nil { - return errors.Errorf("failed to list preview branches: %w", err) - } - - if resp.JSON200 == nil { - return errors.New("Unexpected error listing preview branches: " + string(resp.Body)) + return err } table := `|ID|NAME|DEFAULT|GIT BRANCH|STATUS|CREATED AT (UTC)|UPDATED AT (UTC)| |-|-|-|-|-|-|-| ` - for _, branch := range *resp.JSON200 { + for _, branch := range branches { gitBranch := " " if branch.GitBranch != nil { gitBranch = *branch.GitBranch @@ -44,3 +41,31 @@ func Run(ctx context.Context, fsys afero.Fs) error { return list.RenderTable(table) } + +type BranchFilter func(api.BranchResponse) bool + +func ListBranch(ctx context.Context, ref string, filter ...BranchFilter) ([]api.BranchResponse, error) { + resp, err := utils.GetSupabase().V1ListAllBranchesWithResponse(ctx, ref) + if err != nil { + return nil, errors.Errorf("failed to list branch: %w", err) + } else if resp.JSON200 == nil { + return nil, errors.Errorf("unexpected list branch status %d: %s", resp.StatusCode(), string(resp.Body)) + } + var result []api.BranchResponse +OUTER: + for _, branch := range *resp.JSON200 { + for _, keep := range filter { + if !keep(branch) { + continue OUTER + } + } + result = append(result, branch) + } + return result, nil +} + +func FilterByName(branchName string) BranchFilter { + return func(br api.BranchResponse) bool { + return br.Name == branchName + } +} From 277f377adcb88e3b6c29c4197700064ba2ca4efb Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Thu, 27 Feb 2025 20:39:42 +0800 Subject: [PATCH 12/54] fix: support env output by default --- cmd/branches.go | 2 -- cmd/status.go | 7 +------ internal/branches/get/get.go | 15 ++++----------- internal/projects/apiKeys/api_keys.go | 15 ++++++++++++++- internal/projects/create/create.go | 3 ++- internal/projects/list/list.go | 7 +++++-- internal/sso/create/create.go | 3 ++- internal/sso/get/get.go | 4 ++-- internal/sso/info/info.go | 3 +-- internal/sso/remove/remove.go | 3 ++- internal/sso/update/update.go | 3 ++- internal/utils/output.go | 15 ++++++--------- 12 files changed, 41 insertions(+), 39 deletions(-) diff --git a/cmd/branches.go b/cmd/branches.go index d9d2513c9..1c093278b 100644 --- a/cmd/branches.go +++ b/cmd/branches.go @@ -157,8 +157,6 @@ func init() { createFlags.Var(&branchRegion, "region", "Select a region to deploy the branch database.") createFlags.Var(&size, "size", "Select a desired instance size for the branch database.") createFlags.BoolVar(&persistent, "persistent", false, "Whether to create a persistent branch.") - getFlags := branchGetCmd.Flags() - getFlags.VarP(&utils.OutputFormat, "output", "o", "Output format of branch details.") branchesCmd.AddCommand(branchCreateCmd) branchesCmd.AddCommand(branchListCmd) branchesCmd.AddCommand(branchGetCmd) diff --git a/cmd/status.go b/cmd/status.go index 13540bfb1..11b774854 100644 --- a/cmd/status.go +++ b/cmd/status.go @@ -14,10 +14,6 @@ import ( var ( override []string names status.CustomName - output = utils.EnumFlag{ - Allowed: append([]string{utils.OutputEnv}, utils.OutputDefaultAllowed...), - Value: utils.OutputPretty, - } statusCmd = &cobra.Command{ GroupID: groupLocalDev, @@ -32,7 +28,7 @@ var ( }, RunE: func(cmd *cobra.Command, args []string) error { ctx, _ := signal.NotifyContext(cmd.Context(), os.Interrupt) - return status.Run(ctx, names, output.Value, afero.NewOsFs()) + return status.Run(ctx, names, utils.OutputFormat.Value, afero.NewOsFs()) }, Example: ` supabase status -o env --override-name api.url=NEXT_PUBLIC_SUPABASE_URL supabase status -o json`, @@ -41,7 +37,6 @@ var ( func init() { flags := statusCmd.Flags() - flags.VarP(&output, "output", "o", "Output format of status variables.") flags.StringSliceVar(&override, "override-name", []string{}, "Override specific variable names.") rootCmd.AddCommand(statusCmd) } diff --git a/internal/branches/get/get.go b/internal/branches/get/get.go index 23967acfc..eebd8b4c2 100644 --- a/internal/branches/get/get.go +++ b/internal/branches/get/get.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "os" - "strings" "github.com/go-errors/errors" "github.com/jackc/pgconn" @@ -102,15 +101,9 @@ func toStandardEnvs(detail api.BranchDetailResponse, pooler api.SupavisorConfigR } else { config.Password = direct.Password } - envs := map[string]string{ - "POSTGRES_URL": utils.ToPostgresURL(*config), - "POSTGRES_URL_NON_POOLING": utils.ToPostgresURL(direct), - "SUPABASE_URL": "https://" + utils.GetSupabaseHost(detail.Ref), - } - for _, entry := range keys { - name := strings.ToUpper(entry.Name) - key := fmt.Sprintf("SUPABASE_%s_KEY", name) - envs[key] = entry.ApiKey - } + envs := apiKeys.ToEnv(keys) + envs["POSTGRES_URL"] = utils.ToPostgresURL(*config) + envs["POSTGRES_URL_NON_POOLING"] = utils.ToPostgresURL(direct) + envs["SUPABASE_URL"] = "https://" + utils.GetSupabaseHost(detail.Ref) return envs } diff --git a/internal/projects/apiKeys/api_keys.go b/internal/projects/apiKeys/api_keys.go index 8d26d540d..5d5af351c 100644 --- a/internal/projects/apiKeys/api_keys.go +++ b/internal/projects/apiKeys/api_keys.go @@ -19,7 +19,8 @@ func Run(ctx context.Context, projectRef string, fsys afero.Fs) error { return err } - if utils.OutputFormat.Value == utils.OutputPretty { + switch utils.OutputFormat.Value { + case utils.OutputPretty: table := `|NAME|KEY VALUE| |-|-| ` @@ -28,6 +29,8 @@ func Run(ctx context.Context, projectRef string, fsys afero.Fs) error { } return list.RenderTable(table) + case utils.OutputToml, utils.OutputEnv: + return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, ToEnv(keys)) } return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, keys) @@ -42,3 +45,13 @@ func RunGetApiKeys(ctx context.Context, projectRef string) ([]api.ApiKeyResponse } return *resp.JSON200, nil } + +func ToEnv(keys []api.ApiKeyResponse) map[string]string { + envs := make(map[string]string, len(keys)) + for _, entry := range keys { + name := strings.ToUpper(entry.Name) + key := fmt.Sprintf("SUPABASE_%s_KEY", name) + envs[key] = entry.ApiKey + } + return envs +} diff --git a/internal/projects/create/create.go b/internal/projects/create/create.go index ddbd46b47..bfd461769 100644 --- a/internal/projects/create/create.go +++ b/internal/projects/create/create.go @@ -36,7 +36,8 @@ func Run(ctx context.Context, params api.V1CreateProjectBodyDto, fsys afero.Fs) projectUrl := fmt.Sprintf("%s/project/%s", utils.GetSupabaseDashboardURL(), resp.JSON201.Id) fmt.Fprintf(os.Stderr, "Created a new project %s at %s\n", utils.Aqua(resp.JSON201.Name), utils.Bold(projectUrl)) - if utils.OutputFormat.Value == utils.OutputPretty { + switch utils.OutputFormat.Value { + case utils.OutputPretty, utils.OutputEnv: return nil } diff --git a/internal/projects/list/list.go b/internal/projects/list/list.go index ef356dfcf..babded41d 100644 --- a/internal/projects/list/list.go +++ b/internal/projects/list/list.go @@ -41,7 +41,8 @@ func Run(ctx context.Context, fsys afero.Fs) error { }) } - if utils.OutputFormat.Value == utils.OutputPretty { + switch utils.OutputFormat.Value { + case utils.OutputPretty: table := `LINKED|ORG ID|REFERENCE ID|NAME|REGION|CREATED AT (UTC) |-|-|-|-|-|-| ` @@ -57,12 +58,14 @@ func Run(ctx context.Context, fsys afero.Fs) error { ) } return list.RenderTable(table) - } else if utils.OutputFormat.Value == utils.OutputToml { + case utils.OutputToml: return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, struct { Projects []linkedProject `toml:"projects"` }{ Projects: projects, }) + case utils.OutputEnv: + return errors.Errorf("--output env flag is not supported") } return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, projects) diff --git a/internal/sso/create/create.go b/internal/sso/create/create.go index a33b6e7e7..802bbd05b 100644 --- a/internal/sso/create/create.go +++ b/internal/sso/create/create.go @@ -83,7 +83,8 @@ func Run(ctx context.Context, params RunParams) error { CreatedAt: resp.JSON201.CreatedAt, UpdatedAt: resp.JSON201.UpdatedAt, }) - + case utils.OutputEnv: + return nil default: return utils.EncodeOutput(params.Format, os.Stdout, resp.JSON201) } diff --git a/internal/sso/get/get.go b/internal/sso/get/get.go index 34370523e..75de6abcd 100644 --- a/internal/sso/get/get.go +++ b/internal/sso/get/get.go @@ -30,7 +30,6 @@ func Run(ctx context.Context, ref, providerId, format string) error { case utils.OutputMetadata: _, err := fmt.Println(*resp.JSON200.Saml.MetadataXml) return err - case utils.OutputPretty: return render.SingleMarkdown(api.Provider{ Id: resp.JSON200.Id, @@ -39,7 +38,8 @@ func Run(ctx context.Context, ref, providerId, format string) error { CreatedAt: resp.JSON200.CreatedAt, UpdatedAt: resp.JSON200.UpdatedAt, }) - + case utils.OutputEnv: + return errors.Errorf("--output env flag is not supported") default: return utils.EncodeOutput(format, os.Stdout, resp.JSON200) } diff --git a/internal/sso/info/info.go b/internal/sso/info/info.go index c8a25805f..0de8f1efd 100644 --- a/internal/sso/info/info.go +++ b/internal/sso/info/info.go @@ -13,9 +13,8 @@ func Run(ctx context.Context, ref string, format string) error { switch format { case utils.OutputPretty: return render.InfoMarkdown(ref) - default: - return utils.EncodeOutput(format, os.Stdout, map[string]interface{}{ + return utils.EncodeOutput(format, os.Stdout, map[string]string{ "acs_url": fmt.Sprintf("https://%s.supabase.co/auth/v1/sso/saml/acs", ref), "entity_id": fmt.Sprintf("https://%s.supabase.co/auth/v1/sso/saml/metadata", ref), "relay_state": fmt.Sprintf("https://%s.supabase.co", ref), diff --git a/internal/sso/remove/remove.go b/internal/sso/remove/remove.go index 1514314da..69bf5c4d0 100644 --- a/internal/sso/remove/remove.go +++ b/internal/sso/remove/remove.go @@ -34,7 +34,8 @@ func Run(ctx context.Context, ref, providerId, format string) error { CreatedAt: resp.JSON200.CreatedAt, UpdatedAt: resp.JSON200.UpdatedAt, }) - + case utils.OutputEnv: + return nil default: return utils.EncodeOutput(format, os.Stdout, resp.JSON200) } diff --git a/internal/sso/update/update.go b/internal/sso/update/update.go index e8a745dc3..5729a64e7 100644 --- a/internal/sso/update/update.go +++ b/internal/sso/update/update.go @@ -119,7 +119,8 @@ func Run(ctx context.Context, params RunParams) error { CreatedAt: putResp.JSON200.CreatedAt, UpdatedAt: putResp.JSON200.UpdatedAt, }) - + case utils.OutputEnv: + return nil default: return utils.EncodeOutput(params.Format, os.Stdout, putResp.JSON200) } diff --git a/internal/utils/output.go b/internal/utils/output.go index 6d1a72aa4..b518567ed 100644 --- a/internal/utils/output.go +++ b/internal/utils/output.go @@ -22,19 +22,16 @@ const ( OutputMetadata = "metadata" ) -var ( - OutputDefaultAllowed = []string{ +var OutputFormat = EnumFlag{ + Allowed: []string{ + OutputEnv, OutputPretty, OutputJson, OutputToml, OutputYaml, - } - - OutputFormat = EnumFlag{ - Allowed: OutputDefaultAllowed, - Value: OutputPretty, - } -) + }, + Value: OutputPretty, +} func EncodeOutput(format string, w io.Writer, value any) error { switch format { From 32064abfa8f9b0a8e18c4713f4ad4228bef0013c Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Thu, 27 Feb 2025 20:51:19 +0800 Subject: [PATCH 13/54] chore: dudupe output flag for gen keys --- cmd/gen.go | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/cmd/gen.go b/cmd/gen.go index 7f936bda0..5849a5ce0 100644 --- a/cmd/gen.go +++ b/cmd/gen.go @@ -21,16 +21,7 @@ var ( Short: "Run code generation tools", } - keyNames keys.CustomName - keyOutput = utils.EnumFlag{ - Allowed: []string{ - utils.OutputEnv, - utils.OutputJson, - utils.OutputToml, - utils.OutputYaml, - }, - Value: utils.OutputEnv, - } + keyNames keys.CustomName genKeysCmd = &cobra.Command{ Use: "keys", @@ -47,7 +38,11 @@ var ( return cmd.Root().PersistentPreRunE(cmd, args) }, RunE: func(cmd *cobra.Command, args []string) error { - return keys.Run(cmd.Context(), flags.ProjectRef, keyOutput.Value, keyNames, afero.NewOsFs()) + format := utils.OutputFormat.Value + if format == utils.OutputPretty { + format = utils.OutputEnv + } + return keys.Run(cmd.Context(), flags.ProjectRef, format, keyNames, afero.NewOsFs()) }, } @@ -114,7 +109,6 @@ func init() { genCmd.AddCommand(genTypesCmd) keyFlags := genKeysCmd.Flags() keyFlags.StringVar(&flags.ProjectRef, "project-ref", "", "Project ref of the Supabase project.") - keyFlags.VarP(&keyOutput, "output", "o", "Output format of key variables.") keyFlags.StringSliceVar(&override, "override-name", []string{}, "Override specific variable names.") genCmd.AddCommand(genKeysCmd) rootCmd.AddCommand(genCmd) From d3a60d1b6d666fddba5a1ee5c3ae0701f5e6fff9 Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Thu, 27 Feb 2025 21:57:34 +0800 Subject: [PATCH 14/54] fix: add pooler to start test (#3223) * chore: add pooler to start test * Revert "chore(deps): bump supabase/supavisor from 2.3.10 to 2.4.2 in /pkg/config/templates (#3209)" This reverts commit bff16cc51eeef4cecd477b2e7d64cdfec4d5b47b. --- .github/workflows/ci.yml | 1 + pkg/config/templates/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ce32d176b..d6bdee179 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,6 +56,7 @@ jobs: cache: true - run: go build main.go - run: ./main init + - run: sed -i '/\[db.pooler\]/{n;s/.*/enabled = true/}' supabase/config.toml - run: ./main start env: SUPABASE_INTERNAL_IMAGE_REGISTRY: ghcr.io diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index d8f04db3b..574134fdc 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -9,7 +9,7 @@ FROM supabase/studio:20250224-d10db0f AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy FROM supabase/edge-runtime:v1.67.2 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector -FROM supabase/supavisor:2.4.2 AS supavisor +FROM supabase/supavisor:2.3.10 AS supavisor FROM supabase/gotrue:v2.169.0 AS gotrue FROM supabase/realtime:v2.34.34 AS realtime FROM supabase/storage-api:v1.19.1 AS storage From 37ebd41778fc4e2ed8ee5bd64905f530f7ac6511 Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Thu, 27 Feb 2025 22:01:04 +0800 Subject: [PATCH 15/54] fix: eliminate link warning on additional url (#3222) --- pkg/config/auth_test.go | 3 ++- .../TestCaptchaDiff/local_disabled_remote_enabled.diff | 2 +- .../TestCaptchaDiff/local_enabled_remote_disabled.diff | 2 +- .../TestEmailDiff/local_disabled_remote_enabled.diff | 2 +- .../TestEmailDiff/local_enabled_remote_disabled.diff | 2 +- .../TestExternalDiff/local_enabled_and_disabled.diff | 6 +++--- .../TestHookDiff/local_disabled_remote_enabled.diff | 2 +- .../TestHookDiff/local_enabled_remote_disabled.diff | 2 +- .../testdata/TestMfaDiff/local_enabled_and_disabled.diff | 2 +- .../TestSmsDiff/enable_sign_up_without_provider.diff | 2 +- .../TestSmsDiff/local_disabled_remote_enabled.diff | 4 ++-- .../TestSmsDiff/local_enabled_remote_disabled.diff | 6 +++--- pkg/config/updater_test.go | 9 +++++---- pkg/config/utils.go | 2 +- 14 files changed, 24 insertions(+), 22 deletions(-) diff --git a/pkg/config/auth_test.go b/pkg/config/auth_test.go index 176cb79b7..a64680e0b 100644 --- a/pkg/config/auth_test.go +++ b/pkg/config/auth_test.go @@ -14,7 +14,8 @@ import ( func newWithDefaults() auth { return auth{ - EnableSignup: true, + EnableSignup: true, + AdditionalRedirectUrls: []string{}, Email: email{ EnableConfirmations: true, }, diff --git a/pkg/config/testdata/TestCaptchaDiff/local_disabled_remote_enabled.diff b/pkg/config/testdata/TestCaptchaDiff/local_disabled_remote_enabled.diff index 84085ccd4..e761786e9 100644 --- a/pkg/config/testdata/TestCaptchaDiff/local_disabled_remote_enabled.diff +++ b/pkg/config/testdata/TestCaptchaDiff/local_disabled_remote_enabled.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -10,7 +10,7 @@ +@@ -11,7 +11,7 @@ password_requirements = "" [captcha] diff --git a/pkg/config/testdata/TestCaptchaDiff/local_enabled_remote_disabled.diff b/pkg/config/testdata/TestCaptchaDiff/local_enabled_remote_disabled.diff index 43bb8802b..440eafba1 100644 --- a/pkg/config/testdata/TestCaptchaDiff/local_enabled_remote_disabled.diff +++ b/pkg/config/testdata/TestCaptchaDiff/local_enabled_remote_disabled.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -10,9 +10,9 @@ +@@ -11,9 +11,9 @@ password_requirements = "" [captcha] diff --git a/pkg/config/testdata/TestEmailDiff/local_disabled_remote_enabled.diff b/pkg/config/testdata/TestEmailDiff/local_disabled_remote_enabled.diff index 99a50071f..fdf64dc65 100644 --- a/pkg/config/testdata/TestEmailDiff/local_disabled_remote_enabled.diff +++ b/pkg/config/testdata/TestEmailDiff/local_disabled_remote_enabled.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -31,13 +31,13 @@ +@@ -32,13 +32,13 @@ inactivity_timeout = "0s" [email] diff --git a/pkg/config/testdata/TestEmailDiff/local_enabled_remote_disabled.diff b/pkg/config/testdata/TestEmailDiff/local_enabled_remote_disabled.diff index fb42aaabb..9fd0dbbec 100644 --- a/pkg/config/testdata/TestEmailDiff/local_enabled_remote_disabled.diff +++ b/pkg/config/testdata/TestEmailDiff/local_enabled_remote_disabled.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -31,36 +31,44 @@ +@@ -32,36 +32,44 @@ inactivity_timeout = "0s" [email] diff --git a/pkg/config/testdata/TestExternalDiff/local_enabled_and_disabled.diff b/pkg/config/testdata/TestExternalDiff/local_enabled_and_disabled.diff index 8b78fb240..372d9152c 100644 --- a/pkg/config/testdata/TestExternalDiff/local_enabled_and_disabled.diff +++ b/pkg/config/testdata/TestExternalDiff/local_enabled_and_disabled.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -71,7 +71,7 @@ +@@ -72,7 +72,7 @@ [external] [external.apple] @@ -10,7 +10,7 @@ diff remote[auth] local[auth] client_id = "test-client-1,test-client-2" secret = "hash:ce62bb9bcced294fd4afe668f8ab3b50a89cf433093c526fffa3d0e46bf55252" url = "" -@@ -78,9 +78,9 @@ +@@ -79,9 +79,9 @@ redirect_uri = "" skip_nonce_check = false [external.azure] @@ -23,7 +23,7 @@ diff remote[auth] local[auth] url = "" redirect_uri = "" skip_nonce_check = false -@@ -127,7 +127,7 @@ +@@ -128,7 +128,7 @@ redirect_uri = "" skip_nonce_check = false [external.google] diff --git a/pkg/config/testdata/TestHookDiff/local_disabled_remote_enabled.diff b/pkg/config/testdata/TestHookDiff/local_disabled_remote_enabled.diff index 247618f0c..ea7da07ef 100644 --- a/pkg/config/testdata/TestHookDiff/local_disabled_remote_enabled.diff +++ b/pkg/config/testdata/TestHookDiff/local_disabled_remote_enabled.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -11,19 +11,19 @@ +@@ -12,19 +12,19 @@ [hook] [hook.mfa_verification_attempt] diff --git a/pkg/config/testdata/TestHookDiff/local_enabled_remote_disabled.diff b/pkg/config/testdata/TestHookDiff/local_enabled_remote_disabled.diff index 556b13ff5..cabd1d757 100644 --- a/pkg/config/testdata/TestHookDiff/local_enabled_remote_disabled.diff +++ b/pkg/config/testdata/TestHookDiff/local_enabled_remote_disabled.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -11,20 +11,20 @@ +@@ -12,20 +12,20 @@ [hook] [hook.mfa_verification_attempt] diff --git a/pkg/config/testdata/TestMfaDiff/local_enabled_and_disabled.diff b/pkg/config/testdata/TestMfaDiff/local_enabled_and_disabled.diff index e5fa7c476..6687ca2fb 100644 --- a/pkg/config/testdata/TestMfaDiff/local_enabled_and_disabled.diff +++ b/pkg/config/testdata/TestMfaDiff/local_enabled_and_disabled.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -12,16 +12,16 @@ +@@ -13,16 +13,16 @@ [hook] [mfa] diff --git a/pkg/config/testdata/TestSmsDiff/enable_sign_up_without_provider.diff b/pkg/config/testdata/TestSmsDiff/enable_sign_up_without_provider.diff index a7c312c91..2b0a59538 100644 --- a/pkg/config/testdata/TestSmsDiff/enable_sign_up_without_provider.diff +++ b/pkg/config/testdata/TestSmsDiff/enable_sign_up_without_provider.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -40,7 +40,7 @@ +@@ -41,7 +41,7 @@ otp_expiry = 0 [sms] diff --git a/pkg/config/testdata/TestSmsDiff/local_disabled_remote_enabled.diff b/pkg/config/testdata/TestSmsDiff/local_disabled_remote_enabled.diff index 1dd938cd7..1504a0bf8 100644 --- a/pkg/config/testdata/TestSmsDiff/local_disabled_remote_enabled.diff +++ b/pkg/config/testdata/TestSmsDiff/local_disabled_remote_enabled.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -40,12 +40,12 @@ +@@ -41,12 +41,12 @@ otp_expiry = 0 [sms] @@ -19,7 +19,7 @@ diff remote[auth] local[auth] account_sid = "" message_service_sid = "" auth_token = "" -@@ -68,8 +68,6 @@ +@@ -69,8 +69,6 @@ api_key = "" api_secret = "" [sms.test_otp] diff --git a/pkg/config/testdata/TestSmsDiff/local_enabled_remote_disabled.diff b/pkg/config/testdata/TestSmsDiff/local_enabled_remote_disabled.diff index 02f0b76cd..99f0d6131 100644 --- a/pkg/config/testdata/TestSmsDiff/local_enabled_remote_disabled.diff +++ b/pkg/config/testdata/TestSmsDiff/local_enabled_remote_disabled.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -40,12 +40,12 @@ +@@ -41,12 +41,12 @@ otp_expiry = 0 [sms] @@ -19,7 +19,7 @@ diff remote[auth] local[auth] account_sid = "" message_service_sid = "" auth_token = "" -@@ -55,9 +55,9 @@ +@@ -56,9 +56,9 @@ message_service_sid = "" auth_token = "" [sms.messagebird] @@ -32,7 +32,7 @@ diff remote[auth] local[auth] [sms.textlocal] enabled = false sender = "" -@@ -68,6 +68,7 @@ +@@ -69,6 +69,7 @@ api_key = "" api_secret = "" [sms.test_otp] diff --git a/pkg/config/updater_test.go b/pkg/config/updater_test.go index f3eb0bcb4..05a5d91d7 100644 --- a/pkg/config/updater_test.go +++ b/pkg/config/updater_test.go @@ -190,10 +190,11 @@ func TestUpdateAuthConfig(t *testing.T) { JSON(v1API.AuthConfigResponse{}) // Run test err := updater.UpdateAuthConfig(context.Background(), "test-project", auth{ - Enabled: true, - EnableSignup: true, - Email: email{EnableConfirmations: true}, - Sms: sms{TestOTP: map[string]string{}}, + Enabled: true, + EnableSignup: true, + AdditionalRedirectUrls: []string{}, + Email: email{EnableConfirmations: true}, + Sms: sms{TestOTP: map[string]string{}}, }) // Check result assert.NoError(t, err) diff --git a/pkg/config/utils.go b/pkg/config/utils.go index 78a991c82..e4a77aef4 100644 --- a/pkg/config/utils.go +++ b/pkg/config/utils.go @@ -89,7 +89,7 @@ func replaceImageTag(image string, tag string) string { func strToArr(v string) []string { // Avoid returning [""] if v is empty if len(v) == 0 { - return nil + return []string{} } return strings.Split(v, ",") } From df81dd6e27caad8815d67c982069dbe42d3dba4f Mon Sep 17 00:00:00 2001 From: Julien Goux Date: Thu, 27 Feb 2025 16:10:44 +0100 Subject: [PATCH 16/54] fix: drop public views explicitly --- pkg/migration/queries/drop.sql | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pkg/migration/queries/drop.sql b/pkg/migration/queries/drop.sql index 71564659c..3a5ecfe4f 100644 --- a/pkg/migration/queries/drop.sql +++ b/pkg/migration/queries/drop.sql @@ -20,6 +20,17 @@ begin execute format('drop routine if exists %I.%I(%s) cascade', rec.pronamespace::regnamespace::name, rec.proname, pg_catalog.pg_get_function_identity_arguments(rec.oid)); end loop; + -- views (necessary for views targeting supabase specific schemas objects) + for rec in + select * + from pg_class c + where + c.relnamespace::regnamespace::name = 'public' + and c.relkind = 'v' + loop + execute format('drop view if exists %I.%I cascade', rec.relnamespace::regnamespace::name, rec.relname); + end loop; + -- tables (cascade to views) for rec in select * From 8e04aeff947a140ec4cf176812fb2b8f783fc017 Mon Sep 17 00:00:00 2001 From: Julien Goux Date: Thu, 27 Feb 2025 16:51:17 +0100 Subject: [PATCH 17/54] handle materialized views as well --- pkg/migration/queries/drop.sql | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/pkg/migration/queries/drop.sql b/pkg/migration/queries/drop.sql index 3a5ecfe4f..ed07c7242 100644 --- a/pkg/migration/queries/drop.sql +++ b/pkg/migration/queries/drop.sql @@ -20,7 +20,7 @@ begin execute format('drop routine if exists %I.%I(%s) cascade', rec.pronamespace::regnamespace::name, rec.proname, pg_catalog.pg_get_function_identity_arguments(rec.oid)); end loop; - -- views (necessary for views targeting supabase specific schemas objects) + -- views (necessary for views referencing objects in Supabase-managed schemas) for rec in select * from pg_class c @@ -31,6 +31,17 @@ begin execute format('drop view if exists %I.%I cascade', rec.relnamespace::regnamespace::name, rec.relname); end loop; + -- materialized views (necessary for materialized views referencing objects in Supabase-managed schemas) + for rec in + select * + from pg_class c + where + c.relnamespace::regnamespace::name = 'public' + and c.relkind = 'm' + loop + execute format('drop materialized view if exists %I.%I cascade', rec.relnamespace::regnamespace::name, rec.relname); + end loop; + -- tables (cascade to views) for rec in select * From 08dc55de921ce0512d01bd561608f08f8e71aa21 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2025 04:31:53 +0000 Subject: [PATCH 18/54] chore(deps): bump github.com/go-git/go-git/v5 from 5.13.2 to 5.14.0 (#3225) Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) from 5.13.2 to 5.14.0. - [Release notes](https://github.com/go-git/go-git/releases) - [Commits](https://github.com/go-git/go-git/compare/v5.13.2...v5.14.0) --- updated-dependencies: - dependency-name: github.com/go-git/go-git/v5 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 16 ++++++++-------- go.sum | 35 ++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/go.mod b/go.mod index 05d8d25b7..0330961c5 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/ecies/go/v2 v2.0.10 github.com/getsentry/sentry-go v0.31.1 github.com/go-errors/errors v1.5.1 - github.com/go-git/go-git/v5 v5.13.2 + github.com/go-git/go-git/v5 v5.14.0 github.com/go-xmlfmt/xmlfmt v1.1.3 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/golangci/golangci-lint v1.64.5 @@ -104,12 +104,12 @@ require ( github.com/charmbracelet/x/ansi v0.1.4 // indirect github.com/chavacava/garif v0.1.0 // indirect github.com/ckaznocha/intrange v0.3.0 // indirect - github.com/cloudflare/circl v1.3.7 // indirect + github.com/cloudflare/circl v1.6.0 // indirect github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect github.com/containerd/log v0.1.0 // indirect github.com/containers/storage v1.57.1 // indirect github.com/curioswitch/go-reassign v0.3.0 // indirect - github.com/cyphar/filepath-securejoin v0.3.6 // indirect + github.com/cyphar/filepath-securejoin v0.4.1 // indirect github.com/daixiang0/gci v0.13.5 // indirect github.com/danieljoos/wincred v1.2.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -154,7 +154,7 @@ require ( github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gofrs/flock v0.12.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect github.com/golangci/go-printf-func-name v0.1.0 // indirect @@ -163,7 +163,7 @@ require ( github.com/golangci/plugin-module-register v0.1.1 // indirect github.com/golangci/revgrep v0.8.0 // indirect github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed // indirect - github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gordonklaus/ineffassign v0.1.0 // indirect github.com/gorilla/css v1.0.0 // indirect @@ -258,7 +258,7 @@ require ( github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect github.com/raeperd/recvcheck v0.2.0 // indirect github.com/rivo/uniseg v0.4.7 // indirect - github.com/rogpeppe/go-internal v1.13.1 // indirect + github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/ryancurrah/gomodguard v1.3.5 // indirect github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect @@ -273,7 +273,7 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/sivchari/containedctx v1.0.3 // indirect github.com/sivchari/tenv v1.12.1 // indirect - github.com/skeema/knownhosts v1.3.0 // indirect + github.com/skeema/knownhosts v1.3.1 // indirect github.com/sonatard/noctx v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/sourcegraph/go-diff v0.7.0 // indirect @@ -323,7 +323,7 @@ require ( go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/multierr v1.9.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.33.0 // indirect + golang.org/x/crypto v0.35.0 // indirect golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 // indirect golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac // indirect golang.org/x/net v0.35.0 // indirect diff --git a/go.sum b/go.sum index f3aff5d69..4fcd5f65e 100644 --- a/go.sum +++ b/go.sum @@ -183,8 +183,8 @@ github.com/ckaznocha/intrange v0.3.0/go.mod h1:+I/o2d2A1FBHgGELbGxzIcyd3/9l9Duwj github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e85keuznYcH5rqI438v41pKcBl4ZxQ= github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= -github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= -github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk= +github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= @@ -205,8 +205,8 @@ github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/curioswitch/go-reassign v0.3.0 h1:dh3kpQHuADL3cobV/sSGETA8DOv457dwl+fbBAhrQPs= github.com/curioswitch/go-reassign v0.3.0/go.mod h1:nApPCCTtqLJN/s8HfItCcKV0jIPwluBOvZP+dsJGA88= -github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= -github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= +github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/daixiang0/gci v0.13.5 h1:kThgmH1yBmZSBCh1EJVxQ7JsHpm5Oms0AMed/0LaH4c= github.com/daixiang0/gci v0.13.5/go.mod h1:12etP2OniiIdP4q+kjUGrC/rUagga7ODbqsom5Eo5Yk= github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0= @@ -253,8 +253,8 @@ github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5ql github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= github.com/ecies/go/v2 v2.0.10 h1:AaLxGio0MLLbvWur4rKnLzw+K9zI+wMScIDAtqCqOtU= github.com/ecies/go/v2 v2.0.10/go.mod h1:N73OyuR6tuKznit2LhXjrZ0XAQ234uKbzYz8pEPYzlI= -github.com/elazarl/goproxy v1.4.0 h1:4GyuSbFa+s26+3rmYNSuUVsx+HgPrV1bk1jXI0l9wjM= -github.com/elazarl/goproxy v1.4.0/go.mod h1:X/5W/t+gzDyLfHW4DrMdpjqYjpXsURlBt9lpBDxZZZQ= +github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o= +github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -305,8 +305,8 @@ github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UN github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0= -github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A= +github.com/go-git/go-git/v5 v5.14.0 h1:/MD3lCrGjCen5WfEAzKg00MJJffKhC8gzS80ycmCi60= +github.com/go-git/go-git/v5 v5.14.0/go.mod h1:Z5Xhoia5PcWA3NF8vRLURn9E5FRhSl7dGj9ItW3Wk5k= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -380,8 +380,8 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -441,8 +441,9 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-github/v62 v62.0.0 h1:/6mGCaRywZz9MuHyw9gD1CwsbmBX8GWsbFkwMmHdhl4= github.com/google/go-github/v62 v62.0.0/go.mod h1:EMxeUqGJq2xRu9DYBMwel/mr7kZrzUOfQmmpYrZn2a4= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= @@ -854,8 +855,8 @@ github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= @@ -901,8 +902,8 @@ github.com/sivchari/containedctx v1.0.3 h1:x+etemjbsh2fB5ewm5FeLNi5bUjK0V8n0RB+W github.com/sivchari/containedctx v1.0.3/go.mod h1:c1RDvCbnJLtH4lLcYD/GqwiBSSf4F5Qk0xld2rBqzJ4= github.com/sivchari/tenv v1.12.1 h1:+E0QzjktdnExv/wwsnnyk4oqZBUfuh89YMQT1cyuvSY= github.com/sivchari/tenv v1.12.1/go.mod h1:1LjSOUCc25snIr5n3DtGGrENhX3LuWefcplwVGC24mw= -github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= -github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= +github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= +github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= github.com/slack-go/slack v0.16.0 h1:khp/WCFv+Hb/B/AJaAwvcxKun0hM6grN0bUZ8xG60P8= github.com/slack-go/slack v0.16.0/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= github.com/sonatard/noctx v0.1.0 h1:JjqOc2WN16ISWAjAk8M5ej0RfExEXtkEyExl2hLW+OM= @@ -1104,8 +1105,8 @@ golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= -golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= +golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= From f35d660ef85226852df8439515270cfd4c97f94e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2025 05:15:43 +0000 Subject: [PATCH 19/54] chore(deps): bump supabase/realtime from v2.34.34 to v2.34.37 in /pkg/config/templates (#3227) chore(deps): bump supabase/realtime in /pkg/config/templates Bumps supabase/realtime from v2.34.34 to v2.34.37. --- updated-dependencies: - dependency-name: supabase/realtime dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 574134fdc..89bcc9988 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -11,7 +11,7 @@ FROM supabase/edge-runtime:v1.67.2 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.3.10 AS supavisor FROM supabase/gotrue:v2.169.0 AS gotrue -FROM supabase/realtime:v2.34.34 AS realtime +FROM supabase/realtime:v2.34.37 AS realtime FROM supabase/storage-api:v1.19.1 AS storage FROM supabase/logflare:1.11.0 AS logflare # Append to JobImages when adding new dependencies below From 074079ef307100d2db5a75c8a5ab2f1bdb35923c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2025 05:19:46 +0000 Subject: [PATCH 20/54] chore(deps): bump supabase/postgres from 15.8.1.045 to 15.8.1.046 in /pkg/config/templates (#3228) chore(deps): bump supabase/postgres in /pkg/config/templates Bumps supabase/postgres from 15.8.1.045 to 15.8.1.046. --- updated-dependencies: - dependency-name: supabase/postgres dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 89bcc9988..4809fe56a 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -1,5 +1,5 @@ # Exposed for updates by .github/dependabot.yml -FROM supabase/postgres:15.8.1.045 AS pg15 +FROM supabase/postgres:15.8.1.046 AS pg15 # Append to ServiceImages when adding new dependencies below FROM library/kong:2.8.1 AS kong FROM inbucket/inbucket:3.0.3 AS inbucket From 9ce71ee4d5675aaa91d31e820e1530e4ededf160 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Fri, 28 Feb 2025 16:15:31 +0800 Subject: [PATCH 21/54] fix: remove dependency on global viper --- pkg/config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index 306256806..1e7da0a63 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -871,7 +871,7 @@ func loadNestedEnv(basePath string) error { if !filepath.IsAbs(basePath) { basePath = filepath.Join(repoDir, basePath) } - env := viper.GetString("ENV") + env := os.Getenv("SUPABASE_ENV") for cwd := basePath; cwd != filepath.Dir(repoDir); cwd = filepath.Dir(cwd) { if err := os.Chdir(cwd); err != nil && !errors.Is(err, os.ErrNotExist) { return errors.Errorf("failed to change directory: %w", err) From bb8f0415935b58ea8a95997d4680467be19fca6a Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Fri, 28 Feb 2025 16:51:43 +0800 Subject: [PATCH 22/54] chore: parse private keys when instantiating hook --- pkg/config/secret.go | 71 ++++++++++++++++++++++----------------- pkg/config/secret_test.go | 2 +- 2 files changed, 42 insertions(+), 31 deletions(-) diff --git a/pkg/config/secret.go b/pkg/config/secret.go index d83ad5365..c78a5b8b8 100644 --- a/pkg/config/secret.go +++ b/pkg/config/secret.go @@ -27,14 +27,31 @@ func (s Secret) MarshalText() (text []byte, err error) { const ENCRYPTED_PREFIX = "encrypted:" +func (s *Secret) Decrypt(keys []string) error { + if !strings.HasPrefix(s.Value, ENCRYPTED_PREFIX) { + return nil + } + if len(keys) == 0 { + return errors.New(errMissingKey) + } + var err error + for _, k := range keys { + // Use the first private key that successfully decrypts the secret + if s.Value, err = decrypt(k, s.Value); err == nil { + break + } + } + // If we didn't break, none of the keys worked + return err +} + +var errMissingKey = errors.New("missing private key") + // Decrypt secret values following dotenvx convention: // https://github.com/dotenvx/dotenvx/blob/main/src/lib/helpers/decryptKeyValue.js func decrypt(key, value string) (string, error) { - if !strings.HasPrefix(value, ENCRYPTED_PREFIX) { - return value, nil - } if len(key) == 0 { - return value, errors.New("missing private key") + return value, errors.New(errMissingKey) } // Verify private key exists privateKey, err := ecies.NewPrivateKeyFromHex(key) @@ -55,7 +72,17 @@ func decrypt(key, value string) (string, error) { return string(plaintext), nil } +const PRIVATE_KEY_PREFIX = "DOTENV_PRIVATE_KEY" + func DecryptSecretHookFunc(hashKey string) mapstructure.DecodeHookFunc { + // Get all env vars and filter for private keys + var privateKeys []string + for _, env := range os.Environ() { + kv := strings.SplitN(env, "=", 2) + if kv[0] == PRIVATE_KEY_PREFIX || strings.HasPrefix(kv[0], PRIVATE_KEY_PREFIX+"_") { + privateKeys = append(privateKeys, strToArr(kv[1])...) + } + } return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { if f.Kind() != reflect.String { return data, nil @@ -64,35 +91,19 @@ func DecryptSecretHookFunc(hashKey string) mapstructure.DecodeHookFunc { if t != reflect.TypeOf(result) { return data, nil } - value := data.(string) - if len(value) == 0 { + result.Value = data.(string) + if len(result.Value) == 0 { return result, nil } - // Get all env vars and filter for DOTENV_PRIVATE_KEY - var privateKeys []string - for _, env := range os.Environ() { - key := strings.Split(env, "=")[0] - if key == "DOTENV_PRIVATE_KEY" || strings.HasPrefix(key, "DOTENV_PRIVATE_KEY_") { - if value := os.Getenv(key); value != "" { - privateKeys = append(privateKeys, value) - } - } + // Unloaded env() references should be returned verbatim without hashing + if envPattern.MatchString(result.Value) { + return result, nil } - // Try each private key - var err error - privKey := strings.Join(privateKeys, ",") - for _, k := range strings.Split(privKey, ",") { - // Use the first private key that successfully decrypts the secret - if result.Value, err = decrypt(k, value); err == nil { - // Unloaded env() references may be returned verbatim. - // Don't hash those values as they are meaningless. - if !envPattern.MatchString(result.Value) { - result.SHA256 = sha256Hmac(hashKey, result.Value) - } - break - } + if err := result.Decrypt(privateKeys); err != nil { + return result, err } - // If we get here, none of the keys worked - return result, err + // Decrypted values should be hashed + result.SHA256 = sha256Hmac(hashKey, result.Value) + return result, nil } } diff --git a/pkg/config/secret_test.go b/pkg/config/secret_test.go index c4bf74e5b..a83d07666 100644 --- a/pkg/config/secret_test.go +++ b/pkg/config/secret_test.go @@ -22,7 +22,7 @@ func TestDecryptSecret(t *testing.T) { // Run test plaintext, err := decrypt("", value) // Check error - assert.ErrorContains(t, err, "missing private key") + assert.ErrorIs(t, err, errMissingKey) assert.Equal(t, value, plaintext) }) From 37907393cbbe74bcc27bf7d37ffb1b627f007eaa Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Fri, 28 Feb 2025 18:52:19 +0800 Subject: [PATCH 23/54] fix: set openai api key as secret --- internal/start/start.go | 2 +- pkg/config/config.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/start/start.go b/internal/start/start.go index 5402283b7..70d44c7fc 100644 --- a/internal/start/start.go +++ b/internal/start/start.go @@ -988,7 +988,7 @@ EOF "SUPABASE_ANON_KEY=" + utils.Config.Auth.AnonKey, "SUPABASE_SERVICE_KEY=" + utils.Config.Auth.ServiceRoleKey, "LOGFLARE_API_KEY=" + utils.Config.Analytics.ApiKey, - "OPENAI_API_KEY=" + utils.Config.Studio.OpenaiApiKey, + "OPENAI_API_KEY=" + utils.Config.Studio.OpenaiApiKey.Value, fmt.Sprintf("LOGFLARE_URL=http://%v:4000", utils.LogflareId), fmt.Sprintf("NEXT_PUBLIC_ENABLE_LOGS=%v", utils.Config.Analytics.Enabled), fmt.Sprintf("NEXT_ANALYTICS_BACKEND_PROVIDER=%v", utils.Config.Analytics.Backend), diff --git a/pkg/config/config.go b/pkg/config/config.go index 1e7da0a63..9e78299d0 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -205,7 +205,7 @@ type ( Image string `toml:"-"` Port uint16 `toml:"port"` ApiUrl string `toml:"api_url"` - OpenaiApiKey string `toml:"openai_api_key"` + OpenaiApiKey Secret `toml:"openai_api_key"` PgmetaImage string `toml:"-"` } From 7c0adfe538b0b23926e19b10a0e88967d10b0305 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 04:16:08 +0000 Subject: [PATCH 24/54] chore(deps): bump github.com/golangci/golangci-lint from 1.64.5 to 1.64.6 (#3235) chore(deps): bump github.com/golangci/golangci-lint Bumps [github.com/golangci/golangci-lint](https://github.com/golangci/golangci-lint) from 1.64.5 to 1.64.6. - [Release notes](https://github.com/golangci/golangci-lint/releases) - [Changelog](https://github.com/golangci/golangci-lint/blob/master/CHANGELOG.md) - [Commits](https://github.com/golangci/golangci-lint/compare/v1.64.5...v1.64.6) --- updated-dependencies: - dependency-name: github.com/golangci/golangci-lint dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 26 +++++++++++++------------- go.sum | 51 ++++++++++++++++++++++++++------------------------- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/go.mod b/go.mod index 0330961c5..66788505c 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/go-git/go-git/v5 v5.14.0 github.com/go-xmlfmt/xmlfmt v1.1.3 github.com/golang-jwt/jwt/v5 v5.2.1 - github.com/golangci/golangci-lint v1.64.5 + github.com/golangci/golangci-lint v1.64.6 github.com/google/go-github/v62 v62.0.0 github.com/google/go-querystring v1.1.0 github.com/google/uuid v1.6.0 @@ -58,11 +58,11 @@ require ( ) require ( - 4d63.com/gocheckcompilerdirectives v1.2.1 // indirect + 4d63.com/gocheckcompilerdirectives v1.3.0 // indirect 4d63.com/gochecknoglobals v0.2.2 // indirect al.essio.dev/pkg/shellescape v1.5.1 // indirect dario.cat/mergo v1.0.1 // indirect - github.com/4meepo/tagalign v1.4.1 // indirect + github.com/4meepo/tagalign v1.4.2 // indirect github.com/Abirdcfly/dupword v0.1.3 // indirect github.com/Antonboom/errname v1.0.0 // indirect github.com/Antonboom/nilnil v1.0.1 // indirect @@ -70,7 +70,7 @@ require ( github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect github.com/Crocmagnon/fatcontext v0.7.1 // indirect github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect - github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 // indirect + github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1 // indirect github.com/Masterminds/semver/v3 v3.3.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/OpenPeeDeeP/depguard/v2 v2.2.0 // indirect @@ -96,7 +96,7 @@ require ( github.com/breml/errchkjson v0.4.0 // indirect github.com/butuzov/ireturn v0.3.1 // indirect github.com/butuzov/mirror v1.3.0 // indirect - github.com/catenacyber/perfsprint v0.8.1 // indirect + github.com/catenacyber/perfsprint v0.8.2 // indirect github.com/ccojocar/zxcvbn-go v1.0.2 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/charithe/durationcheck v0.0.10 // indirect @@ -170,7 +170,7 @@ require ( github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect - github.com/gostaticanalysis/comment v1.4.2 // indirect + github.com/gostaticanalysis/comment v1.5.0 // indirect github.com/gostaticanalysis/forcetypeassert v0.2.0 // indirect github.com/gostaticanalysis/nilerr v0.1.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect @@ -194,14 +194,14 @@ require ( github.com/julz/importas v0.2.0 // indirect github.com/karamaru-alpha/copyloopvar v1.2.1 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect - github.com/kisielk/errcheck v1.8.0 // indirect - github.com/kkHAIKE/contextcheck v1.1.5 // indirect + github.com/kisielk/errcheck v1.9.0 // indirect + github.com/kkHAIKE/contextcheck v1.1.6 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.10 // indirect github.com/lasiar/canonicalheader v1.1.2 // indirect - github.com/ldez/exptostd v0.4.1 // indirect + github.com/ldez/exptostd v0.4.2 // indirect github.com/ldez/gomoddirectives v0.6.1 // indirect github.com/ldez/grignotin v0.9.0 // indirect github.com/ldez/tagliatelle v0.7.1 // indirect @@ -220,7 +220,7 @@ require ( github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect - github.com/mgechev/revive v1.6.1 // indirect + github.com/mgechev/revive v1.7.0 // indirect github.com/microcosm-cc/bluemonday v1.0.25 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -237,7 +237,7 @@ require ( github.com/nakabonne/nestif v0.3.1 // indirect github.com/nishanths/exhaustive v0.12.0 // indirect github.com/nishanths/predeclared v0.2.2 // indirect - github.com/nunnatsa/ginkgolinter v0.19.0 // indirect + github.com/nunnatsa/ginkgolinter v0.19.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect @@ -283,8 +283,8 @@ require ( github.com/stbenjam/no-sprintf-host-port v0.2.0 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/tdakkota/asciicheck v0.4.0 // indirect - github.com/tetafro/godot v1.4.20 // indirect + github.com/tdakkota/asciicheck v0.4.1 // indirect + github.com/tetafro/godot v1.5.0 // indirect github.com/theupdateframework/notary v0.7.0 // indirect github.com/timakin/bodyclose v0.0.0-20241017074812-ed6a65f985e3 // indirect github.com/timonwong/loggercheck v0.10.1 // indirect diff --git a/go.sum b/go.sum index 4fcd5f65e..ade5b6e3d 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -4d63.com/gocheckcompilerdirectives v1.2.1 h1:AHcMYuw56NPjq/2y615IGg2kYkBdTvOaojYCBcRE7MA= -4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs= +4d63.com/gocheckcompilerdirectives v1.3.0 h1:Ew5y5CtcAAQeTVKUVFrE7EwHMrTO6BggtEj8BZSjZ3A= +4d63.com/gocheckcompilerdirectives v1.3.0/go.mod h1:ofsJ4zx2QAuIP/NO/NAh1ig6R1Fb18/GI7RVMwz7kAY= 4d63.com/gochecknoglobals v0.2.2 h1:H1vdnwnMaZdQW/N+NrkT1SZMTBmcwHe9Vq8lJcYYTtU= 4d63.com/gochecknoglobals v0.2.2/go.mod h1:lLxwTQjL5eIesRbvnzIP3jZtG140FnTdz+AlMa+ogt0= al.essio.dev/pkg/shellescape v1.5.1 h1:86HrALUujYS/h+GtqoB26SBEdkWfmMI6FubjXlsXyho= @@ -39,8 +39,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/4meepo/tagalign v1.4.1 h1:GYTu2FaPGOGb/xJalcqHeD4il5BiCywyEYZOA55P6J4= -github.com/4meepo/tagalign v1.4.1/go.mod h1:2H9Yu6sZ67hmuraFgfZkNcg5Py9Ch/Om9l2K/2W1qS4= +github.com/4meepo/tagalign v1.4.2 h1:0hcLHPGMjDyM1gHG58cS73aQF8J4TdVR96TZViorO9E= +github.com/4meepo/tagalign v1.4.2/go.mod h1:+p4aMyFM+ra7nb41CnFG6aSDXqRxU/w1VQqScKqDARI= github.com/Abirdcfly/dupword v0.1.3 h1:9Pa1NuAsZvpFPi9Pqkd93I7LIYRURj+A//dFd5tgBeE= github.com/Abirdcfly/dupword v0.1.3/go.mod h1:8VbB2t7e10KRNdwTVoxdBaxla6avbhGzb8sCTygUMhw= github.com/Antonboom/errname v1.0.0 h1:oJOOWR07vS1kRusl6YRSlat7HFnb3mSfMl6sDMRoTBA= @@ -59,8 +59,8 @@ github.com/Crocmagnon/fatcontext v0.7.1 h1:SC/VIbRRZQeQWj/TcQBS6JmrXcfA+BU4OGSVU github.com/Crocmagnon/fatcontext v0.7.1/go.mod h1:1wMvv3NXEBJucFGfwOJBxSVWcoIO6emV215SMkW9MFU= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= -github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 h1:/fTUt5vmbkAcMBt4YQiuC23cV0kEsN1MVMNqeOW43cU= -github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0/go.mod h1:ONJg5sxcbsdQQ4pOW8TGdTidT2TMAUy/2Xhr8mrYaao= +github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1 h1:Sz1JIXEcSfhz7fUi7xHnhpIE0thVASYjvosApmHuD2k= +github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1/go.mod h1:n/LSCXNuIYqVfBlVXyHfMQkZDdp1/mmxfSjADd3z1Zg= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= @@ -148,8 +148,8 @@ github.com/butuzov/ireturn v0.3.1 h1:mFgbEI6m+9W8oP/oDdfA34dLisRFCj2G6o/yiI1yZrY github.com/butuzov/ireturn v0.3.1/go.mod h1:ZfRp+E7eJLC0NQmk1Nrm1LOrn/gQlOykv+cVPdiXH5M= github.com/butuzov/mirror v1.3.0 h1:HdWCXzmwlQHdVhwvsfBb2Au0r3HyINry3bDWLYXiKoc= github.com/butuzov/mirror v1.3.0/go.mod h1:AEij0Z8YMALaq4yQj9CPPVYOyJQyiexpQEQgihajRfI= -github.com/catenacyber/perfsprint v0.8.1 h1:bGOHuzHe0IkoGeY831RW4aSlt1lPRd3WRAScSWOaV7E= -github.com/catenacyber/perfsprint v0.8.1/go.mod h1:/wclWYompEyjUD2FuIIDVKNkqz7IgBIWXIH3V0Zol50= +github.com/catenacyber/perfsprint v0.8.2 h1:+o9zVmCSVa7M4MvabsWvESEhpsMkhfE7k0sHNGL95yw= +github.com/catenacyber/perfsprint v0.8.2/go.mod h1:q//VWC2fWbcdSLEY1R3l8n0zQCDPdE4IjZwyY1HMunM= github.com/ccojocar/zxcvbn-go v1.0.2 h1:na/czXU8RrhXO4EZme6eQJLR4PzcGsahsBOAwU6I3Vg= github.com/ccojocar/zxcvbn-go v1.0.2/go.mod h1:g1qkXtUSvHP8lhHp5GrSmTz6uWALGRMQdw6Qnz/hi60= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= @@ -413,8 +413,8 @@ github.com/golangci/go-printf-func-name v0.1.0 h1:dVokQP+NMTO7jwO4bwsRwLWeudOVUP github.com/golangci/go-printf-func-name v0.1.0/go.mod h1:wqhWFH5mUdJQhweRnldEywnR5021wTdZSNgwYceV14s= github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d h1:viFft9sS/dxoYY0aiOTsLKO2aZQAPT4nlQCsimGcSGE= github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d/go.mod h1:ivJ9QDg0XucIkmwhzCDsqcnxxlDStoTl89jDMIoNxKY= -github.com/golangci/golangci-lint v1.64.5 h1:5omC86XFBKXZgCrVdUWU+WNHKd+CWCxNx717KXnzKZY= -github.com/golangci/golangci-lint v1.64.5/go.mod h1:WZnwq8TF0z61h3jLQ7Sk5trcP7b3kUFxLD6l1ivtdvU= +github.com/golangci/golangci-lint v1.64.6 h1:jOLaQN41IV7bMzXuNC4UnQGll7N1xY6eFDXkXEPGKAs= +github.com/golangci/golangci-lint v1.64.6/go.mod h1:Wz9q+6EVuqGQ94GQ96RB2mjpcZYTOGhBhbt4O7REPu4= github.com/golangci/misspell v0.6.0 h1:JCle2HUTNWirNlDIAUO44hUsKhOFqGPoC4LZxlaSXDs= github.com/golangci/misspell v0.6.0/go.mod h1:keMNyY6R9isGaSAu+4Q8NMBwMPkh15Gtc8UCVoDtAWo= github.com/golangci/plugin-module-register v0.1.1 h1:TCmesur25LnyJkpsVrupv1Cdzo+2f7zX0H6Jkw1Ol6c= @@ -481,8 +481,9 @@ github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= -github.com/gostaticanalysis/comment v1.4.2 h1:hlnx5+S2fY9Zo9ePo4AhgYsYHbM2+eAv8m/s1JiCd6Q= github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM= +github.com/gostaticanalysis/comment v1.5.0 h1:X82FLl+TswsUMpMh17srGRuKaaXprTaytmEpgnKIDu8= +github.com/gostaticanalysis/comment v1.5.0/go.mod h1:V6eb3gpCv9GNVqb6amXzEUX3jXLVK/AdA+IrAMSqvEc= github.com/gostaticanalysis/forcetypeassert v0.2.0 h1:uSnWrrUEYDr86OCxWa4/Tp2jeYDlogZiZHzGkWFefTk= github.com/gostaticanalysis/forcetypeassert v0.2.0/go.mod h1:M5iPavzE9pPqWyeiVXSFghQjljW1+l/Uke3PXHS6ILY= github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk= @@ -609,11 +610,11 @@ github.com/karamaru-alpha/copyloopvar v1.2.1/go.mod h1:nFmMlFNlClC2BPvNaHMdkirmT github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/errcheck v1.8.0 h1:ZX/URYa7ilESY19ik/vBmCn6zdGQLxACwjAcWbHlYlg= -github.com/kisielk/errcheck v1.8.0/go.mod h1:1kLL+jV4e+CFfueBmI1dSK2ADDyQnlrnrY/FqKluHJQ= +github.com/kisielk/errcheck v1.9.0 h1:9xt1zI9EBfcYBvdU1nVrzMzzUPUtPKs9bVSIM3TAb3M= +github.com/kisielk/errcheck v1.9.0/go.mod h1:kQxWMMVZgIkDq7U8xtG/n2juOjbLgZtedi0D+/VL/i8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kkHAIKE/contextcheck v1.1.5 h1:CdnJh63tcDe53vG+RebdpdXJTc9atMgGqdx8LXxiilg= -github.com/kkHAIKE/contextcheck v1.1.5/go.mod h1:O930cpht4xb1YQpK+1+AgoM3mFsvxr7uyFptcnWTYUA= +github.com/kkHAIKE/contextcheck v1.1.6 h1:7HIyRcnyzxL9Lz06NGhiKvenXq7Zw6Q0UQu/ttjfJCE= +github.com/kkHAIKE/contextcheck v1.1.6/go.mod h1:3dDbMRNBFaq8HFXWC1JyvDSPm43CmE6IuHam8Wr0rkg= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -634,8 +635,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lasiar/canonicalheader v1.1.2 h1:vZ5uqwvDbyJCnMhmFYimgMZnJMjwljN5VGY0VKbMXb4= github.com/lasiar/canonicalheader v1.1.2/go.mod h1:qJCeLFS0G/QlLQ506T+Fk/fWMa2VmBUiEI2cuMK4djI= -github.com/ldez/exptostd v0.4.1 h1:DIollgQ3LWZMp3HJbSXsdE2giJxMfjyHj3eX4oiD6JU= -github.com/ldez/exptostd v0.4.1/go.mod h1:iZBRYaUmcW5jwCR3KROEZ1KivQQp6PHXbDPk9hqJKCQ= +github.com/ldez/exptostd v0.4.2 h1:l5pOzHBz8mFOlbcifTxzfyYbgEmoUqjxLFHZkjlbHXs= +github.com/ldez/exptostd v0.4.2/go.mod h1:iZBRYaUmcW5jwCR3KROEZ1KivQQp6PHXbDPk9hqJKCQ= github.com/ldez/gomoddirectives v0.6.1 h1:Z+PxGAY+217f/bSGjNZr/b2KTXcyYLgiWI6geMBN2Qc= github.com/ldez/gomoddirectives v0.6.1/go.mod h1:cVBiu3AHR9V31em9u2kwfMKD43ayN5/XDgr+cdaFaKs= github.com/ldez/grignotin v0.9.0 h1:MgOEmjZIVNn6p5wPaGp/0OKWyvq42KnzAt/DAb8O4Ow= @@ -693,8 +694,8 @@ github.com/mattn/go-sqlite3 v1.6.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOq github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mgechev/revive v1.6.1 h1:ncK0ZCMWtb8GXwVAmk+IeWF2ULIDsvRxSRfg5sTwQ2w= -github.com/mgechev/revive v1.6.1/go.mod h1:/2tfHWVO8UQi/hqJsIYNEKELi+DJy/e+PQpLgTB1v88= +github.com/mgechev/revive v1.7.0 h1:JyeQ4yO5K8aZhIKf5rec56u0376h8AlKNQEmjfkjKlY= +github.com/mgechev/revive v1.7.0/go.mod h1:qZnwcNhoguE58dfi96IJeSTPeZQejNeoMQLUZGi4SW4= github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg= github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE= github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= @@ -743,8 +744,8 @@ github.com/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhK github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs= github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= -github.com/nunnatsa/ginkgolinter v0.19.0 h1:CnHRFAeBS3LdLI9h+Jidbcc5KH71GKOmaBZQk8Srnto= -github.com/nunnatsa/ginkgolinter v0.19.0/go.mod h1:jkQ3naZDmxaZMXPWaS9rblH+i+GWXQCaS/JFIWcOH2s= +github.com/nunnatsa/ginkgolinter v0.19.1 h1:mjwbOlDQxZi9Cal+KfbEJTCz327OLNfwNvoZ70NJ+c4= +github.com/nunnatsa/ginkgolinter v0.19.1/go.mod h1:jkQ3naZDmxaZMXPWaS9rblH+i+GWXQCaS/JFIWcOH2s= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -957,14 +958,14 @@ github.com/stripe/pg-schema-diff v0.8.0 h1:Ggm4yDbPtaflYQLV3auEMTLxQPaentV/wmDEo github.com/stripe/pg-schema-diff v0.8.0/go.mod h1:HuTBuWLuvnY9g9nptbSD58xugN19zSJNkF4w/sYRtdU= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/tdakkota/asciicheck v0.4.0 h1:VZ13Itw4k1i7d+dpDSNS8Op645XgGHpkCEh/WHicgWw= -github.com/tdakkota/asciicheck v0.4.0/go.mod h1:0k7M3rCfRXb0Z6bwgvkEIMleKH3kXNz9UqJ9Xuqopr8= +github.com/tdakkota/asciicheck v0.4.1 h1:bm0tbcmi0jezRA2b5kg4ozmMuGAFotKI3RZfrhfovg8= +github.com/tdakkota/asciicheck v0.4.1/go.mod h1:0k7M3rCfRXb0Z6bwgvkEIMleKH3kXNz9UqJ9Xuqopr8= github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag= github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= -github.com/tetafro/godot v1.4.20 h1:z/p8Ek55UdNvzt4TFn2zx2KscpW4rWqcnUrdmvWJj7E= -github.com/tetafro/godot v1.4.20/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio= +github.com/tetafro/godot v1.5.0 h1:aNwfVI4I3+gdxjMgYPus9eHmoBeJIbnajOyqZYStzuw= +github.com/tetafro/godot v1.5.0/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio= github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c= github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw= github.com/tidwall/jsonc v0.3.2 h1:ZTKrmejRlAJYdn0kcaFqRAKlxxFIC21pYq8vLa4p2Wc= From 36d95128585644cd47bfe90327666548007a373c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 05:35:35 +0000 Subject: [PATCH 25/54] chore(deps): bump supabase/postgres from 15.8.1.046 to 15.8.1.047 in /pkg/config/templates (#3237) chore(deps): bump supabase/postgres in /pkg/config/templates Bumps supabase/postgres from 15.8.1.046 to 15.8.1.047. --- updated-dependencies: - dependency-name: supabase/postgres dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 4809fe56a..84dfe57b1 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -1,5 +1,5 @@ # Exposed for updates by .github/dependabot.yml -FROM supabase/postgres:15.8.1.046 AS pg15 +FROM supabase/postgres:15.8.1.047 AS pg15 # Append to ServiceImages when adding new dependencies below FROM library/kong:2.8.1 AS kong FROM inbucket/inbucket:3.0.3 AS inbucket From 50d2230961d888cc887a9a6eaf496e481c75b418 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 05:40:26 +0000 Subject: [PATCH 26/54] chore(deps): bump supabase/realtime from v2.34.37 to v2.34.39 in /pkg/config/templates (#3236) chore(deps): bump supabase/realtime in /pkg/config/templates Bumps supabase/realtime from v2.34.37 to v2.34.39. --- updated-dependencies: - dependency-name: supabase/realtime dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 84dfe57b1..9275b5a01 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -11,7 +11,7 @@ FROM supabase/edge-runtime:v1.67.2 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.3.10 AS supavisor FROM supabase/gotrue:v2.169.0 AS gotrue -FROM supabase/realtime:v2.34.37 AS realtime +FROM supabase/realtime:v2.34.39 AS realtime FROM supabase/storage-api:v1.19.1 AS storage FROM supabase/logflare:1.11.0 AS logflare # Append to JobImages when adding new dependencies below From 7a7abede5c888a20bc15a348e3fffff1d864d986 Mon Sep 17 00:00:00 2001 From: Andrew Valleteau Date: Mon, 3 Mar 2025 09:43:23 +0100 Subject: [PATCH 27/54] feat(config): add rate limit configuration for emails in toml (#3206) * feat(config): add rate limit to config * chore: add default project values for rate limit * chore: add local config to container * chore: move email ratelimit to smtp * chore: fix tests * chore: move rateLimit to dedicated struct * chore: update tests * chore: update snapshots tests * chore: fix update * chore: rename fields * chore: update struct fields * chore: use non-pointer for rate limit * chore: update unit tests * chore: update test config --------- Co-authored-by: Qiao Han --- internal/start/start.go | 8 +++ pkg/config/auth.go | 51 ++++++++++++-- pkg/config/auth_test.go | 67 +++++++++++++++++++ pkg/config/templates/config.toml | 15 +++++ .../local_enabled_and_disabled.diff | 4 +- .../local_disabled_remote_enabled.diff | 4 +- .../local_enabled_remote_disabled.diff | 4 +- .../local_disabled_remote_enabled.diff | 2 +- .../local_enabled_remote_disabled.diff | 2 +- .../local_enabled_and_disabled.diff | 6 +- .../local_disabled_remote_enabled.diff | 2 +- .../local_enabled_remote_disabled.diff | 2 +- .../local_enabled_and_disabled.diff | 2 +- .../local_and_remote_rate_limits_differ.diff | 20 ++++++ .../enable_sign_up_without_provider.diff | 2 +- .../local_disabled_remote_enabled.diff | 4 +- .../local_enabled_remote_disabled.diff | 6 +- pkg/config/testdata/config.toml | 14 ++++ 18 files changed, 188 insertions(+), 27 deletions(-) create mode 100644 pkg/config/testdata/TestRateLimitsDiff/local_and_remote_rate_limits_differ.diff diff --git a/internal/start/start.go b/internal/start/start.go index 70d44c7fc..0b9d079ce 100644 --- a/internal/start/start.go +++ b/internal/start/start.go @@ -504,6 +504,14 @@ EOF fmt.Sprintf("GOTRUE_MFA_WEB_AUTHN_ENROLL_ENABLED=%v", utils.Config.Auth.MFA.WebAuthn.EnrollEnabled), fmt.Sprintf("GOTRUE_MFA_WEB_AUTHN_VERIFY_ENABLED=%v", utils.Config.Auth.MFA.WebAuthn.VerifyEnabled), fmt.Sprintf("GOTRUE_MFA_MAX_ENROLLED_FACTORS=%v", utils.Config.Auth.MFA.MaxEnrolledFactors), + + // Add rate limit configurations + fmt.Sprintf("GOTRUE_RATE_LIMIT_ANONYMOUS_USERS=%v", utils.Config.Auth.RateLimit.AnonymousUsers), + fmt.Sprintf("GOTRUE_RATE_LIMIT_TOKEN_REFRESH=%v", utils.Config.Auth.RateLimit.TokenRefresh), + fmt.Sprintf("GOTRUE_RATE_LIMIT_OTP=%v", utils.Config.Auth.RateLimit.SignInSignUps), + fmt.Sprintf("GOTRUE_RATE_LIMIT_VERIFY=%v", utils.Config.Auth.RateLimit.TokenVerifications), + fmt.Sprintf("GOTRUE_RATE_LIMIT_SMS_SENT=%v", utils.Config.Auth.RateLimit.SmsSent), + fmt.Sprintf("GOTRUE_RATE_LIMIT_EMAIL_SENT=%v", utils.Config.Auth.RateLimit.EmailSent), } if utils.Config.Auth.Email.Smtp != nil && utils.Config.Auth.Email.Smtp.Enabled { diff --git a/pkg/config/auth.go b/pkg/config/auth.go index 30e00e245..4b5cd546d 100644 --- a/pkg/config/auth.go +++ b/pkg/config/auth.go @@ -83,13 +83,14 @@ type ( MinimumPasswordLength uint `toml:"minimum_password_length"` PasswordRequirements PasswordRequirements `toml:"password_requirements"` - Captcha *captcha `toml:"captcha"` - Hook hook `toml:"hook"` - MFA mfa `toml:"mfa"` - Sessions sessions `toml:"sessions"` - Email email `toml:"email"` - Sms sms `toml:"sms"` - External external `toml:"external"` + RateLimit rateLimit `toml:"rate_limit"` + Captcha *captcha `toml:"captcha"` + Hook hook `toml:"hook"` + MFA mfa `toml:"mfa"` + Sessions sessions `toml:"sessions"` + Email email `toml:"email"` + Sms sms `toml:"sms"` + External external `toml:"external"` // Custom secrets can be injected from .env file JwtSecret string `toml:"-" mapstructure:"jwt_secret"` @@ -107,6 +108,15 @@ type ( Cognito tpaCognito `toml:"aws_cognito"` } + rateLimit struct { + AnonymousUsers uint `toml:"anonymous_users"` + TokenRefresh uint `toml:"token_refresh"` + SignInSignUps uint `toml:"sign_in_sign_ups"` + TokenVerifications uint `toml:"token_verifications"` + EmailSent uint `toml:"email_sent"` + SmsSent uint `toml:"sms_sent"` + } + tpaFirebase struct { Enabled bool `toml:"enabled"` @@ -262,6 +272,11 @@ func (a *auth) ToUpdateAuthConfigBody() v1API.UpdateAuthConfigBody { PasswordMinLength: cast.UintToIntPtr(&a.MinimumPasswordLength), PasswordRequiredCharacters: cast.Ptr(a.PasswordRequirements.ToChar()), } + // Add rate limit fields + a.RateLimit.toAuthConfigBody(&body) + if s := a.Email.Smtp; s != nil && s.Enabled { + body.RateLimitEmailSent = cast.Ptr(cast.UintToInt(a.RateLimit.EmailSent)) + } // When local config is not set, we assume platform defaults should not change if a.Captcha != nil { a.Captcha.toAuthConfigBody(&body) @@ -287,6 +302,10 @@ func (a *auth) FromRemoteAuthConfig(remoteConfig v1API.AuthConfigResponse) { a.MinimumPasswordLength = cast.IntToUint(cast.Val(remoteConfig.PasswordMinLength, 0)) prc := cast.Val(remoteConfig.PasswordRequiredCharacters, "") a.PasswordRequirements = NewPasswordRequirement(v1API.UpdateAuthConfigBodyPasswordRequiredCharacters(prc)) + a.RateLimit.fromAuthConfig(remoteConfig) + if s := a.Email.Smtp; s != nil && s.Enabled { + a.RateLimit.EmailSent = cast.IntToUint(cast.Val(remoteConfig.RateLimitEmailSent, 0)) + } a.Captcha.fromAuthConfig(remoteConfig) a.Hook.fromAuthConfig(remoteConfig) a.MFA.fromAuthConfig(remoteConfig) @@ -296,6 +315,24 @@ func (a *auth) FromRemoteAuthConfig(remoteConfig v1API.AuthConfigResponse) { a.External.fromAuthConfig(remoteConfig) } +func (r rateLimit) toAuthConfigBody(body *v1API.UpdateAuthConfigBody) { + body.RateLimitAnonymousUsers = cast.Ptr(cast.UintToInt(r.AnonymousUsers)) + body.RateLimitTokenRefresh = cast.Ptr(cast.UintToInt(r.TokenRefresh)) + body.RateLimitOtp = cast.Ptr(cast.UintToInt(r.SignInSignUps)) + body.RateLimitVerify = cast.Ptr(cast.UintToInt(r.TokenVerifications)) + // Email rate limit is only updated when SMTP is enabled + body.RateLimitSmsSent = cast.Ptr(cast.UintToInt(r.SmsSent)) +} + +func (r *rateLimit) fromAuthConfig(remoteConfig v1API.AuthConfigResponse) { + r.AnonymousUsers = cast.IntToUint(cast.Val(remoteConfig.RateLimitAnonymousUsers, 0)) + r.TokenRefresh = cast.IntToUint(cast.Val(remoteConfig.RateLimitTokenRefresh, 0)) + r.SignInSignUps = cast.IntToUint(cast.Val(remoteConfig.RateLimitOtp, 0)) + r.TokenVerifications = cast.IntToUint(cast.Val(remoteConfig.RateLimitVerify, 0)) + // Email rate limit is only updated when SMTP is enabled + r.SmsSent = cast.IntToUint(cast.Val(remoteConfig.RateLimitSmsSent, 0)) +} + func (c captcha) toAuthConfigBody(body *v1API.UpdateAuthConfigBody) { if body.SecurityCaptchaEnabled = &c.Enabled; c.Enabled { body.SecurityCaptchaProvider = cast.Ptr(string(c.Provider)) diff --git a/pkg/config/auth_test.go b/pkg/config/auth_test.go index a64680e0b..3bf9dae1f 100644 --- a/pkg/config/auth_test.go +++ b/pkg/config/auth_test.go @@ -1115,3 +1115,70 @@ func TestExternalDiff(t *testing.T) { assert.Empty(t, string(diff)) }) } + +func TestRateLimitsDiff(t *testing.T) { + t.Run("local and remote rate limits match", func(t *testing.T) { + // Setup auth with rate limits + c := newWithDefaults() + c.RateLimit.AnonymousUsers = 20 + c.RateLimit.TokenRefresh = 30 + c.RateLimit.SignInSignUps = 40 + c.RateLimit.TokenVerifications = 50 + c.RateLimit.EmailSent = 25 + c.RateLimit.SmsSent = 35 + c.Email.Smtp = &smtp{Enabled: true} + // Run test + diff, err := c.DiffWithRemote(v1API.AuthConfigResponse{ + RateLimitAnonymousUsers: cast.Ptr(20), + RateLimitTokenRefresh: cast.Ptr(30), + RateLimitOtp: cast.Ptr(40), + RateLimitVerify: cast.Ptr(50), + RateLimitEmailSent: cast.Ptr(25), + RateLimitSmsSent: cast.Ptr(35), + SmtpHost: cast.Ptr(""), + }) + // Check error + assert.NoError(t, err) + assert.Empty(t, string(diff)) + }) + + t.Run("local and remote rate limits differ", func(t *testing.T) { + // Setup auth with rate limits + c := newWithDefaults() + c.RateLimit.AnonymousUsers = 20 + c.RateLimit.TokenRefresh = 30 + c.RateLimit.SignInSignUps = 40 + c.RateLimit.TokenVerifications = 50 + c.RateLimit.EmailSent = 25 + c.RateLimit.SmsSent = 35 + c.Email.Smtp = &smtp{Enabled: true} + // Run test with different remote values + diff, err := c.DiffWithRemote(v1API.AuthConfigResponse{ + RateLimitAnonymousUsers: cast.Ptr(10), // Different value + RateLimitTokenRefresh: cast.Ptr(30), + RateLimitOtp: cast.Ptr(45), // Different value + RateLimitVerify: cast.Ptr(50), + RateLimitEmailSent: cast.Ptr(15), // Different value + RateLimitSmsSent: cast.Ptr(55), // Different value + SmtpHost: cast.Ptr(""), + }) + // Check error + assert.NoError(t, err) + // Compare with snapshot + assertSnapshotEqual(t, diff) + }) + + t.Run("ignores email rate limit when smtp is disabled", func(t *testing.T) { + // Setup auth without rate limits + c := newWithDefaults() + c.RateLimit.EmailSent = 25 + // Run test with remote rate limits + diff, err := c.DiffWithRemote(v1API.AuthConfigResponse{ + RateLimitEmailSent: cast.Ptr(15), + SmtpHost: cast.Ptr(""), + }) + // Check error + assert.NoError(t, err) + assert.Empty(t, string(diff)) + }) +} diff --git a/pkg/config/templates/config.toml b/pkg/config/templates/config.toml index 8e84899a2..77d854ab0 100644 --- a/pkg/config/templates/config.toml +++ b/pkg/config/templates/config.toml @@ -127,6 +127,21 @@ minimum_password_length = 6 # are: `letters_digits`, `lower_upper_letters_digits`, `lower_upper_letters_digits_symbols` password_requirements = "" +[auth.rate_limit] +# Number of emails that can be sent per hour. Requires auth.email.smtp to be enabled. +email_sent = 2 +# Number of SMS messages that can be sent per hour. Requires auth.sms to be enabled. +sms_sent = 30 +# Number of anonymous sign-ins that can be made per hour per IP address. Requires enable_anonymous_sign_ins = true. +anonymous_users = 30 +# Number of sessions that can be refreshed in a 5 minute interval per IP address. +token_refresh = 150 +# Number of sign up and sign-in requests that can be made in a 5 minute interval per IP address (excludes anonymous users). +sign_in_sign_ups = 30 +# Number of OTP / Magic link verifications that can be made in a 5 minute interval per IP address. +token_verifications = 30 + + # Configure one of the supported captcha providers: `hcaptcha`, `turnstile`. # [auth.captcha] # enabled = true diff --git a/pkg/config/testdata/TestAuthDiff/local_enabled_and_disabled.diff b/pkg/config/testdata/TestAuthDiff/local_enabled_and_disabled.diff index b4022569c..b997bb15a 100644 --- a/pkg/config/testdata/TestAuthDiff/local_enabled_and_disabled.diff +++ b/pkg/config/testdata/TestAuthDiff/local_enabled_and_disabled.diff @@ -24,5 +24,5 @@ diff remote[auth] local[auth] +minimum_password_length = 6 +password_requirements = "lower_upper_letters_digits_symbols" - [hook] - + [rate_limit] + anonymous_users = 0 diff --git a/pkg/config/testdata/TestCaptchaDiff/local_disabled_remote_enabled.diff b/pkg/config/testdata/TestCaptchaDiff/local_disabled_remote_enabled.diff index e761786e9..514251aa3 100644 --- a/pkg/config/testdata/TestCaptchaDiff/local_disabled_remote_enabled.diff +++ b/pkg/config/testdata/TestCaptchaDiff/local_disabled_remote_enabled.diff @@ -1,8 +1,8 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -11,7 +11,7 @@ - password_requirements = "" +@@ -19,7 +19,7 @@ + sms_sent = 0 [captcha] -enabled = true diff --git a/pkg/config/testdata/TestCaptchaDiff/local_enabled_remote_disabled.diff b/pkg/config/testdata/TestCaptchaDiff/local_enabled_remote_disabled.diff index 440eafba1..7bbf9ee8a 100644 --- a/pkg/config/testdata/TestCaptchaDiff/local_enabled_remote_disabled.diff +++ b/pkg/config/testdata/TestCaptchaDiff/local_enabled_remote_disabled.diff @@ -1,8 +1,8 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -11,9 +11,9 @@ - password_requirements = "" +@@ -19,9 +19,9 @@ + sms_sent = 0 [captcha] -enabled = false diff --git a/pkg/config/testdata/TestEmailDiff/local_disabled_remote_enabled.diff b/pkg/config/testdata/TestEmailDiff/local_disabled_remote_enabled.diff index fdf64dc65..031c2c5f1 100644 --- a/pkg/config/testdata/TestEmailDiff/local_disabled_remote_enabled.diff +++ b/pkg/config/testdata/TestEmailDiff/local_disabled_remote_enabled.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -32,13 +32,13 @@ +@@ -40,13 +40,13 @@ inactivity_timeout = "0s" [email] diff --git a/pkg/config/testdata/TestEmailDiff/local_enabled_remote_disabled.diff b/pkg/config/testdata/TestEmailDiff/local_enabled_remote_disabled.diff index 9fd0dbbec..b9f205742 100644 --- a/pkg/config/testdata/TestEmailDiff/local_enabled_remote_disabled.diff +++ b/pkg/config/testdata/TestEmailDiff/local_enabled_remote_disabled.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -32,36 +32,44 @@ +@@ -40,36 +40,44 @@ inactivity_timeout = "0s" [email] diff --git a/pkg/config/testdata/TestExternalDiff/local_enabled_and_disabled.diff b/pkg/config/testdata/TestExternalDiff/local_enabled_and_disabled.diff index 372d9152c..2eef288c5 100644 --- a/pkg/config/testdata/TestExternalDiff/local_enabled_and_disabled.diff +++ b/pkg/config/testdata/TestExternalDiff/local_enabled_and_disabled.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -72,7 +72,7 @@ +@@ -80,7 +80,7 @@ [external] [external.apple] @@ -10,7 +10,7 @@ diff remote[auth] local[auth] client_id = "test-client-1,test-client-2" secret = "hash:ce62bb9bcced294fd4afe668f8ab3b50a89cf433093c526fffa3d0e46bf55252" url = "" -@@ -79,9 +79,9 @@ +@@ -87,9 +87,9 @@ redirect_uri = "" skip_nonce_check = false [external.azure] @@ -23,7 +23,7 @@ diff remote[auth] local[auth] url = "" redirect_uri = "" skip_nonce_check = false -@@ -128,7 +128,7 @@ +@@ -136,7 +136,7 @@ redirect_uri = "" skip_nonce_check = false [external.google] diff --git a/pkg/config/testdata/TestHookDiff/local_disabled_remote_enabled.diff b/pkg/config/testdata/TestHookDiff/local_disabled_remote_enabled.diff index ea7da07ef..b3cb9e1b7 100644 --- a/pkg/config/testdata/TestHookDiff/local_disabled_remote_enabled.diff +++ b/pkg/config/testdata/TestHookDiff/local_disabled_remote_enabled.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -12,19 +12,19 @@ +@@ -20,19 +20,19 @@ [hook] [hook.mfa_verification_attempt] diff --git a/pkg/config/testdata/TestHookDiff/local_enabled_remote_disabled.diff b/pkg/config/testdata/TestHookDiff/local_enabled_remote_disabled.diff index cabd1d757..b618fb667 100644 --- a/pkg/config/testdata/TestHookDiff/local_enabled_remote_disabled.diff +++ b/pkg/config/testdata/TestHookDiff/local_enabled_remote_disabled.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -12,20 +12,20 @@ +@@ -20,20 +20,20 @@ [hook] [hook.mfa_verification_attempt] diff --git a/pkg/config/testdata/TestMfaDiff/local_enabled_and_disabled.diff b/pkg/config/testdata/TestMfaDiff/local_enabled_and_disabled.diff index 6687ca2fb..dbb25a845 100644 --- a/pkg/config/testdata/TestMfaDiff/local_enabled_and_disabled.diff +++ b/pkg/config/testdata/TestMfaDiff/local_enabled_and_disabled.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -13,16 +13,16 @@ +@@ -21,16 +21,16 @@ [hook] [mfa] diff --git a/pkg/config/testdata/TestRateLimitsDiff/local_and_remote_rate_limits_differ.diff b/pkg/config/testdata/TestRateLimitsDiff/local_and_remote_rate_limits_differ.diff new file mode 100644 index 000000000..c403f9cbb --- /dev/null +++ b/pkg/config/testdata/TestRateLimitsDiff/local_and_remote_rate_limits_differ.diff @@ -0,0 +1,20 @@ +diff remote[auth] local[auth] +--- remote[auth] ++++ local[auth] +@@ -11,12 +11,12 @@ + password_requirements = "" + + [rate_limit] +-anonymous_users = 10 ++anonymous_users = 20 + token_refresh = 30 +-sign_in_sign_ups = 45 ++sign_in_sign_ups = 40 + token_verifications = 50 +-email_sent = 15 +-sms_sent = 55 ++email_sent = 25 ++sms_sent = 35 + + [hook] + diff --git a/pkg/config/testdata/TestSmsDiff/enable_sign_up_without_provider.diff b/pkg/config/testdata/TestSmsDiff/enable_sign_up_without_provider.diff index 2b0a59538..a9b5eb63b 100644 --- a/pkg/config/testdata/TestSmsDiff/enable_sign_up_without_provider.diff +++ b/pkg/config/testdata/TestSmsDiff/enable_sign_up_without_provider.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -41,7 +41,7 @@ +@@ -49,7 +49,7 @@ otp_expiry = 0 [sms] diff --git a/pkg/config/testdata/TestSmsDiff/local_disabled_remote_enabled.diff b/pkg/config/testdata/TestSmsDiff/local_disabled_remote_enabled.diff index 1504a0bf8..b1cf6e99d 100644 --- a/pkg/config/testdata/TestSmsDiff/local_disabled_remote_enabled.diff +++ b/pkg/config/testdata/TestSmsDiff/local_disabled_remote_enabled.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -41,12 +41,12 @@ +@@ -49,12 +49,12 @@ otp_expiry = 0 [sms] @@ -19,7 +19,7 @@ diff remote[auth] local[auth] account_sid = "" message_service_sid = "" auth_token = "" -@@ -69,8 +69,6 @@ +@@ -77,8 +77,6 @@ api_key = "" api_secret = "" [sms.test_otp] diff --git a/pkg/config/testdata/TestSmsDiff/local_enabled_remote_disabled.diff b/pkg/config/testdata/TestSmsDiff/local_enabled_remote_disabled.diff index 99f0d6131..e2853e76e 100644 --- a/pkg/config/testdata/TestSmsDiff/local_enabled_remote_disabled.diff +++ b/pkg/config/testdata/TestSmsDiff/local_enabled_remote_disabled.diff @@ -1,7 +1,7 @@ diff remote[auth] local[auth] --- remote[auth] +++ local[auth] -@@ -41,12 +41,12 @@ +@@ -49,12 +49,12 @@ otp_expiry = 0 [sms] @@ -19,7 +19,7 @@ diff remote[auth] local[auth] account_sid = "" message_service_sid = "" auth_token = "" -@@ -56,9 +56,9 @@ +@@ -64,9 +64,9 @@ message_service_sid = "" auth_token = "" [sms.messagebird] @@ -32,7 +32,7 @@ diff remote[auth] local[auth] [sms.textlocal] enabled = false sender = "" -@@ -69,6 +69,7 @@ +@@ -77,6 +77,7 @@ api_key = "" api_secret = "" [sms.test_otp] diff --git a/pkg/config/testdata/config.toml b/pkg/config/testdata/config.toml index c83baf088..5eb81c62b 100644 --- a/pkg/config/testdata/config.toml +++ b/pkg/config/testdata/config.toml @@ -127,6 +127,20 @@ minimum_password_length = 6 # are: `letters_digits`, `lower_upper_letters_digits`, `lower_upper_letters_digits_symbols` password_requirements = "" +[auth.rate_limit] +# Number of emails that can be sent per hour. Requires auth.email.smtp to be enabled. +email_sent = 2 +# Number of SMS messages that can be sent per hour. Requires auth.sms to be enabled. +sms_sent = 30 +# Number of anonymous sign-ins that can be made per hour per IP address. Requires enable_anonymous_sign_ins = true. +anonymous_users = 30 +# Number of sessions that can be refreshed in a 5 minute interval per IP address. +token_refresh = 150 +# Number of sign up and sign-in requests that can be made in a 5 minute interval per IP address (excludes anonymous users). +sign_in_sign_ups = 30 +# Number of OTP / Magic link verifications that can be made in a 5 minute interval per IP address. +token_verifications = 30 + # Configure one of the supported captcha providers: `hcaptcha`, `turnstile`. [auth.captcha] enabled = true From c84582c2356acb8c37c7a3494f960fce3d654288 Mon Sep 17 00:00:00 2001 From: Andrew Smith Date: Mon, 3 Mar 2025 09:34:54 +0000 Subject: [PATCH 28/54] feat: add mailpit image (#3121) * fix: add mailpit image * chore: replace inbucket image with mailpit * chore: update mailpit image --------- Co-authored-by: Han Qiao Co-authored-by: Qiao Han --- .github/dependabot.yml | 2 +- internal/start/start.go | 15 ++++++--------- pkg/config/constants.go | 2 +- pkg/config/templates/Dockerfile | 2 +- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c1c1005b8..172917207 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -18,6 +18,6 @@ updates: interval: "daily" ignore: - dependency-name: "library/kong" - - dependency-name: "inbucket/inbucket" + - dependency-name: "axllent/mailpit" - dependency-name: "darthsim/imgproxy" - dependency-name: "timberio/vector" diff --git a/internal/start/start.go b/internal/start/start.go index 0b9d079ce..ea8d2a886 100644 --- a/internal/start/start.go +++ b/internal/start/start.go @@ -526,7 +526,7 @@ EOF } else if utils.Config.Inbucket.Enabled { env = append(env, "GOTRUE_SMTP_HOST="+utils.InbucketId, - "GOTRUE_SMTP_PORT=2500", + "GOTRUE_SMTP_PORT=1025", fmt.Sprintf("GOTRUE_SMTP_ADMIN_EMAIL=%s", utils.Config.Inbucket.AdminEmail), fmt.Sprintf("GOTRUE_SMTP_SENDER_NAME=%s", utils.Config.Inbucket.SenderName), ) @@ -708,14 +708,14 @@ EOF started = append(started, utils.GotrueId) } - // Start Inbucket. + // Start Mailpit if utils.Config.Inbucket.Enabled && !isContainerExcluded(utils.Config.Inbucket.Image, excluded) { - inbucketPortBindings := nat.PortMap{"9000/tcp": []nat.PortBinding{{HostPort: strconv.FormatUint(uint64(utils.Config.Inbucket.Port), 10)}}} + inbucketPortBindings := nat.PortMap{"8025/tcp": []nat.PortBinding{{HostPort: strconv.FormatUint(uint64(utils.Config.Inbucket.Port), 10)}}} if utils.Config.Inbucket.SmtpPort != 0 { - inbucketPortBindings["2500/tcp"] = []nat.PortBinding{{HostPort: strconv.FormatUint(uint64(utils.Config.Inbucket.SmtpPort), 10)}} + inbucketPortBindings["1025/tcp"] = []nat.PortBinding{{HostPort: strconv.FormatUint(uint64(utils.Config.Inbucket.SmtpPort), 10)}} } if utils.Config.Inbucket.Pop3Port != 0 { - inbucketPortBindings["1100/tcp"] = []nat.PortBinding{{HostPort: strconv.FormatUint(uint64(utils.Config.Inbucket.Pop3Port), 10)}} + inbucketPortBindings["1110/tcp"] = []nat.PortBinding{{HostPort: strconv.FormatUint(uint64(utils.Config.Inbucket.Pop3Port), 10)}} } if _, err := utils.DockerStart( ctx, @@ -724,10 +724,7 @@ EOF }, container.HostConfig{ Binds: []string{ - // Override default mount points to avoid creating multiple anonymous volumes - // Ref: https://github.com/inbucket/inbucket/blob/v3.0.4/Dockerfile#L52 - utils.InbucketId + ":/config", - utils.InbucketId + ":/storage", + utils.InbucketId + ":/data", }, PortBindings: inbucketPortBindings, RestartPolicy: container.RestartPolicy{Name: "always"}, diff --git a/pkg/config/constants.go b/pkg/config/constants.go index b659ba6ff..8cee0c392 100644 --- a/pkg/config/constants.go +++ b/pkg/config/constants.go @@ -17,7 +17,7 @@ type images struct { Pg15 string `mapstructure:"pg15"` // Append to Services when adding new dependencies below Kong string `mapstructure:"kong"` - Inbucket string `mapstructure:"inbucket"` + Inbucket string `mapstructure:"mailpit"` Postgrest string `mapstructure:"postgrest"` Pgmeta string `mapstructure:"pgmeta"` Studio string `mapstructure:"studio"` diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 9275b5a01..1184f3cd1 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -2,7 +2,7 @@ FROM supabase/postgres:15.8.1.047 AS pg15 # Append to ServiceImages when adding new dependencies below FROM library/kong:2.8.1 AS kong -FROM inbucket/inbucket:3.0.3 AS inbucket +FROM axllent/mailpit:v1.22.3 AS mailpit FROM postgrest/postgrest:v12.2.8 AS postgrest FROM supabase/postgres-meta:v0.86.0 AS pgmeta FROM supabase/studio:20250224-d10db0f AS studio From d0c0076ab9d8e406dfc9b4c18d4246a3fbc358d0 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Mon, 3 Mar 2025 18:01:49 +0800 Subject: [PATCH 29/54] chore: remove unnecessary volume mount --- internal/start/start.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/start/start.go b/internal/start/start.go index ea8d2a886..7a00c1ddb 100644 --- a/internal/start/start.go +++ b/internal/start/start.go @@ -723,9 +723,6 @@ EOF Image: utils.Config.Inbucket.Image, }, container.HostConfig{ - Binds: []string{ - utils.InbucketId + ":/data", - }, PortBindings: inbucketPortBindings, RestartPolicy: container.RestartPolicy{Name: "always"}, }, From ef7ed6565d75b04a599818e8465ca219ceb66f1e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 18:31:35 +0800 Subject: [PATCH 30/54] chore(deps): bump supabase/logflare from 1.11.0 to 1.12.0 in /pkg/config/templates (#3238) chore(deps): bump supabase/logflare in /pkg/config/templates Bumps supabase/logflare from 1.11.0 to 1.12.0. --- updated-dependencies: - dependency-name: supabase/logflare dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 1184f3cd1..d218d6d36 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -13,7 +13,7 @@ FROM supabase/supavisor:2.3.10 AS supavisor FROM supabase/gotrue:v2.169.0 AS gotrue FROM supabase/realtime:v2.34.39 AS realtime FROM supabase/storage-api:v1.19.1 AS storage -FROM supabase/logflare:1.11.0 AS logflare +FROM supabase/logflare:1.12.0 AS logflare # Append to JobImages when adding new dependencies below FROM supabase/pgadmin-schema-diff:cli-0.0.5 AS differ FROM supabase/migra:3.0.1663481299 AS migra From 0ec16b882e948a4d784339726621ba086dfea7b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 20:39:03 +0800 Subject: [PATCH 31/54] chore(deps): bump github.com/docker/cli from 27.5.1+incompatible to 28.0.1+incompatible (#3218) * chore(deps): bump github.com/docker/cli Bumps [github.com/docker/cli](https://github.com/docker/cli) from 27.5.1+incompatible to 28.0.1+incompatible. - [Commits](https://github.com/docker/cli/compare/v27.5.1...v28.0.1) --- updated-dependencies: - dependency-name: github.com/docker/cli dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * chore: remove deprecated types * chore: update unit tests --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Qiao Han --- go.mod | 4 +- go.sum | 8 ++-- internal/db/branch/create/create_test.go | 6 +-- internal/db/branch/switch_/switch__test.go | 14 +++---- internal/db/diff/diff_test.go | 23 +++++------ internal/db/dump/dump_test.go | 2 +- internal/db/lint/lint_test.go | 4 +- internal/db/reset/reset_test.go | 33 ++++++++-------- internal/db/start/start_test.go | 25 ++++++------ internal/functions/serve/serve_test.go | 8 ++-- internal/gen/types/types_test.go | 8 ++-- internal/migration/squash/squash_test.go | 23 +++++------ internal/start/start_test.go | 46 ++++++++++++---------- internal/status/status_test.go | 18 +++++---- internal/stop/stop_test.go | 17 ++++---- internal/testing/apitest/docker.go | 17 ++++---- internal/utils/docker.go | 2 +- internal/utils/docker_test.go | 17 ++++---- 18 files changed, 144 insertions(+), 131 deletions(-) diff --git a/go.mod b/go.mod index 66788505c..24954516e 100644 --- a/go.mod +++ b/go.mod @@ -12,8 +12,8 @@ require ( github.com/charmbracelet/glamour v0.7.0 github.com/charmbracelet/lipgloss v0.12.1 github.com/containers/common v0.62.0 - github.com/docker/cli v27.5.1+incompatible - github.com/docker/docker v27.5.1+incompatible + github.com/docker/cli v28.0.1+incompatible + github.com/docker/docker v28.0.1+incompatible github.com/docker/go-connections v0.5.0 github.com/docker/go-units v0.5.0 github.com/ecies/go/v2 v2.0.10 diff --git a/go.sum b/go.sum index ade5b6e3d..41e307ed7 100644 --- a/go.sum +++ b/go.sum @@ -226,13 +226,13 @@ github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxK github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= -github.com/docker/cli v27.5.1+incompatible h1:JB9cieUT9YNiMITtIsguaN55PLOHhBSz3LKVc6cqWaY= -github.com/docker/cli v27.5.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v28.0.1+incompatible h1:g0h5NQNda3/CxIsaZfH4Tyf6vpxFth7PYl3hgCPOKzs= +github.com/docker/cli v28.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v27.5.1+incompatible h1:4PYU5dnBYqRQi0294d1FBECqT9ECWeQAIfE8q4YnPY8= -github.com/docker/docker v27.5.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v28.0.1+incompatible h1:FCHjSRdXhNRFjlHMTv4jUNlIBbTeRjrWfeFuJp7jpo0= +github.com/docker/docker v28.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= diff --git a/internal/db/branch/create/create_test.go b/internal/db/branch/create/create_test.go index 8e3842345..66b919ecb 100644 --- a/internal/db/branch/create/create_test.go +++ b/internal/db/branch/create/create_test.go @@ -5,7 +5,7 @@ import ( "net/http" "testing" - "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/h2non/gock" "github.com/spf13/afero" "github.com/stretchr/testify/assert" @@ -60,7 +60,7 @@ func TestBranchCreation(t *testing.T) { // Run test err := createBranch(context.Background(), "test-branch") // Validate api - assert.ErrorContains(t, err, "request returned Service Unavailable for API route and version") + assert.ErrorContains(t, err, "request returned 503 Service Unavailable for API route and version") assert.Empty(t, apitest.ListUnmatchedRequests()) }) @@ -71,7 +71,7 @@ func TestBranchCreation(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Post("/v" + utils.Docker.ClientVersion() + "/containers/" + utils.DbId + "/exec"). Reply(http.StatusCreated). - JSON(types.ContainerJSON{}) + JSON(container.InspectResponse{}) // Run test err := createBranch(context.Background(), "test-branch") // Validate api diff --git a/internal/db/branch/switch_/switch__test.go b/internal/db/branch/switch_/switch__test.go index 4e2e1055b..3eca45cd1 100644 --- a/internal/db/branch/switch_/switch__test.go +++ b/internal/db/branch/switch_/switch__test.go @@ -6,7 +6,7 @@ import ( "path/filepath" "testing" - "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/h2non/gock" "github.com/jackc/pgerrcode" "github.com/spf13/afero" @@ -34,7 +34,7 @@ func TestSwitchCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers"). Reply(http.StatusOK). - JSON(types.ContainerJSON{}) + JSON(container.InspectResponse{}) gock.New(utils.Docker.DaemonHost()). Post("/v" + utils.Docker.ClientVersion() + "/containers"). Reply(http.StatusServiceUnavailable) @@ -99,7 +99,7 @@ func TestSwitchCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers"). Reply(http.StatusOK). - JSON(types.ContainerJSON{}) + JSON(container.InspectResponse{}) // Run test err := Run(context.Background(), "postgres", fsys) // Check error @@ -117,7 +117,7 @@ func TestSwitchCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers"). Reply(http.StatusOK). - JSON(types.ContainerJSON{}) + JSON(container.InspectResponse{}) // Run test err := Run(context.Background(), "main", fsys) // Check error @@ -135,7 +135,7 @@ func TestSwitchCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers"). Reply(http.StatusOK). - JSON(types.ContainerJSON{}) + JSON(container.InspectResponse{}) // Setup target branch branch := "main" branchPath := filepath.Join(filepath.Dir(utils.CurrBranchPath), branch) @@ -159,7 +159,7 @@ func TestSwitchCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers"). Reply(http.StatusOK). - JSON(types.ContainerJSON{}) + JSON(container.InspectResponse{}) // Setup target branch branch := "target" branchPath := filepath.Join(filepath.Dir(utils.CurrBranchPath), branch) @@ -183,7 +183,7 @@ func TestSwitchCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers"). Reply(http.StatusOK). - JSON(types.ContainerJSON{}) + JSON(container.InspectResponse{}) // Setup target branch branch := "main" branchPath := filepath.Join(filepath.Dir(utils.CurrBranchPath), branch) diff --git a/internal/db/diff/diff_test.go b/internal/db/diff/diff_test.go index 20094d902..71b03223e 100644 --- a/internal/db/diff/diff_test.go +++ b/internal/db/diff/diff_test.go @@ -11,6 +11,7 @@ import ( "time" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/h2non/gock" "github.com/jackc/pgconn" "github.com/jackc/pgerrcode" @@ -51,10 +52,10 @@ func TestRun(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/test-shadow-db/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: true, - Health: &types.Health{Status: types.Healthy}, + Health: &container.Health{Status: types.Healthy}, }, }}) apitest.MockDockerStart(utils.Docker, utils.GetRegistryImageUrl(utils.Config.Realtime.Image), "test-shadow-realtime") @@ -218,8 +219,8 @@ func TestDiffDatabase(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/test-shadow-db/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: false, Status: "exited", }, @@ -248,10 +249,10 @@ func TestDiffDatabase(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/test-shadow-db/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: true, - Health: &types.Health{Status: types.Healthy}, + Health: &container.Health{Status: types.Healthy}, }, }}) gock.New(utils.Docker.DaemonHost()). @@ -285,10 +286,10 @@ create schema public`) gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/test-shadow-db/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: true, - Health: &types.Health{Status: types.Healthy}, + Health: &container.Health{Status: types.Healthy}, }, }}) gock.New(utils.Docker.DaemonHost()). diff --git a/internal/db/dump/dump_test.go b/internal/db/dump/dump_test.go index 3a7c3cc65..e8e4b2d1a 100644 --- a/internal/db/dump/dump_test.go +++ b/internal/db/dump/dump_test.go @@ -72,7 +72,7 @@ func TestPullCommand(t *testing.T) { // Run test err := Run(context.Background(), "", dbConfig, nil, nil, false, false, false, false, false, fsys) // Check error - assert.ErrorContains(t, err, "request returned Service Unavailable for API route and version") + assert.ErrorContains(t, err, "request returned 503 Service Unavailable for API route and version") assert.Empty(t, apitest.ListUnmatchedRequests()) }) diff --git a/internal/db/lint/lint_test.go b/internal/db/lint/lint_test.go index 8d7abef8f..e8f4bc9a0 100644 --- a/internal/db/lint/lint_test.go +++ b/internal/db/lint/lint_test.go @@ -7,7 +7,7 @@ import ( "net/http" "testing" - "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/h2non/gock" "github.com/jackc/pgconn" "github.com/jackc/pgerrcode" @@ -38,7 +38,7 @@ func TestLintCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers"). Reply(http.StatusOK). - JSON(types.ContainerJSON{}) + JSON(container.InspectResponse{}) // Setup db response expected := Result{ Function: "22751", diff --git a/internal/db/reset/reset_test.go b/internal/db/reset/reset_test.go index 4e3558be3..bb87bd912 100644 --- a/internal/db/reset/reset_test.go +++ b/internal/db/reset/reset_test.go @@ -10,6 +10,7 @@ import ( "time" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/h2non/gock" "github.com/jackc/pgconn" "github.com/jackc/pgerrcode" @@ -50,7 +51,7 @@ func TestResetCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/" + utils.DbId). Reply(http.StatusOK). - JSON(types.ContainerJSON{}) + JSON(container.InspectResponse{}) gock.New(utils.Docker.DaemonHost()). Delete("/v" + utils.Docker.ClientVersion() + "/containers/" + utils.DbId). Reply(http.StatusOK) @@ -61,10 +62,10 @@ func TestResetCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/" + utils.DbId + "/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: true, - Health: &types.Health{Status: types.Healthy}, + Health: &container.Health{Status: types.Healthy}, }, }}) // Setup mock postgres @@ -84,10 +85,10 @@ func TestResetCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/" + utils.StorageId + "/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: true, - Health: &types.Health{Status: types.Healthy}, + Health: &container.Health{Status: types.Healthy}, }, }}) gock.New(utils.Config.Api.ExternalUrl). @@ -147,7 +148,7 @@ func TestResetCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/" + utils.DbId). Reply(http.StatusOK). - JSON(types.ContainerJSON{}) + JSON(container.InspectResponse{}) gock.New(utils.Docker.DaemonHost()). Delete("/v" + utils.Docker.ClientVersion() + "/containers/" + utils.DbId). ReplyError(errors.New("network error")) @@ -298,10 +299,10 @@ func TestRestartDatabase(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/" + utils.DbId + "/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: true, - Health: &types.Health{Status: types.Healthy}, + Health: &container.Health{Status: types.Healthy}, }, }}) // Restarts services @@ -333,10 +334,10 @@ func TestRestartDatabase(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/" + utils.DbId + "/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: true, - Health: &types.Health{Status: types.Healthy}, + Health: &container.Health{Status: types.Healthy}, }, }}) // Restarts services @@ -389,8 +390,8 @@ func TestRestartDatabase(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/test-reset/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: false, Status: "exited", }, diff --git a/internal/db/start/start_test.go b/internal/db/start/start_test.go index fdc76c6ec..4cad4fb11 100644 --- a/internal/db/start/start_test.go +++ b/internal/db/start/start_test.go @@ -9,6 +9,7 @@ import ( "testing" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/volume" "github.com/h2non/gock" "github.com/spf13/afero" @@ -71,10 +72,10 @@ func TestStartDatabase(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/" + utils.DbId + "/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: true, - Health: &types.Health{Status: types.Healthy}, + Health: &container.Health{Status: types.Healthy}, }, }}) apitest.MockDockerStart(utils.Docker, utils.GetRegistryImageUrl(utils.Config.Realtime.Image), "test-realtime") @@ -117,10 +118,10 @@ func TestStartDatabase(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/" + utils.DbId + "/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: true, - Health: &types.Health{Status: types.Healthy}, + Health: &container.Health{Status: types.Healthy}, }, }}) // Run test @@ -147,11 +148,11 @@ func TestStartDatabase(t *testing.T) { ReplyError(errors.New("network error")) gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/images/" + utils.GetRegistryImageUrl(utils.Config.Db.Image) + "/json"). - Reply(http.StatusInternalServerError) + Reply(http.StatusServiceUnavailable) // Run test err := StartDatabase(context.Background(), "", fsys, io.Discard) // Check error - assert.ErrorContains(t, err, "request returned Internal Server Error for API route and version") + assert.ErrorContains(t, err, "request returned 503 Service Unavailable for API route and version") assert.Empty(t, apitest.ListUnmatchedRequests()) }) } @@ -194,7 +195,7 @@ func TestStartCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/"). Reply(http.StatusOK). - JSON(types.ContainerJSON{}) + JSON(container.InspectResponse{}) // Run test err := Run(context.Background(), "", fsys) // Check error @@ -333,10 +334,10 @@ func TestStartDatabaseWithCustomSettings(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/" + utils.DbId + "/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: true, - Health: &types.Health{Status: types.Healthy}, + Health: &container.Health{Status: types.Healthy}, }, }}) diff --git a/internal/functions/serve/serve_test.go b/internal/functions/serve/serve_test.go index 81c385bde..5f66d8e93 100644 --- a/internal/functions/serve/serve_test.go +++ b/internal/functions/serve/serve_test.go @@ -7,7 +7,7 @@ import ( "path/filepath" "testing" - "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/h2non/gock" "github.com/spf13/afero" "github.com/stretchr/testify/assert" @@ -30,7 +30,7 @@ func TestServeCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/supabase_db_test/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{}) + JSON(container.InspectResponse{}) containerId := "supabase_edge_runtime_test" gock.New(utils.Docker.DaemonHost()). Delete("/v" + utils.Docker.ClientVersion() + "/containers/" + containerId). @@ -80,7 +80,7 @@ func TestServeCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/supabase_db_test/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{}) + JSON(container.InspectResponse{}) // Run test err := Run(context.Background(), ".env", nil, "", RuntimeOption{}, fsys) // Check error @@ -100,7 +100,7 @@ func TestServeCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/supabase_db_test/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{}) + JSON(container.InspectResponse{}) // Run test err := Run(context.Background(), ".env", cast.Ptr(true), "import_map.json", RuntimeOption{}, fsys) // Check error diff --git a/internal/gen/types/types_test.go b/internal/gen/types/types_test.go index 811ae061d..bf7ee4067 100644 --- a/internal/gen/types/types_test.go +++ b/internal/gen/types/types_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/h2non/gock" "github.com/jackc/pgconn" "github.com/spf13/afero" @@ -41,7 +41,7 @@ func TestGenLocalCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/" + utils.DbId). Reply(http.StatusOK). - JSON(types.ContainerJSON{}) + JSON(container.InspectResponse{}) apitest.MockDockerStart(utils.Docker, imageUrl, containerId) require.NoError(t, apitest.MockDockerLogs(utils.Docker, containerId, "hello world\n")) // Setup mock postgres @@ -78,7 +78,7 @@ func TestGenLocalCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/" + utils.DbId). Reply(http.StatusOK). - JSON(types.ContainerJSON{}) + JSON(container.InspectResponse{}) gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/images"). Reply(http.StatusServiceUnavailable) @@ -99,7 +99,7 @@ func TestGenLocalCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/" + utils.DbId). Reply(http.StatusOK). - JSON(types.ContainerJSON{}) + JSON(container.InspectResponse{}) apitest.MockDockerStart(utils.Docker, imageUrl, containerId) require.NoError(t, apitest.MockDockerLogs(utils.Docker, containerId, "hello world\n")) // Setup mock postgres diff --git a/internal/migration/squash/squash_test.go b/internal/migration/squash/squash_test.go index b9092d980..bda678b0b 100644 --- a/internal/migration/squash/squash_test.go +++ b/internal/migration/squash/squash_test.go @@ -14,6 +14,7 @@ import ( "time" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/h2non/gock" "github.com/jackc/pgconn" "github.com/jackc/pgerrcode" @@ -59,10 +60,10 @@ func TestSquashCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/test-shadow-db/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: true, - Health: &types.Health{Status: types.Healthy}, + Health: &container.Health{Status: types.Healthy}, }, }}) gock.New(utils.Docker.DaemonHost()). @@ -219,8 +220,8 @@ func TestSquashMigrations(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/test-shadow-db/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: false, Status: "exited", }, @@ -249,10 +250,10 @@ func TestSquashMigrations(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/test-shadow-db/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: true, - Health: &types.Health{Status: types.Healthy}, + Health: &container.Health{Status: types.Healthy}, }, }}) gock.New(utils.Docker.DaemonHost()). @@ -284,10 +285,10 @@ func TestSquashMigrations(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/test-shadow-db/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: true, - Health: &types.Health{Status: types.Healthy}, + Health: &container.Health{Status: types.Healthy}, }, }}) gock.New(utils.Docker.DaemonHost()). diff --git a/internal/start/start_test.go b/internal/start/start_test.go index c00d2e92d..d52bc4590 100644 --- a/internal/start/start_test.go +++ b/internal/start/start_test.go @@ -9,6 +9,8 @@ import ( "testing" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/volume" "github.com/h2non/gock" @@ -52,9 +54,9 @@ func TestStartCommand(t *testing.T) { }) t.Run("show status if database is already running", func(t *testing.T) { - var running []types.Container + var running []container.Summary for _, name := range utils.GetDockerIds() { - running = append(running, types.Container{ + running = append(running, container.Summary{ Names: []string{name + "_test"}, }) } @@ -67,13 +69,15 @@ func TestStartCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers"). Reply(http.StatusOK). - JSON(types.ContainerJSON{}) + JSON(container.InspectResponse{}) gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/supabase_db_start/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{Running: true}, + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ + Running: true, + }, }}) gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/json"). @@ -103,13 +107,13 @@ func TestDatabaseStart(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/images/" + imageUrl + "/json"). Reply(http.StatusOK). - JSON(types.ImageInspect{}) - for _, image := range config.Images.Services() { - service := utils.GetRegistryImageUrl(image) + JSON(image.InspectResponse{}) + for _, img := range config.Images.Services() { + service := utils.GetRegistryImageUrl(img) gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/images/" + service + "/json"). Reply(http.StatusOK). - JSON(types.ImageInspect{}) + JSON(image.InspectResponse{}) } // Start postgres utils.DbId = "test-postgres" @@ -164,14 +168,14 @@ func TestDatabaseStart(t *testing.T) { utils.StorageId, utils.ImgProxyId, utils.EdgeRuntimeId, utils.PgmetaId, utils.StudioId, utils.LogflareId, utils.RestId, utils.VectorId, } - for _, container := range started { + for _, c := range started { gock.New(utils.Docker.DaemonHost()). - Get("/v" + utils.Docker.ClientVersion() + "/containers/" + container + "/json"). + Get("/v" + utils.Docker.ClientVersion() + "/containers/" + c + "/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: true, - Health: &types.Health{Status: types.Healthy}, + Health: &container.Health{Status: types.Healthy}, }, }}) } @@ -185,10 +189,10 @@ func TestDatabaseStart(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/" + utils.StorageId + "/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: true, - Health: &types.Health{Status: types.Healthy}, + Health: &container.Health{Status: types.Healthy}, }, }}) gock.New(utils.Config.Api.ExternalUrl). @@ -219,7 +223,7 @@ func TestDatabaseStart(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/images/" + imageUrl + "/json"). Reply(http.StatusOK). - JSON(types.ImageInspect{}) + JSON(image.InspectResponse{}) // Start postgres utils.DbId = "test-postgres" utils.ConfigId = "test-config" @@ -233,10 +237,10 @@ func TestDatabaseStart(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/" + utils.DbId + "/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ Running: true, - Health: &types.Health{Status: types.Healthy}, + Health: &container.Health{Status: types.Healthy}, }, }}) // Run test diff --git a/internal/status/status_test.go b/internal/status/status_test.go index 01dd1e73b..c7bfc1bc4 100644 --- a/internal/status/status_test.go +++ b/internal/status/status_test.go @@ -7,7 +7,7 @@ import ( "net/http" "testing" - "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/h2non/gock" "github.com/spf13/afero" "github.com/stretchr/testify/assert" @@ -18,9 +18,9 @@ import ( func TestStatusCommand(t *testing.T) { t.Run("shows service status", func(t *testing.T) { - var running []types.Container + var running []container.Summary for _, name := range utils.GetDockerIds() { - running = append(running, types.Container{ + running = append(running, container.Summary{ Names: []string{name + "_test"}, }) } @@ -33,8 +33,10 @@ func TestStatusCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/supabase_db_test/json"). Reply(http.StatusOK). - JSON(types.ContainerJSON{ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{Running: true}, + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ + Running: true, + }, }}) gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/json"). @@ -76,9 +78,9 @@ func TestStatusCommand(t *testing.T) { func TestServiceHealth(t *testing.T) { t.Run("checks all services", func(t *testing.T) { - var running []types.Container + var running []container.Summary for _, name := range utils.GetDockerIds() { - running = append(running, types.Container{ + running = append(running, container.Summary{ Names: []string{"/" + name}, }) } @@ -104,7 +106,7 @@ func TestServiceHealth(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/json"). Reply(http.StatusOK). - JSON([]types.Container{}) + JSON([]container.Summary{}) // Run test stopped, err := checkServiceHealth(context.Background()) // Check error diff --git a/internal/stop/stop_test.go b/internal/stop/stop_test.go index 81fad5dee..d260143df 100644 --- a/internal/stop/stop_test.go +++ b/internal/stop/stop_test.go @@ -8,7 +8,6 @@ import ( "net/http" "testing" - "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/volume" @@ -32,7 +31,7 @@ func TestStopCommand(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/json"). Reply(http.StatusOK). - JSON([]types.Container{}) + JSON([]container.Summary{}) gock.New(utils.Docker.DaemonHost()). Post("/v" + utils.Docker.ClientVersion() + "/containers/prune"). Reply(http.StatusOK). @@ -69,7 +68,7 @@ func TestStopCommand(t *testing.T) { Get("/v"+utils.Docker.ClientVersion()+"/containers/json"). MatchParam("all", "true"). Reply(http.StatusOK). - JSON([]types.Container{ + JSON([]container.Summary{ {ID: "container1", Labels: map[string]string{utils.CliProjectLabel: "project1"}}, {ID: "container2", Labels: map[string]string{utils.CliProjectLabel: "project2"}}, }) @@ -93,7 +92,7 @@ func TestStopCommand(t *testing.T) { MatchParam("all", "1"). MatchParam("filters", fmt.Sprintf(`{"label":{"com.supabase.cli.project=%s":true}}`, projectId)). Reply(http.StatusOK). - JSON([]types.Container{{ID: "container-" + projectId, State: "running"}}) + JSON([]container.Summary{{ID: "container-" + projectId, State: "running"}}) // Mock container stop gock.New(utils.Docker.DaemonHost()). @@ -120,11 +119,11 @@ func TestStopCommand(t *testing.T) { Get("/v"+utils.Docker.ClientVersion()+"/containers/json"). MatchParam("all", "true"). Reply(http.StatusOK). - JSON([]types.Container{}) + JSON([]container.Summary{}) gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/json"). Reply(http.StatusOK). - JSON([]types.Container{}) + JSON([]container.Summary{}) // Run test err := Run(context.Background(), true, "", true, fsys) @@ -157,14 +156,14 @@ func TestStopCommand(t *testing.T) { // Run test err := Run(context.Background(), false, "test", false, afero.NewReadOnlyFs(fsys)) // Check error - assert.ErrorContains(t, err, "request returned Service Unavailable for API route and version") + assert.ErrorContains(t, err, "request returned 503 Service Unavailable for API route and version") assert.Empty(t, apitest.ListUnmatchedRequests()) }) } func TestStopServices(t *testing.T) { t.Run("stops all services", func(t *testing.T) { - containers := []types.Container{{ID: "c1", State: "running"}, {ID: "c2"}} + containers := []container.Summary{{ID: "c1", State: "running"}, {ID: "c2"}} // Setup mock docker require.NoError(t, apitest.MockDocker(utils.Docker)) defer gock.OffAll() @@ -232,7 +231,7 @@ func TestStopServices(t *testing.T) { gock.New(utils.Docker.DaemonHost()). Get("/v" + utils.Docker.ClientVersion() + "/containers/json"). Reply(http.StatusOK). - JSON([]types.Container{}) + JSON([]container.Summary{}) gock.New(utils.Docker.DaemonHost()). Post("/v" + utils.Docker.ClientVersion() + "/containers/prune"). ReplyError(errors.New("network error")) diff --git a/internal/testing/apitest/docker.go b/internal/testing/apitest/docker.go index 556756dfd..17a14355d 100644 --- a/internal/testing/apitest/docker.go +++ b/internal/testing/apitest/docker.go @@ -6,8 +6,8 @@ import ( "net/http" "github.com/docker/docker/api" - "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/volume" @@ -33,11 +33,11 @@ func MockDocker(docker *client.Client) error { } // Ref: internal/utils/docker.go::DockerStart -func MockDockerStart(docker *client.Client, image, containerID string) { +func MockDockerStart(docker *client.Client, imageID, containerID string) { gock.New(docker.DaemonHost()). - Get("/v" + docker.ClientVersion() + "/images/" + image + "/json"). + Get("/v" + docker.ClientVersion() + "/images/" + imageID + "/json"). Reply(http.StatusOK). - JSON(types.ImageInspect{}) + JSON(image.InspectResponse{}) gock.New(docker.DaemonHost()). Post("/v" + docker.ClientVersion() + "/networks/create"). Reply(http.StatusCreated). @@ -61,7 +61,7 @@ func MockDockerStop(docker *client.Client) { gock.New(docker.DaemonHost()). Get("/v" + docker.ClientVersion() + "/containers/json"). Reply(http.StatusOK). - JSON([]types.Container{}) + JSON([]container.Summary{}) gock.New(docker.DaemonHost()). Post("/v" + docker.ClientVersion() + "/containers/prune"). Reply(http.StatusOK). @@ -95,9 +95,10 @@ func setupDockerLogs(docker *client.Client, containerID, stdout string, exitCode gock.New(docker.DaemonHost()). Get("/v" + docker.ClientVersion() + "/containers/" + containerID + "/json"). Reply(http.StatusOK). - JSON(types.ContainerJSONBase{State: &types.ContainerState{ - ExitCode: exitCode, - }}) + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ + ExitCode: exitCode, + }}}) gock.New(docker.DaemonHost()). Delete("/v" + docker.ClientVersion() + "/containers/" + containerID). Reply(http.StatusOK) diff --git a/internal/utils/docker.go b/internal/utils/docker.go index 84911d07f..792ffb3db 100644 --- a/internal/utils/docker.go +++ b/internal/utils/docker.go @@ -239,7 +239,7 @@ func DockerImagePullWithRetry(ctx context.Context, image string, retries int) er func DockerPullImageIfNotCached(ctx context.Context, imageName string) error { imageUrl := GetRegistryImageUrl(imageName) - if _, _, err := Docker.ImageInspectWithRaw(ctx, imageUrl); err == nil { + if _, err := Docker.ImageInspect(ctx, imageUrl); err == nil { return nil } else if !client.IsErrNotFound(err) { return errors.Errorf("failed to inspect docker image: %w", err) diff --git a/internal/utils/docker_test.go b/internal/utils/docker_test.go index 6a0cdf034..069204559 100644 --- a/internal/utils/docker_test.go +++ b/internal/utils/docker_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/network" "github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/pkg/stdcopy" @@ -52,7 +52,7 @@ func TestPullImage(t *testing.T) { gock.New(Docker.DaemonHost()). Get("/v" + Docker.ClientVersion() + "/images/" + imageId + "/json"). Reply(http.StatusOK). - JSON(types.ImageInspect{}) + JSON(image.InspectResponse{}) // Run test assert.NoError(t, DockerPullImageIfNotCached(context.Background(), imageId)) // Validate api @@ -130,7 +130,7 @@ func TestRunOnce(t *testing.T) { gock.New(Docker.DaemonHost()). Get("/v" + Docker.ClientVersion() + "/images/" + imageId + "/json"). Reply(http.StatusOK). - JSON(types.ImageInspect{}) + JSON(image.InspectResponse{}) gock.New(Docker.DaemonHost()). Post("/v" + Docker.ClientVersion() + "/networks/create"). Reply(http.StatusCreated). @@ -152,7 +152,7 @@ func TestRunOnce(t *testing.T) { gock.New(Docker.DaemonHost()). Get("/v" + Docker.ClientVersion() + "/images/" + imageId + "/json"). Reply(http.StatusOK). - JSON(types.ImageInspect{}) + JSON(image.InspectResponse{}) gock.New(Docker.DaemonHost()). Post("/v" + Docker.ClientVersion() + "/networks/create"). Reply(http.StatusCreated). @@ -236,7 +236,7 @@ func TestRunOnce(t *testing.T) { Reply(http.StatusOK) // Run test _, err = DockerRunOnce(context.Background(), imageId, nil, nil) - assert.ErrorContains(t, err, "request returned Service Unavailable for API route and version") + assert.ErrorContains(t, err, "request returned 503 Service Unavailable for API route and version") // Validate api assert.Empty(t, apitest.ListUnmatchedRequests()) }) @@ -259,7 +259,10 @@ func TestRunOnce(t *testing.T) { gock.New("http:///var/run/docker.sock"). Get("/v" + Docker.ClientVersion() + "/containers/" + containerId + "/json"). Reply(http.StatusOK). - JSON(types.ContainerJSONBase{State: &types.ContainerState{ExitCode: 1}}) + JSON(container.InspectResponse{ContainerJSONBase: &container.ContainerJSONBase{ + State: &container.State{ + ExitCode: 1, + }}}) gock.New(Docker.DaemonHost()). Delete("/v" + Docker.ClientVersion() + "/containers/" + containerId). Reply(http.StatusOK) @@ -293,7 +296,7 @@ func TestExecOnce(t *testing.T) { gock.New(Docker.DaemonHost()). Post("/v" + Docker.ClientVersion() + "/containers/" + containerId + "/exec"). Reply(http.StatusAccepted). - JSON(types.IDResponse{ID: "test-command"}) + JSON(container.ExecCreateResponse{ID: "test-command"}) // Run test _, err := DockerExecOnce(context.Background(), containerId, nil, nil) assert.Error(t, err) From 22e97a142bf7e6241d886ea0e9f1a71d6d88ac23 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Tue, 4 Mar 2025 00:44:23 +0800 Subject: [PATCH 32/54] fix: update docker client version From 8256c5758b73de07c2eee746619b882865ce9a64 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 04:10:52 +0000 Subject: [PATCH 33/54] chore(deps): bump github.com/containers/common from 0.62.0 to 0.62.1 (#3245) Bumps [github.com/containers/common](https://github.com/containers/common) from 0.62.0 to 0.62.1. - [Release notes](https://github.com/containers/common/releases) - [Commits](https://github.com/containers/common/compare/v0.62.0...v0.62.1) --- updated-dependencies: - dependency-name: github.com/containers/common dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 24954516e..b72e438ba 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/charmbracelet/bubbletea v0.25.0 github.com/charmbracelet/glamour v0.7.0 github.com/charmbracelet/lipgloss v0.12.1 - github.com/containers/common v0.62.0 + github.com/containers/common v0.62.1 github.com/docker/cli v28.0.1+incompatible github.com/docker/docker v28.0.1+incompatible github.com/docker/go-connections v0.5.0 diff --git a/go.sum b/go.sum index 41e307ed7..41ccbaaf7 100644 --- a/go.sum +++ b/go.sum @@ -192,8 +192,8 @@ github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2 github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/containers/common v0.62.0 h1:Sl9WE5h7Y/F3bejrMAA4teP1EcY9ygqJmW4iwSloZ10= -github.com/containers/common v0.62.0/go.mod h1:Yec+z8mrSq4rydHofrnDCBqAcNA/BGrSg1kfFUL6F6s= +github.com/containers/common v0.62.1 h1:durvu7Kelb8PYgX7bwuAg/d5LKj2hs3cAaqcU7Vnqus= +github.com/containers/common v0.62.1/go.mod h1:n9cEboBmY3AnTk1alkq4t7sLM4plwkDCiaWbsf67YxE= github.com/containers/storage v1.57.1 h1:hKPoFsuBcB3qTzBxa4IFpZMRzUuL5Xhv/BE44W0XHx8= github.com/containers/storage v1.57.1/go.mod h1:i/Hb4lu7YgFr9G0K6BMjqW0BLJO1sFsnWQwj2UoWCUM= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= From b4794cbabfbbf953e68af9622ad985f40d9d554e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Mar 2025 04:33:18 +0000 Subject: [PATCH 34/54] chore(deps): bump google.golang.org/grpc from 1.70.0 to 1.71.0 (#3249) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.70.0 to 1.71.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.70.0...v1.71.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b72e438ba..a3a038df6 100644 --- a/go.mod +++ b/go.mod @@ -52,7 +52,7 @@ require ( golang.org/x/mod v0.23.0 golang.org/x/oauth2 v0.27.0 golang.org/x/term v0.29.0 - google.golang.org/grpc v1.70.0 + google.golang.org/grpc v1.71.0 gopkg.in/yaml.v3 v3.0.1 gotest.tools/gotestsum v1.12.0 ) diff --git a/go.sum b/go.sum index 41ccbaaf7..7c6377105 100644 --- a/go.sum +++ b/go.sum @@ -1490,8 +1490,8 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= -google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= +google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= +google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= From eab3af881c0d591102a74fe22415ec1de2177fd3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Mar 2025 05:16:54 +0000 Subject: [PATCH 35/54] chore(deps): bump supabase/supavisor from 2.3.10 to 2.4.6 in /pkg/config/templates (#3250) chore(deps): bump supabase/supavisor in /pkg/config/templates Bumps supabase/supavisor from 2.3.10 to 2.4.6. --- updated-dependencies: - dependency-name: supabase/supavisor dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index d218d6d36..f45868ecf 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -9,7 +9,7 @@ FROM supabase/studio:20250224-d10db0f AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy FROM supabase/edge-runtime:v1.67.2 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector -FROM supabase/supavisor:2.3.10 AS supavisor +FROM supabase/supavisor:2.4.6 AS supavisor FROM supabase/gotrue:v2.169.0 AS gotrue FROM supabase/realtime:v2.34.39 AS realtime FROM supabase/storage-api:v1.19.1 AS storage From 266ec80dc323169ab00f52bada9847a1f124f6e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Mar 2025 05:21:42 +0000 Subject: [PATCH 36/54] chore(deps): bump supabase/postgres-meta from v0.86.0 to v0.86.1 in /pkg/config/templates (#3251) chore(deps): bump supabase/postgres-meta in /pkg/config/templates Bumps supabase/postgres-meta from v0.86.0 to v0.86.1. --- updated-dependencies: - dependency-name: supabase/postgres-meta dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index f45868ecf..f719800d2 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -4,7 +4,7 @@ FROM supabase/postgres:15.8.1.047 AS pg15 FROM library/kong:2.8.1 AS kong FROM axllent/mailpit:v1.22.3 AS mailpit FROM postgrest/postgrest:v12.2.8 AS postgrest -FROM supabase/postgres-meta:v0.86.0 AS pgmeta +FROM supabase/postgres-meta:v0.86.1 AS pgmeta FROM supabase/studio:20250224-d10db0f AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy FROM supabase/edge-runtime:v1.67.2 AS edgeruntime From a890d777099fda43178076691eb3bad2a7aa302a Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Wed, 5 Mar 2025 15:18:40 +0800 Subject: [PATCH 37/54] feat: support setting function secrets from config (#3246) * feat: support setting function secrets from config * chore: add secrets to functions serve * chore: convert secret keys to upper case --- internal/functions/new/new.go | 2 +- internal/functions/serve/serve.go | 42 +++++++------------- internal/secrets/set/set.go | 64 ++++++++++++++++++------------- pkg/config/config.go | 10 +++++ pkg/config/templates/config.toml | 3 ++ pkg/config/testdata/config.toml | 3 ++ 6 files changed, 69 insertions(+), 55 deletions(-) diff --git a/internal/functions/new/new.go b/internal/functions/new/new.go index f41097cfd..877928c84 100644 --- a/internal/functions/new/new.go +++ b/internal/functions/new/new.go @@ -45,7 +45,7 @@ func Run(ctx context.Context, slug string, fsys afero.Fs) error { } // Load config if available if err := flags.LoadConfig(fsys); err != nil { - utils.CmdSuggestion = "" + fmt.Fprintln(utils.GetDebugLogger(), err) } if err := createEntrypointFile(slug, fsys); err != nil { return err diff --git a/internal/functions/serve/serve.go b/internal/functions/serve/serve.go index 978cb9e70..f46c1af2f 100644 --- a/internal/functions/serve/serve.go +++ b/internal/functions/serve/serve.go @@ -6,7 +6,6 @@ import ( "encoding/json" "fmt" "os" - "path/filepath" "strconv" "strings" @@ -97,15 +96,7 @@ func Run(ctx context.Context, envFilePath string, noVerifyJWT *bool, importMapPa } func ServeFunctions(ctx context.Context, envFilePath string, noVerifyJWT *bool, importMapPath string, dbUrl string, runtimeOption RuntimeOption, fsys afero.Fs) error { - // 1. Load default values - if envFilePath == "" { - if f, err := fsys.Stat(utils.FallbackEnvFilePath); err == nil && !f.IsDir() { - envFilePath = utils.FallbackEnvFilePath - } - } else if !filepath.IsAbs(envFilePath) { - envFilePath = filepath.Join(utils.CurrentDirAbs, envFilePath) - } - // 2. Parse user defined env + // 1. Parse custom env file env, err := parseEnvFile(envFilePath, fsys) if err != nil { return err @@ -124,7 +115,7 @@ func ServeFunctions(ctx context.Context, envFilePath string, noVerifyJWT *bool, if runtimeOption.InspectMode != nil { env = append(env, "SUPABASE_INTERNAL_WALLCLOCK_LIMIT_SEC=0") } - // 3. Parse custom import map + // 2. Parse custom import map cwd, err := os.Getwd() if err != nil { return errors.Errorf("failed to get working directory: %w", err) @@ -134,7 +125,7 @@ func ServeFunctions(ctx context.Context, envFilePath string, noVerifyJWT *bool, return err } env = append(env, "SUPABASE_INTERNAL_FUNCTIONS_CONFIG="+functionsConfigString) - // 4. Parse entrypoint script + // 3. Parse entrypoint script cmd := append([]string{ "edge-runtime", "start", @@ -150,7 +141,7 @@ func ServeFunctions(ctx context.Context, envFilePath string, noVerifyJWT *bool, ` + mainFuncEmbed + ` EOF `} - // 5. Parse exposed ports + // 4. Parse exposed ports dockerRuntimePort := nat.Port(fmt.Sprintf("%d/tcp", dockerRuntimeServerPort)) exposedPorts := nat.PortSet{dockerRuntimePort: struct{}{}} portBindings := nat.PortMap{} @@ -161,7 +152,7 @@ EOF HostPort: strconv.FormatUint(uint64(utils.Config.EdgeRuntime.InspectorPort), 10), }} } - // 6. Start container + // 5. Start container _, err = utils.DockerStart( ctx, container.Config{ @@ -189,22 +180,17 @@ EOF } func parseEnvFile(envFilePath string, fsys afero.Fs) ([]string, error) { - env := []string{} - if len(envFilePath) == 0 { - return env, nil - } - envMap, err := set.ParseEnvFile(envFilePath, fsys) - if err != nil { - return env, err - } - for name, value := range envMap { - if strings.HasPrefix(name, "SUPABASE_") { - fmt.Fprintln(os.Stderr, "Env name cannot start with SUPABASE_, skipping: "+name) - continue + if envFilePath == "" { + if f, err := fsys.Stat(utils.FallbackEnvFilePath); err == nil && !f.IsDir() { + envFilePath = utils.FallbackEnvFilePath } - env = append(env, name+"="+value) } - return env, nil + env := []string{} + secrets, err := set.ListSecrets(envFilePath, fsys) + for _, v := range secrets { + env = append(env, fmt.Sprintf("%s=%s", v.Name, v.Value)) + } + return env, err } func populatePerFunctionConfigs(cwd, importMapPath string, noVerifyJWT *bool, fsys afero.Fs) ([]string, string, error) { diff --git a/internal/secrets/set/set.go b/internal/secrets/set/set.go index d2877c314..de758e5e2 100644 --- a/internal/secrets/set/set.go +++ b/internal/secrets/set/set.go @@ -13,61 +13,73 @@ import ( "github.com/joho/godotenv" "github.com/spf13/afero" "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/flags" "github.com/supabase/cli/pkg/api" ) func Run(ctx context.Context, projectRef, envFilePath string, args []string, fsys afero.Fs) error { // 1. Sanity checks. - envMap := make(map[string]string, len(args)) + if err := flags.LoadConfig(fsys); err != nil { + fmt.Fprintln(utils.GetDebugLogger(), err) + } + secrets, err := ListSecrets(envFilePath, fsys, args...) + if err != nil { + return err + } + if len(secrets) == 0 { + return errors.New("No arguments found. Use --env-file to read from a .env file.") + } + // 2. Set secret(s). + resp, err := utils.GetSupabase().V1BulkCreateSecretsWithResponse(ctx, projectRef, secrets) + if err != nil { + return errors.Errorf("failed to set secrets: %w", err) + } else if resp.StatusCode() != http.StatusCreated { + return errors.New("Unexpected error setting project secrets: " + string(resp.Body)) + } + fmt.Println("Finished " + utils.Aqua("supabase secrets set") + ".") + return nil +} + +func ListSecrets(envFilePath string, fsys afero.Fs, envArgs ...string) ([]api.CreateSecretBody, error) { + envMap := map[string]string{} + for name, secret := range utils.Config.EdgeRuntime.Secrets { + if len(secret.SHA256) > 0 { + envMap[name] = secret.Value + } + } if len(envFilePath) > 0 { if !filepath.IsAbs(envFilePath) { envFilePath = filepath.Join(utils.CurrentDirAbs, envFilePath) } - parsed, err := ParseEnvFile(envFilePath, fsys) + parsed, err := parseEnvFile(envFilePath, fsys) if err != nil { - return err + return nil, err } maps.Copy(envMap, parsed) } - for _, pair := range args { + for _, pair := range envArgs { name, value, found := strings.Cut(pair, "=") if !found { - return errors.Errorf("Invalid secret pair: %s. Must be NAME=VALUE.", pair) + return nil, errors.Errorf("Invalid secret pair: %s. Must be NAME=VALUE.", pair) } envMap[name] = value } - if len(envMap) == 0 { - return errors.New("No arguments found. Use --env-file to read from a .env file.") - } - // 2. Set secret(s). - var secrets api.V1BulkCreateSecretsJSONBody + var result []api.CreateSecretBody for name, value := range envMap { // Lower case prefix is accepted by API if strings.HasPrefix(name, "SUPABASE_") { fmt.Fprintln(os.Stderr, "Env name cannot start with SUPABASE_, skipping: "+name) continue } - secret := api.CreateSecretBody{ + result = append(result, api.CreateSecretBody{ Name: name, Value: value, - } - secrets = append(secrets, secret) - } - - resp, err := utils.GetSupabase().V1BulkCreateSecretsWithResponse(ctx, projectRef, secrets) - if err != nil { - return errors.Errorf("failed to set secrets: %w", err) - } - - if resp.StatusCode() != http.StatusCreated { - return errors.New("Unexpected error setting project secrets: " + string(resp.Body)) + }) } - - fmt.Println("Finished " + utils.Aqua("supabase secrets set") + ".") - return nil + return result, nil } -func ParseEnvFile(envFilePath string, fsys afero.Fs) (map[string]string, error) { +func parseEnvFile(envFilePath string, fsys afero.Fs) (map[string]string, error) { f, err := fsys.Open(envFilePath) if err != nil { return nil, errors.Errorf("failed to open env file: %w", err) diff --git a/pkg/config/config.go b/pkg/config/config.go index 9e78299d0..23cb79714 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -224,8 +224,10 @@ type ( Image string `toml:"-"` Policy RequestPolicy `toml:"policy"` InspectorPort uint16 `toml:"inspector_port"` + Secrets SecretsConfig `toml:"secrets"` } + SecretsConfig map[string]Secret FunctionConfig map[string]function function struct { @@ -312,7 +314,9 @@ func (s *storage) Clone() storage { func (c *baseConfig) Clone() baseConfig { copy := *c + copy.Db.Vault = maps.Clone(c.Db.Vault) copy.Storage = c.Storage.Clone() + copy.EdgeRuntime.Secrets = maps.Clone(c.EdgeRuntime.Secrets) copy.Functions = maps.Clone(c.Functions) copy.Auth = c.Auth.Clone() if c.Experimental.Webhooks != nil { @@ -506,6 +510,12 @@ func (c *config) loadFromReader(v *viper.Viper, r io.Reader) error { }); err != nil { return errors.Errorf("failed to parse config: %w", err) } + // Convert keys to upper case: https://github.com/spf13/viper/issues/1014 + secrets := make(SecretsConfig, len(c.EdgeRuntime.Secrets)) + for k, v := range c.EdgeRuntime.Secrets { + secrets[strings.ToUpper(k)] = v + } + c.EdgeRuntime.Secrets = secrets return nil } diff --git a/pkg/config/templates/config.toml b/pkg/config/templates/config.toml index 77d854ab0..e1bce3814 100644 --- a/pkg/config/templates/config.toml +++ b/pkg/config/templates/config.toml @@ -278,6 +278,9 @@ policy = "oneshot" # Port to attach the Chrome inspector for debugging edge functions. inspector_port = 8083 +# [edge_runtime.secrets] +# secret_key = "env(SECRET_VALUE)" + [analytics] enabled = true port = 54327 diff --git a/pkg/config/testdata/config.toml b/pkg/config/testdata/config.toml index 5eb81c62b..bae13a5bd 100644 --- a/pkg/config/testdata/config.toml +++ b/pkg/config/testdata/config.toml @@ -260,6 +260,9 @@ enabled = true policy = "per_worker" inspector_port = 8083 +[edge_runtime.secrets] +test_key = "test_value" + [analytics] enabled = true port = 54327 From 468ce0f6e51e2e4feb8363c873059c5ae428421c Mon Sep 17 00:00:00 2001 From: Stojan Dimitrovski Date: Wed, 5 Mar 2025 08:23:17 +0100 Subject: [PATCH 38/54] feat: add clerk third-party auth config (#3247) * feat: add clerk third-party auth config * Update pkg/config/templates/config.toml --------- Co-authored-by: Han Qiao --- pkg/config/auth.go | 7 +++++++ pkg/config/config.go | 32 ++++++++++++++++++++++++++++++++ pkg/config/templates/config.toml | 5 +++++ 3 files changed, 44 insertions(+) diff --git a/pkg/config/auth.go b/pkg/config/auth.go index 4b5cd546d..dcbd0f197 100644 --- a/pkg/config/auth.go +++ b/pkg/config/auth.go @@ -106,6 +106,7 @@ type ( Firebase tpaFirebase `toml:"firebase"` Auth0 tpaAuth0 `toml:"auth0"` Cognito tpaCognito `toml:"aws_cognito"` + Clerk tpaClerk `toml:"clerk"` } rateLimit struct { @@ -137,6 +138,12 @@ type ( UserPoolRegion string `toml:"user_pool_region"` } + tpaClerk struct { + Enabled bool `toml:"enabled"` + + Domain string `toml:"domain"` + } + email struct { EnableSignup bool `toml:"enable_signup"` DoubleConfirmChanges bool `toml:"double_confirm_changes"` diff --git a/pkg/config/config.go b/pkg/config/config.go index 23cb79714..13fc9f6d2 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -1209,6 +1209,26 @@ func (c *tpaCognito) validate() (err error) { return nil } +var clerkDomainPattern = regexp.MustCompile("^(clerk([.][a-z0-9-]+){2,}|([a-z0-9-][.])+clerk[.]accounts[.]dev)$") + +func (c *tpaClerk) issuerURL() string { + return fmt.Sprintf("https://%s", c.Domain) +} + +func (c *tpaClerk) validate() (err error) { + if c.Domain == "" { + return errors.New("Invalid config: auth.third_party.clerk is enabled but without a domain.") + } else if err := assertEnvLoaded(c.Domain); err != nil { + return err + } + + if !clerkDomainPattern.MatchString(c.Domain) { + return errors.New("Invalid config: auth.third_party.clerk has invalid domain, it usually is like clerk.example.com or example.clerk.accounts.dev") + } + + return nil +} + func (tpa *thirdParty) validate() error { enabled := 0 @@ -1236,6 +1256,14 @@ func (tpa *thirdParty) validate() error { } } + if tpa.Clerk.Enabled { + enabled += 1 + + if err := tpa.Clerk.validate(); err != nil { + return err + } + } + if enabled > 1 { return errors.New("Invalid config: Only one third_party provider allowed to be enabled at a time.") } @@ -1256,6 +1284,10 @@ func (tpa *thirdParty) IssuerURL() string { return tpa.Cognito.issuerURL() } + if tpa.Clerk.Enabled { + return tpa.Clerk.issuerURL() + } + return "" } diff --git a/pkg/config/templates/config.toml b/pkg/config/templates/config.toml index e1bce3814..e28bd0191 100644 --- a/pkg/config/templates/config.toml +++ b/pkg/config/templates/config.toml @@ -270,6 +270,11 @@ enabled = false # user_pool_id = "my-user-pool-id" # user_pool_region = "us-east-1" +# Use Clerk as a third-party provider alongside Supabase Auth. +[auth.third_party.clerk] +enabled = false +# domain = "example.clerk.accounts.dev" + [edge_runtime] enabled = true # Configure one of the supported request policies: `oneshot`, `per_worker`. From 24f8a321aacae0af808d06030375b3c565f2197e Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Thu, 6 Mar 2025 05:09:45 +0800 Subject: [PATCH 39/54] fix: move function deploy to public package (#3253) --- examples/functions-deploy/main.go | 6 +- internal/functions/deploy/deploy.go | 10 +-- pkg/function/api.go | 26 +++++++- pkg/function/batch_test.go | 4 +- .../upload.go => pkg/function/deploy.go | 60 +++++++++++------- .../function/deploy_test.go | 61 +++++++++---------- .../testdata/geometries/Geometries.js | 0 .../function}/testdata/modules/imports.ts | 0 .../function}/testdata/nested/deno.json | 0 .../function}/testdata/nested/index.ts | 0 .../function}/testdata/shared/whatever.ts | 0 .../function}/testdata/writes_import_map.form | 0 12 files changed, 102 insertions(+), 65 deletions(-) rename internal/functions/deploy/upload.go => pkg/function/deploy.go (78%) rename internal/functions/deploy/upload_test.go => pkg/function/deploy_test.go (78%) rename {internal/functions/deploy => pkg/function}/testdata/geometries/Geometries.js (100%) rename {internal/functions/deploy => pkg/function}/testdata/modules/imports.ts (100%) rename {internal/functions/deploy => pkg/function}/testdata/nested/deno.json (100%) rename {internal/functions/deploy => pkg/function}/testdata/nested/index.ts (100%) rename {internal/functions/deploy => pkg/function}/testdata/shared/whatever.ts (100%) rename {internal/functions/deploy => pkg/function}/testdata/writes_import_map.form (100%) diff --git a/examples/functions-deploy/main.go b/examples/functions-deploy/main.go index 716ef1462..926e8b93c 100644 --- a/examples/functions-deploy/main.go +++ b/examples/functions-deploy/main.go @@ -19,17 +19,15 @@ func main() { } } -// Requires edge runtime binary to be added to PATH func deploy(ctx context.Context, fsys fs.FS) error { project := os.Getenv("SUPABASE_PROJECT_ID") apiClient := newAPIClient(os.Getenv("SUPABASE_ACCESS_TOKEN")) - eszipBundler := function.NewNativeBundler(".", fsys) - functionClient := function.NewEdgeRuntimeAPI(project, apiClient, eszipBundler) + functionClient := function.NewEdgeRuntimeAPI(project, apiClient) fc := config.FunctionConfig{"my-slug": { Entrypoint: "supabase/functions/my-slug/index.ts", ImportMap: "supabase/functions/import_map.json", }} - return functionClient.UpsertFunctions(ctx, fc) + return functionClient.Deploy(ctx, fc, fsys) } func newAPIClient(token string) api.ClientWithResponses { diff --git a/internal/functions/deploy/deploy.go b/internal/functions/deploy/deploy.go index 33ba5c23c..8686a426f 100644 --- a/internal/functions/deploy/deploy.go +++ b/internal/functions/deploy/deploy.go @@ -36,12 +36,12 @@ func Run(ctx context.Context, slugs []string, useDocker bool, noVerifyJWT *bool, if err != nil { return err } + opt := function.WithMaxJobs(maxJobs) if useDocker { - api := function.NewEdgeRuntimeAPI(flags.ProjectRef, *utils.GetSupabase(), NewDockerBundler(fsys)) - if err := api.UpsertFunctions(ctx, functionConfig); err != nil { - return err - } - } else if err := deploy(ctx, functionConfig, maxJobs, fsys); errors.Is(err, errNoDeploy) { + opt = function.WithBundler(NewDockerBundler(fsys)) + } + api := function.NewEdgeRuntimeAPI(flags.ProjectRef, *utils.GetSupabase(), opt) + if err := api.Deploy(ctx, functionConfig, afero.NewIOFS(fsys)); errors.Is(err, function.ErrNoDeploy) { fmt.Fprintln(os.Stderr, err) return nil } else if err != nil { diff --git a/pkg/function/api.go b/pkg/function/api.go index 9fdf52b51..cdf530b55 100644 --- a/pkg/function/api.go +++ b/pkg/function/api.go @@ -11,12 +11,34 @@ type EdgeRuntimeAPI struct { project string client api.ClientWithResponses eszip EszipBundler + maxJobs uint } type EszipBundler interface { Bundle(ctx context.Context, entrypoint string, importMap string, staticFiles []string, output io.Writer) error } -func NewEdgeRuntimeAPI(project string, client api.ClientWithResponses, bundler EszipBundler) EdgeRuntimeAPI { - return EdgeRuntimeAPI{client: client, project: project, eszip: bundler} +func NewEdgeRuntimeAPI(project string, client api.ClientWithResponses, opts ...withOption) EdgeRuntimeAPI { + result := EdgeRuntimeAPI{client: client, project: project} + for _, apply := range opts { + apply(&result) + } + if result.maxJobs == 0 { + result.maxJobs = 1 + } + return result +} + +type withOption func(*EdgeRuntimeAPI) + +func WithBundler(bundler EszipBundler) withOption { + return func(era *EdgeRuntimeAPI) { + era.eszip = bundler + } +} + +func WithMaxJobs(maxJobs uint) withOption { + return func(era *EdgeRuntimeAPI) { + era.maxJobs = maxJobs + } } diff --git a/pkg/function/batch_test.go b/pkg/function/batch_test.go index 101cabb79..f356e74d1 100644 --- a/pkg/function/batch_test.go +++ b/pkg/function/batch_test.go @@ -29,7 +29,9 @@ const ( func TestUpsertFunctions(t *testing.T) { apiClient, err := api.NewClientWithResponses(mockApiHost) require.NoError(t, err) - client := NewEdgeRuntimeAPI(mockProject, *apiClient, &MockBundler{}) + client := NewEdgeRuntimeAPI(mockProject, *apiClient, func(era *EdgeRuntimeAPI) { + era.eszip = &MockBundler{} + }) t.Run("throws error on network failure", func(t *testing.T) { // Setup mock api diff --git a/internal/functions/deploy/upload.go b/pkg/function/deploy.go similarity index 78% rename from internal/functions/deploy/upload.go rename to pkg/function/deploy.go index 06accca5c..3eef79284 100644 --- a/internal/functions/deploy/upload.go +++ b/pkg/function/deploy.go @@ -1,4 +1,4 @@ -package deploy +package function import ( "bytes" @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "io" + "io/fs" "mime/multipart" "os" "path" @@ -14,18 +15,19 @@ import ( "strings" "github.com/go-errors/errors" - "github.com/spf13/afero" - "github.com/supabase/cli/internal/utils" - "github.com/supabase/cli/internal/utils/flags" "github.com/supabase/cli/pkg/api" "github.com/supabase/cli/pkg/cast" "github.com/supabase/cli/pkg/config" "github.com/supabase/cli/pkg/queue" + "github.com/tidwall/jsonc" ) -var errNoDeploy = errors.New("All Functions are up to date.") +var ErrNoDeploy = errors.New("All Functions are up to date.") -func deploy(ctx context.Context, functionConfig config.FunctionConfig, maxJobs uint, fsys afero.Fs) error { +func (s *EdgeRuntimeAPI) Deploy(ctx context.Context, functionConfig config.FunctionConfig, fsys fs.FS) error { + if s.eszip != nil { + return s.UpsertFunctions(ctx, functionConfig) + } var toDeploy []api.FunctionDeployMetadata for slug, fc := range functionConfig { if !fc.Enabled { @@ -46,17 +48,17 @@ func deploy(ctx context.Context, functionConfig config.FunctionConfig, maxJobs u toDeploy = append(toDeploy, meta) } if len(toDeploy) == 0 { - return errors.New(errNoDeploy) + return errors.New(ErrNoDeploy) } else if len(toDeploy) == 1 { param := api.V1DeployAFunctionParams{Slug: toDeploy[0].Name} - _, err := upload(ctx, param, toDeploy[0], fsys) + _, err := s.upload(ctx, param, toDeploy[0], fsys) return err } - return bulkUpload(ctx, toDeploy, maxJobs, fsys) + return s.bulkUpload(ctx, toDeploy, fsys) } -func bulkUpload(ctx context.Context, toDeploy []api.FunctionDeployMetadata, maxJobs uint, fsys afero.Fs) error { - jq := queue.NewJobQueue(maxJobs) +func (s *EdgeRuntimeAPI) bulkUpload(ctx context.Context, toDeploy []api.FunctionDeployMetadata, fsys fs.FS) error { + jq := queue.NewJobQueue(s.maxJobs) toUpdate := make([]api.BulkUpdateFunctionBody, len(toDeploy)) for i, meta := range toDeploy { fmt.Fprintln(os.Stderr, "Deploying Function:", *meta.Name) @@ -65,7 +67,7 @@ func bulkUpload(ctx context.Context, toDeploy []api.FunctionDeployMetadata, maxJ BundleOnly: cast.Ptr(true), } bundle := func() error { - resp, err := upload(ctx, param, meta, fsys) + resp, err := s.upload(ctx, param, meta, fsys) if err != nil { return err } @@ -88,7 +90,7 @@ func bulkUpload(ctx context.Context, toDeploy []api.FunctionDeployMetadata, maxJ if err := jq.Collect(); err != nil { return err } - if resp, err := utils.GetSupabase().V1BulkUpdateFunctionsWithResponse(ctx, flags.ProjectRef, toUpdate); err != nil { + if resp, err := s.client.V1BulkUpdateFunctionsWithResponse(ctx, s.project, toUpdate); err != nil { return errors.Errorf("failed to bulk update: %w", err) } else if resp.JSON200 == nil { return errors.Errorf("unexpected bulk update status %d: %s", resp.StatusCode(), string(resp.Body)) @@ -96,7 +98,7 @@ func bulkUpload(ctx context.Context, toDeploy []api.FunctionDeployMetadata, maxJ return nil } -func upload(ctx context.Context, param api.V1DeployAFunctionParams, meta api.FunctionDeployMetadata, fsys afero.Fs) (*api.DeployFunctionResponse, error) { +func (s *EdgeRuntimeAPI) upload(ctx context.Context, param api.V1DeployAFunctionParams, meta api.FunctionDeployMetadata, fsys fs.FS) (*api.DeployFunctionResponse, error) { body, w := io.Pipe() form := multipart.NewWriter(w) ctx, cancel := context.WithCancelCause(ctx) @@ -109,7 +111,7 @@ func upload(ctx context.Context, param api.V1DeployAFunctionParams, meta api.Fun cancel(err) } }() - resp, err := utils.GetSupabase().V1DeployAFunctionWithBodyWithResponse(ctx, flags.ProjectRef, ¶m, form.FormDataContentType(), body) + resp, err := s.client.V1DeployAFunctionWithBodyWithResponse(ctx, s.project, ¶m, form.FormDataContentType(), body) if cause := context.Cause(ctx); cause != ctx.Err() { return nil, cause } else if err != nil { @@ -120,7 +122,7 @@ func upload(ctx context.Context, param api.V1DeployAFunctionParams, meta api.Fun return resp.JSON201, nil } -func writeForm(form *multipart.Writer, meta api.FunctionDeployMetadata, fsys afero.Fs) error { +func writeForm(form *multipart.Writer, meta api.FunctionDeployMetadata, fsys fs.FS) error { m, err := form.CreateFormField("metadata") if err != nil { return errors.Errorf("failed to create metadata: %w", err) @@ -152,9 +154,9 @@ func writeForm(form *multipart.Writer, meta api.FunctionDeployMetadata, fsys afe return nil } // Add import map - importMap := utils.ImportMap{} + importMap := ImportMap{} if imPath := cast.Val(meta.ImportMapPath, ""); len(imPath) > 0 { - data, err := afero.ReadFile(fsys, filepath.FromSlash(imPath)) + data, err := fs.ReadFile(fsys, filepath.FromSlash(imPath)) if err != nil { return errors.Errorf("failed to load import map: %w", err) } @@ -173,9 +175,9 @@ func writeForm(form *multipart.Writer, meta api.FunctionDeployMetadata, fsys afe } // Add static files patterns := config.Glob(cast.Val(meta.StaticPatterns, []string{})) - files, err := patterns.Files(afero.NewIOFS(fsys)) + files, err := patterns.Files(fsys) if err != nil { - fmt.Fprintln(os.Stderr, utils.Yellow("WARNING:"), err) + fmt.Fprintln(os.Stderr, "WARN:", err) } for _, sfPath := range files { if err := addFile(sfPath, io.Discard); err != nil { @@ -185,10 +187,24 @@ func writeForm(form *multipart.Writer, meta api.FunctionDeployMetadata, fsys afe return walkImportPaths(meta.EntrypointPath, importMap, addFile) } +type ImportMap struct { + Imports map[string]string `json:"imports"` + Scopes map[string]map[string]string `json:"scopes"` +} + +func (m *ImportMap) Parse(data []byte) error { + data = jsonc.ToJSONInPlace(data) + decoder := json.NewDecoder(bytes.NewReader(data)) + if err := decoder.Decode(&m); err != nil { + return errors.Errorf("failed to parse import map: %w", err) + } + return nil +} + // Ref: https://regex101.com/r/DfBdJA/1 var importPathPattern = regexp.MustCompile(`(?i)(?:import|export)\s+(?:{[^{}]+}|.*?)\s*(?:from)?\s*['"](.*?)['"]|import\(\s*['"](.*?)['"]\)`) -func walkImportPaths(srcPath string, importMap utils.ImportMap, readFile func(curr string, w io.Writer) error) error { +func walkImportPaths(srcPath string, importMap ImportMap, readFile func(curr string, w io.Writer) error) error { seen := map[string]struct{}{} // DFS because it's more efficient to pop from end of array q := make([]string, 1) @@ -204,7 +220,7 @@ func walkImportPaths(srcPath string, importMap utils.ImportMap, readFile func(cu // Read into memory for regex match later var buf bytes.Buffer if err := readFile(curr, &buf); errors.Is(err, os.ErrNotExist) { - fmt.Fprintln(os.Stderr, utils.Yellow("WARNING:"), err) + fmt.Fprintln(os.Stderr, "WARN:", err) continue } else if err != nil { return err diff --git a/internal/functions/deploy/upload_test.go b/pkg/function/deploy_test.go similarity index 78% rename from internal/functions/deploy/upload_test.go rename to pkg/function/deploy_test.go index 12c00c128..424478aa3 100644 --- a/internal/functions/deploy/upload_test.go +++ b/pkg/function/deploy_test.go @@ -1,4 +1,4 @@ -package deploy +package function import ( "bytes" @@ -11,15 +11,12 @@ import ( "os" "path" "testing" + fs "testing/fstest" "github.com/h2non/gock" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/supabase/cli/internal/testing/apitest" - "github.com/supabase/cli/internal/utils" - "github.com/supabase/cli/internal/utils/flags" "github.com/supabase/cli/pkg/api" "github.com/supabase/cli/pkg/cast" "github.com/supabase/cli/pkg/config" @@ -52,7 +49,7 @@ func TestImportPaths(t *testing.T) { fsys.On("ReadFile", "testdata/modules/imports.ts").Once() fsys.On("ReadFile", "testdata/geometries/Geometries.js").Once() // Run test - im := utils.ImportMap{} + im := ImportMap{} err := walkImportPaths("testdata/modules/imports.ts", im, fsys.ReadFile) // Check error assert.NoError(t, err) @@ -69,7 +66,7 @@ func TestImportPaths(t *testing.T) { fsys.On("ReadFile", "testdata/shared/mod.ts").Once() fsys.On("ReadFile", "testdata/nested/index.ts").Once() // Run test - im := utils.ImportMap{Imports: map[string]string{ + im := ImportMap{Imports: map[string]string{ "module-name/": "../shared/", }} err := walkImportPaths("testdata/modules/imports.ts", im, fsys.ReadFile) @@ -94,7 +91,7 @@ func TestWriteForm(t *testing.T) { form := multipart.NewWriter(&buf) require.NoError(t, form.SetBoundary("test")) // Setup in-memory fs - fsys := afero.FromIOFS{FS: testImports} + fsys := testImports // Run test err := writeForm(form, api.FunctionDeployMetadata{ Name: cast.Ptr("nested"), @@ -113,7 +110,7 @@ func TestWriteForm(t *testing.T) { form := multipart.NewWriter(&buf) require.NoError(t, form.SetBoundary("test")) // Setup in-memory fs - fsys := afero.NewMemMapFs() + fsys := fs.MapFS{} // Run test err := writeForm(form, api.FunctionDeployMetadata{ ImportMapPath: cast.Ptr("testdata/import_map.json"), @@ -127,7 +124,7 @@ func TestWriteForm(t *testing.T) { form := multipart.NewWriter(&buf) require.NoError(t, form.SetBoundary("test")) // Setup in-memory fs - fsys := afero.NewMemMapFs() + fsys := testImports // Run test err := writeForm(form, api.FunctionDeployMetadata{ StaticPatterns: cast.Ptr([]string{"testdata"}), @@ -138,10 +135,9 @@ func TestWriteForm(t *testing.T) { } func TestDeployAll(t *testing.T) { - flags.ProjectRef = apitest.RandomProjectRef() - // Setup valid access token - token := apitest.RandomAccessToken(t) - t.Setenv("SUPABASE_ACCESS_TOKEN", string(token)) + apiClient, err := api.NewClientWithResponses(mockApiHost) + require.NoError(t, err) + client := NewEdgeRuntimeAPI(mockProject, *apiClient) t.Run("deploys single slug", func(t *testing.T) { c := config.FunctionConfig{"demo": { @@ -149,19 +145,20 @@ func TestDeployAll(t *testing.T) { Entrypoint: "testdata/shared/whatever.ts", }} // Setup in-memory fs - fsys := afero.FromIOFS{FS: testImports} + fsys := testImports // Setup mock api defer gock.OffAll() - gock.New(utils.DefaultApiHost). - Post("/v1/projects/"+flags.ProjectRef+"/functions/deploy"). + gock.New(mockApiHost). + Post("/v1/projects/"+mockProject+"/functions/deploy"). MatchParam("slug", "demo"). Reply(http.StatusCreated). JSON(api.DeployFunctionResponse{}) // Run test - err := deploy(context.Background(), c, 1, fsys) + err := client.Deploy(context.Background(), c, fsys) // Check error assert.NoError(t, err) - assert.Empty(t, apitest.ListUnmatchedRequests()) + assert.Empty(t, gock.Pending()) + assert.Empty(t, gock.GetUnmatchedRequests()) }) t.Run("deploys multiple slugs", func(t *testing.T) { @@ -176,42 +173,44 @@ func TestDeployAll(t *testing.T) { }, } // Setup in-memory fs - fsys := afero.FromIOFS{FS: testImports} + fsys := testImports // Setup mock api defer gock.OffAll() for slug := range c { - gock.New(utils.DefaultApiHost). - Post("/v1/projects/"+flags.ProjectRef+"/functions/deploy"). + gock.New(mockApiHost). + Post("/v1/projects/"+mockProject+"/functions/deploy"). MatchParam("slug", slug). Reply(http.StatusCreated). JSON(api.DeployFunctionResponse{Id: slug}) } - gock.New(utils.DefaultApiHost). - Put("/v1/projects/" + flags.ProjectRef + "/functions"). + gock.New(mockApiHost). + Put("/v1/projects/" + mockProject + "/functions"). Reply(http.StatusOK). JSON(api.BulkUpdateFunctionResponse{}) // Run test - err := deploy(context.Background(), c, 1, fsys) + err := client.Deploy(context.Background(), c, fsys) // Check error assert.NoError(t, err) - assert.Empty(t, apitest.ListUnmatchedRequests()) + assert.Empty(t, gock.Pending()) + assert.Empty(t, gock.GetUnmatchedRequests()) }) t.Run("throws error on network failure", func(t *testing.T) { errNetwork := errors.New("network") c := config.FunctionConfig{"demo": {Enabled: true}} // Setup in-memory fs - fsys := afero.NewMemMapFs() + fsys := fs.MapFS{} // Setup mock api defer gock.OffAll() - gock.New(utils.DefaultApiHost). - Post("/v1/projects/"+flags.ProjectRef+"/functions/deploy"). + gock.New(mockApiHost). + Post("/v1/projects/"+mockProject+"/functions/deploy"). MatchParam("slug", "demo"). ReplyError(errNetwork) // Run test - err := deploy(context.Background(), c, 1, fsys) + err := client.Deploy(context.Background(), c, fsys) // Check error assert.ErrorIs(t, err, errNetwork) - assert.Empty(t, apitest.ListUnmatchedRequests()) + assert.Empty(t, gock.Pending()) + assert.Empty(t, gock.GetUnmatchedRequests()) }) } diff --git a/internal/functions/deploy/testdata/geometries/Geometries.js b/pkg/function/testdata/geometries/Geometries.js similarity index 100% rename from internal/functions/deploy/testdata/geometries/Geometries.js rename to pkg/function/testdata/geometries/Geometries.js diff --git a/internal/functions/deploy/testdata/modules/imports.ts b/pkg/function/testdata/modules/imports.ts similarity index 100% rename from internal/functions/deploy/testdata/modules/imports.ts rename to pkg/function/testdata/modules/imports.ts diff --git a/internal/functions/deploy/testdata/nested/deno.json b/pkg/function/testdata/nested/deno.json similarity index 100% rename from internal/functions/deploy/testdata/nested/deno.json rename to pkg/function/testdata/nested/deno.json diff --git a/internal/functions/deploy/testdata/nested/index.ts b/pkg/function/testdata/nested/index.ts similarity index 100% rename from internal/functions/deploy/testdata/nested/index.ts rename to pkg/function/testdata/nested/index.ts diff --git a/internal/functions/deploy/testdata/shared/whatever.ts b/pkg/function/testdata/shared/whatever.ts similarity index 100% rename from internal/functions/deploy/testdata/shared/whatever.ts rename to pkg/function/testdata/shared/whatever.ts diff --git a/internal/functions/deploy/testdata/writes_import_map.form b/pkg/function/testdata/writes_import_map.form similarity index 100% rename from internal/functions/deploy/testdata/writes_import_map.form rename to pkg/function/testdata/writes_import_map.form From 37679466a72ac4bb85c109db963ca1949a42552b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Mar 2025 04:22:16 +0000 Subject: [PATCH 40/54] chore(deps): bump go.opentelemetry.io/otel from 1.34.0 to 1.35.0 (#3257) Bumps [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) from 1.34.0 to 1.35.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.34.0...v1.35.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index a3a038df6..0502cb17a 100644 --- a/go.mod +++ b/go.mod @@ -48,7 +48,7 @@ require ( github.com/tidwall/jsonc v0.3.2 github.com/withfig/autocomplete-tools/packages/cobra v1.2.0 github.com/zalando/go-keyring v0.2.6 - go.opentelemetry.io/otel v1.34.0 + go.opentelemetry.io/otel v1.35.0 golang.org/x/mod v0.23.0 golang.org/x/oauth2 v0.27.0 golang.org/x/term v0.29.0 @@ -314,10 +314,10 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect - go.opentelemetry.io/otel/metric v1.34.0 // indirect + go.opentelemetry.io/otel/metric v1.35.0 // indirect go.opentelemetry.io/otel/sdk v1.34.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect - go.opentelemetry.io/otel/trace v1.34.0 // indirect + go.opentelemetry.io/otel/trace v1.35.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/automaxprocs v1.6.0 // indirect diff --git a/go.sum b/go.sum index 7c6377105..919190145 100644 --- a/go.sum +++ b/go.sum @@ -1042,8 +1042,8 @@ go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJyS go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q= -go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= -go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 h1:ajl4QczuJVA2TU9W9AGw++86Xga/RKt//16z/yxPgdk= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0/go.mod h1:Vn3/rlOJ3ntf/Q3zAI0V5lDnTbHGaUsNUeF6nZmm7pA= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= @@ -1052,14 +1052,14 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0u go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4= -go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= -go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= -go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= -go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= From 09faa38afca5fdd7eaf1cb95167c2fdc7cd260c7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Mar 2025 04:29:01 +0000 Subject: [PATCH 41/54] chore(deps): bump supabase/supavisor from 2.4.6 to 2.4.9 in /pkg/config/templates (#3262) chore(deps): bump supabase/supavisor in /pkg/config/templates Bumps supabase/supavisor from 2.4.6 to 2.4.9. --- updated-dependencies: - dependency-name: supabase/supavisor dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index f719800d2..f087fd475 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -9,7 +9,7 @@ FROM supabase/studio:20250224-d10db0f AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy FROM supabase/edge-runtime:v1.67.2 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector -FROM supabase/supavisor:2.4.6 AS supavisor +FROM supabase/supavisor:2.4.9 AS supavisor FROM supabase/gotrue:v2.169.0 AS gotrue FROM supabase/realtime:v2.34.39 AS realtime FROM supabase/storage-api:v1.19.1 AS storage From 42f560e45328aa759459dee96d9e1bfb5c1507b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Mar 2025 04:33:53 +0000 Subject: [PATCH 42/54] chore(deps): bump supabase/realtime from v2.34.39 to v2.34.40 in /pkg/config/templates (#3263) chore(deps): bump supabase/realtime in /pkg/config/templates Bumps supabase/realtime from v2.34.39 to v2.34.40. --- updated-dependencies: - dependency-name: supabase/realtime dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index f087fd475..a4b8a2f20 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -11,7 +11,7 @@ FROM supabase/edge-runtime:v1.67.2 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.4.9 AS supavisor FROM supabase/gotrue:v2.169.0 AS gotrue -FROM supabase/realtime:v2.34.39 AS realtime +FROM supabase/realtime:v2.34.40 AS realtime FROM supabase/storage-api:v1.19.1 AS storage FROM supabase/logflare:1.12.0 AS logflare # Append to JobImages when adding new dependencies below From 840ffd623801f9496e651b87d06df9a7889d566b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Mar 2025 04:48:04 +0000 Subject: [PATCH 43/54] chore(deps): bump supabase/postgres from 15.8.1.047 to 15.8.1.048 in /pkg/config/templates (#3267) chore(deps): bump supabase/postgres in /pkg/config/templates Bumps supabase/postgres from 15.8.1.047 to 15.8.1.048. --- updated-dependencies: - dependency-name: supabase/postgres dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index a4b8a2f20..bd1316d59 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -1,5 +1,5 @@ # Exposed for updates by .github/dependabot.yml -FROM supabase/postgres:15.8.1.047 AS pg15 +FROM supabase/postgres:15.8.1.048 AS pg15 # Append to ServiceImages when adding new dependencies below FROM library/kong:2.8.1 AS kong FROM axllent/mailpit:v1.22.3 AS mailpit From 11ad92f8e872754477bf24e0e791351fca2ed013 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Mar 2025 04:52:33 +0000 Subject: [PATCH 44/54] chore(deps): bump supabase/supavisor from 2.4.9 to 2.4.12 in /pkg/config/templates (#3268) chore(deps): bump supabase/supavisor in /pkg/config/templates Bumps supabase/supavisor from 2.4.9 to 2.4.12. --- updated-dependencies: - dependency-name: supabase/supavisor dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index bd1316d59..88b872725 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -9,7 +9,7 @@ FROM supabase/studio:20250224-d10db0f AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy FROM supabase/edge-runtime:v1.67.2 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector -FROM supabase/supavisor:2.4.9 AS supavisor +FROM supabase/supavisor:2.4.12 AS supavisor FROM supabase/gotrue:v2.169.0 AS gotrue FROM supabase/realtime:v2.34.40 AS realtime FROM supabase/storage-api:v1.19.1 AS storage From af8ad6e7700622f39988e2f4b92326625e0316f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Mar 2025 04:56:43 +0000 Subject: [PATCH 45/54] chore(deps): bump supabase/gotrue from v2.169.0 to v2.170.0 in /pkg/config/templates (#3269) chore(deps): bump supabase/gotrue in /pkg/config/templates Bumps supabase/gotrue from v2.169.0 to v2.170.0. --- updated-dependencies: - dependency-name: supabase/gotrue dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 88b872725..c7319b93b 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -10,7 +10,7 @@ FROM darthsim/imgproxy:v3.8.0 AS imgproxy FROM supabase/edge-runtime:v1.67.2 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.4.12 AS supavisor -FROM supabase/gotrue:v2.169.0 AS gotrue +FROM supabase/gotrue:v2.170.0 AS gotrue FROM supabase/realtime:v2.34.40 AS realtime FROM supabase/storage-api:v1.19.1 AS storage FROM supabase/logflare:1.12.0 AS logflare From b02f6dc0053f4902c0d9c097dc76cec86fe01eab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 8 Mar 2025 13:01:20 +0800 Subject: [PATCH 46/54] chore(deps): bump golang.org/x/mod from 0.23.0 to 0.24.0 (#3260) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0502cb17a..2cff23da7 100644 --- a/go.mod +++ b/go.mod @@ -49,7 +49,7 @@ require ( github.com/withfig/autocomplete-tools/packages/cobra v1.2.0 github.com/zalando/go-keyring v0.2.6 go.opentelemetry.io/otel v1.35.0 - golang.org/x/mod v0.23.0 + golang.org/x/mod v0.24.0 golang.org/x/oauth2 v0.27.0 golang.org/x/term v0.29.0 google.golang.org/grpc v1.71.0 diff --git a/go.sum b/go.sum index 919190145..4e987d4d2 100644 --- a/go.sum +++ b/go.sum @@ -1156,8 +1156,8 @@ golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= +golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= From 57af4da2739b073af1e7d3a6964fe755ae6777c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 8 Mar 2025 13:02:18 +0800 Subject: [PATCH 47/54] chore(deps): bump golang.org/x/term from 0.29.0 to 0.30.0 (#3258) --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 2cff23da7..22809a655 100644 --- a/go.mod +++ b/go.mod @@ -51,7 +51,7 @@ require ( go.opentelemetry.io/otel v1.35.0 golang.org/x/mod v0.24.0 golang.org/x/oauth2 v0.27.0 - golang.org/x/term v0.29.0 + golang.org/x/term v0.30.0 google.golang.org/grpc v1.71.0 gopkg.in/yaml.v3 v3.0.1 gotest.tools/gotestsum v1.12.0 @@ -328,7 +328,7 @@ require ( golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac // indirect golang.org/x/net v0.35.0 // indirect golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect + golang.org/x/sys v0.31.0 // indirect golang.org/x/text v0.22.0 // indirect golang.org/x/tools v0.30.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect diff --git a/go.sum b/go.sum index 4e987d4d2..e47477253 100644 --- a/go.sum +++ b/go.sum @@ -1307,8 +1307,8 @@ golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1323,8 +1323,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= -golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= +golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= +golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= From 106b2cc76c4939e620c0cf941206f89f762c49b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 8 Mar 2025 13:56:08 +0800 Subject: [PATCH 48/54] chore(deps): bump golang.org/x/oauth2 from 0.27.0 to 0.28.0 (#3259) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 22809a655..fdf5a7d32 100644 --- a/go.mod +++ b/go.mod @@ -50,7 +50,7 @@ require ( github.com/zalando/go-keyring v0.2.6 go.opentelemetry.io/otel v1.35.0 golang.org/x/mod v0.24.0 - golang.org/x/oauth2 v0.27.0 + golang.org/x/oauth2 v0.28.0 golang.org/x/term v0.30.0 google.golang.org/grpc v1.71.0 gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index e47477253..f9941eb8e 100644 --- a/go.sum +++ b/go.sum @@ -1216,8 +1216,8 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= -golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc= +golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= From fe3584650c9623ada6607f1300d5d1dea98a9b74 Mon Sep 17 00:00:00 2001 From: Stojan Dimitrovski Date: Sun, 9 Mar 2025 15:59:10 +0100 Subject: [PATCH 49/54] fix: clerk tpa domain pattern works for non-production mode domains (#3273) * fix: clerk tpa domain pattern works for non-production mode domains * fix: link to clerk supabase setup guide in config template and error message * apply suggestion from @sweatybridge Co-authored-by: Han Qiao --------- Co-authored-by: Han Qiao --- pkg/config/config.go | 4 ++-- pkg/config/templates/config.toml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index 13fc9f6d2..899deb63f 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -1209,7 +1209,7 @@ func (c *tpaCognito) validate() (err error) { return nil } -var clerkDomainPattern = regexp.MustCompile("^(clerk([.][a-z0-9-]+){2,}|([a-z0-9-][.])+clerk[.]accounts[.]dev)$") +var clerkDomainPattern = regexp.MustCompile("^(clerk([.][a-z0-9-]+){2,}|([a-z0-9-]+[.])+clerk[.]accounts[.]dev)$") func (c *tpaClerk) issuerURL() string { return fmt.Sprintf("https://%s", c.Domain) @@ -1223,7 +1223,7 @@ func (c *tpaClerk) validate() (err error) { } if !clerkDomainPattern.MatchString(c.Domain) { - return errors.New("Invalid config: auth.third_party.clerk has invalid domain, it usually is like clerk.example.com or example.clerk.accounts.dev") + return errors.New("Invalid config: auth.third_party.clerk has invalid domain, it usually is like clerk.example.com or example.clerk.accounts.dev. Check https://clerk.com/setup/supabase on how to find the correct value.") } return nil diff --git a/pkg/config/templates/config.toml b/pkg/config/templates/config.toml index e28bd0191..ec363cd42 100644 --- a/pkg/config/templates/config.toml +++ b/pkg/config/templates/config.toml @@ -273,6 +273,7 @@ enabled = false # Use Clerk as a third-party provider alongside Supabase Auth. [auth.third_party.clerk] enabled = false +# Obtain from https://clerk.com/setup/supabase # domain = "example.clerk.accounts.dev" [edge_runtime] From e1ae7274d88e594af689b4a622ebdf00b8052986 Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Tue, 11 Mar 2025 00:20:54 +0800 Subject: [PATCH 50/54] fix: bulk update after deploying multiple functions (#3277) --- internal/functions/deploy/deploy_test.go | 4 +++ pkg/function/batch.go | 46 +++++++++++++++++++++--- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/internal/functions/deploy/deploy_test.go b/internal/functions/deploy/deploy_test.go index 9a5b99785..9510d4c73 100644 --- a/internal/functions/deploy/deploy_test.go +++ b/internal/functions/deploy/deploy_test.go @@ -54,6 +54,10 @@ func TestDeployCommand(t *testing.T) { apitest.MockDockerStart(utils.Docker, imageUrl, containerId) require.NoError(t, apitest.MockDockerLogs(utils.Docker, containerId, "bundled")) } + gock.New(utils.DefaultApiHost). + Put("/v1/projects/" + flags.ProjectRef + "/functions"). + Reply(http.StatusOK). + JSON(api.BulkUpdateFunctionResponse{}) // Setup output file for _, v := range functions { outputDir := filepath.Join(utils.TempDir, fmt.Sprintf(".output_%s", v)) diff --git a/pkg/function/batch.go b/pkg/function/batch.go index e5400efbc..2d38ec63b 100644 --- a/pkg/function/batch.go +++ b/pkg/function/batch.go @@ -34,6 +34,7 @@ func (s *EdgeRuntimeAPI) UpsertFunctions(ctx context.Context, functionConfig con for _, f := range result { exists[f.Slug] = struct{}{} } + toUpdate := map[string]api.BulkUpdateFunctionBody{} OUTER: for slug, function := range functionConfig { if !function.Enabled { @@ -52,27 +53,53 @@ OUTER: // Update if function already exists upsert := func() error { if _, ok := exists[slug]; ok { - if resp, err := s.client.V1UpdateAFunctionWithBodyWithResponse(ctx, s.project, slug, &api.V1UpdateAFunctionParams{ + resp, err := s.client.V1UpdateAFunctionWithBodyWithResponse(ctx, s.project, slug, &api.V1UpdateAFunctionParams{ VerifyJwt: &function.VerifyJWT, ImportMapPath: toFileURL(function.ImportMap), EntrypointPath: toFileURL(function.Entrypoint), - }, eszipContentType, bytes.NewReader(body.Bytes())); err != nil { + }, eszipContentType, bytes.NewReader(body.Bytes())) + if err != nil { return errors.Errorf("failed to update function: %w", err) } else if resp.JSON200 == nil { return errors.Errorf("unexpected status %d: %s", resp.StatusCode(), string(resp.Body)) } + toUpdate[slug] = api.BulkUpdateFunctionBody{ + Id: resp.JSON200.Id, + Name: resp.JSON200.Name, + Slug: resp.JSON200.Slug, + Version: resp.JSON200.Version, + EntrypointPath: resp.JSON200.EntrypointPath, + ImportMap: resp.JSON200.ImportMap, + ImportMapPath: resp.JSON200.ImportMapPath, + VerifyJwt: resp.JSON200.VerifyJwt, + Status: api.BulkUpdateFunctionBodyStatus(resp.JSON200.Status), + CreatedAt: &resp.JSON200.CreatedAt, + } } else { - if resp, err := s.client.V1CreateAFunctionWithBodyWithResponse(ctx, s.project, &api.V1CreateAFunctionParams{ + resp, err := s.client.V1CreateAFunctionWithBodyWithResponse(ctx, s.project, &api.V1CreateAFunctionParams{ Slug: &slug, Name: &slug, VerifyJwt: &function.VerifyJWT, ImportMapPath: toFileURL(function.ImportMap), EntrypointPath: toFileURL(function.Entrypoint), - }, eszipContentType, bytes.NewReader(body.Bytes())); err != nil { + }, eszipContentType, bytes.NewReader(body.Bytes())) + if err != nil { return errors.Errorf("failed to create function: %w", err) } else if resp.JSON201 == nil { return errors.Errorf("unexpected status %d: %s", resp.StatusCode(), string(resp.Body)) } + toUpdate[slug] = api.BulkUpdateFunctionBody{ + Id: resp.JSON201.Id, + Name: resp.JSON201.Name, + Slug: resp.JSON201.Slug, + Version: resp.JSON201.Version, + EntrypointPath: resp.JSON201.EntrypointPath, + ImportMap: resp.JSON201.ImportMap, + ImportMapPath: resp.JSON201.ImportMapPath, + VerifyJwt: resp.JSON201.VerifyJwt, + Status: api.BulkUpdateFunctionBodyStatus(resp.JSON201.Status), + CreatedAt: &resp.JSON201.CreatedAt, + } } return nil } @@ -83,6 +110,17 @@ OUTER: return err } } + if len(toUpdate) > 1 { + body := make([]api.BulkUpdateFunctionBody, len(toUpdate)) + for _, b := range toUpdate { + body = append(body, b) + } + if resp, err := s.client.V1BulkUpdateFunctionsWithResponse(ctx, s.project, body); err != nil { + return errors.Errorf("failed to bulk update: %w", err) + } else if resp.JSON200 == nil { + return errors.Errorf("unexpected bulk update status %d: %s", resp.StatusCode(), string(resp.Body)) + } + } return nil } From 6ad2b988c4379231b05f8f0c0a5a98c2f520e4da Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Tue, 11 Mar 2025 05:15:52 +0800 Subject: [PATCH 51/54] fix: append to empty request array (#3279) --- pkg/function/batch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/function/batch.go b/pkg/function/batch.go index 2d38ec63b..9c0f82059 100644 --- a/pkg/function/batch.go +++ b/pkg/function/batch.go @@ -111,7 +111,7 @@ OUTER: } } if len(toUpdate) > 1 { - body := make([]api.BulkUpdateFunctionBody, len(toUpdate)) + var body []api.BulkUpdateFunctionBody for _, b := range toUpdate { body = append(body, b) } From ce255382a7fff55b419cca59d6a60f8a14e4a61f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Mar 2025 05:17:22 +0000 Subject: [PATCH 52/54] chore(deps): bump supabase/storage-api from v1.19.1 to v1.19.2 in /pkg/config/templates (#3280) chore(deps): bump supabase/storage-api in /pkg/config/templates Bumps supabase/storage-api from v1.19.1 to v1.19.2. --- updated-dependencies: - dependency-name: supabase/storage-api dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index c7319b93b..187d948e2 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -12,7 +12,7 @@ FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.4.12 AS supavisor FROM supabase/gotrue:v2.170.0 AS gotrue FROM supabase/realtime:v2.34.40 AS realtime -FROM supabase/storage-api:v1.19.1 AS storage +FROM supabase/storage-api:v1.19.2 AS storage FROM supabase/logflare:1.12.0 AS logflare # Append to JobImages when adding new dependencies below FROM supabase/pgadmin-schema-diff:cli-0.0.5 AS differ From 02c25efb121de5c02c18b761372ddf33ea87cf6e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Mar 2025 05:21:50 +0000 Subject: [PATCH 53/54] chore(deps): bump supabase/logflare from 1.12.0 to 1.12.5 in /pkg/config/templates (#3276) chore(deps): bump supabase/logflare in /pkg/config/templates Bumps supabase/logflare from 1.12.0 to 1.12.5. --- updated-dependencies: - dependency-name: supabase/logflare dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 187d948e2..65e002e5f 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -13,7 +13,7 @@ FROM supabase/supavisor:2.4.12 AS supavisor FROM supabase/gotrue:v2.170.0 AS gotrue FROM supabase/realtime:v2.34.40 AS realtime FROM supabase/storage-api:v1.19.2 AS storage -FROM supabase/logflare:1.12.0 AS logflare +FROM supabase/logflare:1.12.5 AS logflare # Append to JobImages when adding new dependencies below FROM supabase/pgadmin-schema-diff:cli-0.0.5 AS differ FROM supabase/migra:3.0.1663481299 AS migra From 7a6338af1d608c17083e79a2ff1a3114bf6b167b Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Tue, 11 Mar 2025 17:19:11 +0100 Subject: [PATCH 54/54] fix: bump logflare version to 1.12.5