From b5abdaff9f2b7de797b277238164aadb11084bed Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Fri, 9 Jan 2026 03:01:53 +0800 Subject: [PATCH 001/117] feat: support ssl enforcement config --- pkg/config/db.go | 33 ++++++++++++++++++++++++++++++++ pkg/config/templates/config.toml | 4 ++++ pkg/config/testdata/config.toml | 4 ++++ pkg/config/updater.go | 32 +++++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+) diff --git a/pkg/config/db.go b/pkg/config/db.go index 122f5364bc..a367beb3a6 100644 --- a/pkg/config/db.go +++ b/pkg/config/db.go @@ -75,6 +75,10 @@ type ( AllowedCidrsV6 []string `toml:"allowed_cidrs_v6"` } + sslEnforcement struct { + Enabled bool `toml:"enabled"` + } + db struct { Image string `toml:"-"` Port uint16 `toml:"port"` @@ -88,6 +92,7 @@ type ( Seed seed `toml:"seed"` Settings settings `toml:"settings"` NetworkRestrictions networkRestrictions `toml:"network_restrictions"` + SslEnforcement *sslEnforcement `toml:"ssl_enforcement"` Vault map[string]Secret `toml:"vault"` } @@ -233,3 +238,31 @@ func (n *networkRestrictions) DiffWithRemote(remoteConfig v1API.NetworkRestricti } return diff.Diff("remote[db.network_restrictions]", remoteCompare, "local[db.network_restrictions]", currentValue), nil } + +func (s sslEnforcement) ToUpdateSslEnforcementBody() v1API.V1UpdateSslEnforcementConfigJSONRequestBody { + body := v1API.V1UpdateSslEnforcementConfigJSONRequestBody{} + body.RequestedConfig.Database = s.Enabled + return body +} + +func (s *sslEnforcement) FromRemoteSslEnforcement(remoteConfig v1API.SslEnforcementResponse) { + if s == nil { + return + } + s.Enabled = remoteConfig.CurrentConfig.Database +} + +func (s *sslEnforcement) DiffWithRemote(remoteConfig v1API.SslEnforcementResponse) ([]byte, error) { + copy := *s + // Convert the config values into easily comparable remoteConfig values + currentValue, err := ToTomlBytes(copy) + if err != nil { + return nil, err + } + copy.FromRemoteSslEnforcement(remoteConfig) + remoteCompare, err := ToTomlBytes(copy) + if err != nil { + return nil, err + } + return diff.Diff("remote[db.ssl_enforcement]", remoteCompare, "local[db.ssl_enforcement]", currentValue), nil +} diff --git a/pkg/config/templates/config.toml b/pkg/config/templates/config.toml index 87af2c3899..44b58cdb0c 100644 --- a/pkg/config/templates/config.toml +++ b/pkg/config/templates/config.toml @@ -74,6 +74,10 @@ allowed_cidrs = ["0.0.0.0/0"] # Defaults to allow all IPv6 connections. Set empty array to block all IPs. allowed_cidrs_v6 = ["::/0"] +# Uncomment to reject non-secure connections to the database. +# [db.ssl_enforcement] +# enabled = true + [realtime] enabled = true # Bind realtime via either IPv4 or IPv6. (default: IPv4) diff --git a/pkg/config/testdata/config.toml b/pkg/config/testdata/config.toml index ad2a0dd3e6..b228a9c073 100644 --- a/pkg/config/testdata/config.toml +++ b/pkg/config/testdata/config.toml @@ -74,6 +74,10 @@ allowed_cidrs = ["0.0.0.0/0"] # Defaults to allow all IPv6 connections. Set empty array to block all IPs. allowed_cidrs_v6 = ["::/0"] +# Uncomment to reject non-secure connections to the database. +[db.ssl_enforcement] +enabled = true + [realtime] enabled = true # Bind realtime via either IPv4 or IPv6. (default: IPv6) diff --git a/pkg/config/updater.go b/pkg/config/updater.go index 8915f43fb3..eb0e87c088 100644 --- a/pkg/config/updater.go +++ b/pkg/config/updater.go @@ -100,6 +100,9 @@ func (u *ConfigUpdater) UpdateDbConfig(ctx context.Context, projectRef string, c if err := u.UpdateDbNetworkRestrictionsConfig(ctx, projectRef, c.NetworkRestrictions, filter...); err != nil { return err } + if c.SslEnforcement != nil { + return u.UpdateSslEnforcement(ctx, projectRef, *c.SslEnforcement, filter...) + } return nil } @@ -132,6 +135,35 @@ func (u *ConfigUpdater) UpdateDbNetworkRestrictionsConfig(ctx context.Context, p return nil } +func (u *ConfigUpdater) UpdateSslEnforcement(ctx context.Context, projectRef string, s sslEnforcement, filter ...func(string) bool) error { + sslEnforcementConfig, err := u.client.V1GetSslEnforcementConfigWithResponse(ctx, projectRef) + if err != nil { + return errors.Errorf("failed to read SSL enforcement config: %w", err) + } else if sslEnforcementConfig.JSON200 == nil { + return errors.Errorf("unexpected status %d: %s", sslEnforcementConfig.StatusCode(), string(sslEnforcementConfig.Body)) + } + sslEnforcementDiff, err := s.DiffWithRemote(*sslEnforcementConfig.JSON200) + if err != nil { + return err + } else if len(sslEnforcementDiff) == 0 { + fmt.Fprintln(os.Stderr, "Remote DB SSL enforcement config is up to date.") + return nil + } + fmt.Fprintln(os.Stderr, "Updating SSL enforcement with config:", string(sslEnforcementDiff)) + for _, keep := range filter { + if !keep("db") { + return nil + } + } + updateBody := s.ToUpdateSslEnforcementBody() + if resp, err := u.client.V1UpdateSslEnforcementConfigWithResponse(ctx, projectRef, updateBody); err != nil { + return errors.Errorf("failed to update SSL enforcement config: %w", err) + } else if resp.JSON200 == nil { + return errors.Errorf("unexpected status %d: %s", resp.StatusCode(), string(resp.Body)) + } + return nil +} + func (u *ConfigUpdater) UpdateAuthConfig(ctx context.Context, projectRef string, c auth, filter ...func(string) bool) error { if !c.Enabled { return nil From 00698f583166e6abbc3b8b945b34c5484ada6ce0 Mon Sep 17 00:00:00 2001 From: 7ttp <117663341+7ttp@users.noreply.github.com> Date: Tue, 20 Jan 2026 13:04:14 +0530 Subject: [PATCH 002/117] fix(db): set working directory for SQL relative imports --- internal/db/test/test.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/db/test/test.go b/internal/db/test/test.go index dadb447367..f2caea9a5d 100644 --- a/internal/db/test/test.go +++ b/internal/db/test/test.go @@ -35,6 +35,7 @@ func Run(ctx context.Context, testFiles []string, config pgconn.Config, fsys afe } binds := make([]string, len(testFiles)) cmd := []string{"pg_prove", "--ext", ".pg", "--ext", ".sql", "-r"} + var workingDir string for i, fp := range testFiles { if !filepath.IsAbs(fp) { fp = filepath.Join(utils.CurrentDirAbs, fp) @@ -42,6 +43,9 @@ func Run(ctx context.Context, testFiles []string, config pgconn.Config, fsys afe dockerPath := utils.ToDockerPath(fp) cmd = append(cmd, dockerPath) binds[i] = fmt.Sprintf("%s:%s:ro", fp, dockerPath) + if workingDir == "" { + workingDir = filepath.Dir(dockerPath) + } } if viper.GetBool("DEBUG") { cmd = append(cmd, "--verbose") @@ -89,7 +93,8 @@ func Run(ctx context.Context, testFiles []string, config pgconn.Config, fsys afe "PGPASSWORD=" + config.Password, "PGDATABASE=" + config.Database, }, - Cmd: cmd, + Cmd: cmd, + WorkingDir: workingDir, }, hostConfig, network.NetworkingConfig{}, From 3364bd2b909194369db409f38cbcb936fc6ca633 Mon Sep 17 00:00:00 2001 From: Vaibhav <117663341+7ttp@users.noreply.github.com> Date: Tue, 20 Jan 2026 14:36:56 +0530 Subject: [PATCH 003/117] fix: handle directories and use path.Dir for unix separators Co-authored-by: Han Qiao --- internal/db/test/test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/internal/db/test/test.go b/internal/db/test/test.go index f2caea9a5d..faf16367ce 100644 --- a/internal/db/test/test.go +++ b/internal/db/test/test.go @@ -44,7 +44,10 @@ func Run(ctx context.Context, testFiles []string, config pgconn.Config, fsys afe cmd = append(cmd, dockerPath) binds[i] = fmt.Sprintf("%s:%s:ro", fp, dockerPath) if workingDir == "" { - workingDir = filepath.Dir(dockerPath) + workingDir = dockerPath + if path.Ext(dockerPath) != "" { + workingDir = path.Dir(dockerPath) + } } } if viper.GetBool("DEBUG") { From 0ecc36eebb56aa1b5f2a9facf973425c3ed0db04 Mon Sep 17 00:00:00 2001 From: Vaibhav <117663341+7ttp@users.noreply.github.com> Date: Tue, 20 Jan 2026 15:25:40 +0530 Subject: [PATCH 004/117] import "path" --- internal/db/test/test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/db/test/test.go b/internal/db/test/test.go index faf16367ce..2852ee9432 100644 --- a/internal/db/test/test.go +++ b/internal/db/test/test.go @@ -5,6 +5,7 @@ import ( _ "embed" "fmt" "os" + "path" "path/filepath" "github.com/docker/docker/api/types/container" From 1715b85173cb807a3b534b443cd669554ac7acc6 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Sat, 31 Jan 2026 02:50:30 +0800 Subject: [PATCH 005/117] chore: separate docker function config --- internal/functions/serve/serve.go | 23 ++++++++++++++++------ internal/functions/serve/templates/main.ts | 1 + 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/internal/functions/serve/serve.go b/internal/functions/serve/serve.go index b0db41ffd4..730e626dac 100644 --- a/internal/functions/serve/serve.go +++ b/internal/functions/serve/serve.go @@ -241,6 +241,13 @@ func parseEnvFile(envFilePath string, fsys afero.Fs) ([]string, error) { return env, err } +type dockerFunction struct { + VerifyJWT bool `json:"verifyJWT"` + EntrypointPath string `json:"entrypointPath,omitempty"` + ImportMapPath string `json:"importMapPath,omitempty"` + StaticFiles []string `json:"staticFiles,omitempty"` +} + func PopulatePerFunctionConfigs(cwd, importMapPath string, noVerifyJWT *bool, fsys afero.Fs) ([]string, string, error) { slugs, err := deploy.GetFunctionSlugs(fsys) if err != nil { @@ -251,10 +258,10 @@ func PopulatePerFunctionConfigs(cwd, importMapPath string, noVerifyJWT *bool, fs return nil, "", err } binds := []string{} + enabledFunctions := map[string]dockerFunction{} for slug, fc := range functionsConfig { if !fc.Enabled { fmt.Fprintln(os.Stderr, "Skipped serving Function:", slug) - delete(functionsConfig, slug) continue } modules, err := deploy.GetBindMounts(cwd, utils.FunctionsDir, "", fc.Entrypoint, fc.ImportMap, fsys) @@ -262,14 +269,18 @@ func PopulatePerFunctionConfigs(cwd, importMapPath string, noVerifyJWT *bool, fs return nil, "", err } binds = append(binds, modules...) - fc.ImportMap = utils.ToDockerPath(fc.ImportMap) - fc.Entrypoint = utils.ToDockerPath(fc.Entrypoint) - functionsConfig[slug] = fc + enabled := dockerFunction{ + VerifyJWT: fc.VerifyJWT, + EntrypointPath: utils.ToDockerPath(fc.Entrypoint), + ImportMapPath: utils.ToDockerPath(fc.ImportMap), + StaticFiles: make([]string, len(fc.StaticFiles)), + } for i, val := range fc.StaticFiles { - fc.StaticFiles[i] = utils.ToDockerPath(val) + enabled.StaticFiles[i] = utils.ToDockerPath(val) } + enabledFunctions[slug] = enabled } - functionsConfigBytes, err := json.Marshal(functionsConfig) + functionsConfigBytes, err := json.Marshal(enabledFunctions) if err != nil { return nil, "", errors.Errorf("failed to marshal config json: %w", err) } diff --git a/internal/functions/serve/templates/main.ts b/internal/functions/serve/templates/main.ts index f6676c163d..60ea512713 100644 --- a/internal/functions/serve/templates/main.ts +++ b/internal/functions/serve/templates/main.ts @@ -53,6 +53,7 @@ const GENERIC_FUNCTION_SERVE_MESSAGE = `Serving functions on http://127.0.0.1:${ interface FunctionConfig { entrypointPath: string; importMapPath: string; + staticFiles: string[]; verifyJWT: boolean; } From af0173cbc42c3f6dda4eda724bc3521d56d40a74 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Sat, 31 Jan 2026 02:51:51 +0800 Subject: [PATCH 006/117] chore: swap toml tag for json --- pkg/config/api.go | 28 ++--- pkg/config/auth.go | 278 +++++++++++++++++++++--------------------- pkg/config/config.go | 138 ++++++++++----------- pkg/config/db.go | 106 ++++++++-------- pkg/config/storage.go | 58 ++++----- 5 files changed, 304 insertions(+), 304 deletions(-) diff --git a/pkg/config/api.go b/pkg/config/api.go index e294a38c68..e8e8aaf843 100644 --- a/pkg/config/api.go +++ b/pkg/config/api.go @@ -10,25 +10,25 @@ import ( type ( api struct { - Enabled bool `toml:"enabled"` - Schemas []string `toml:"schemas"` - ExtraSearchPath []string `toml:"extra_search_path"` - MaxRows uint `toml:"max_rows"` + Enabled bool `json:"enabled"` + Schemas []string `json:"schemas"` + ExtraSearchPath []string `json:"extra_search_path"` + MaxRows uint `json:"max_rows"` // Local only config - Image string `toml:"-"` - KongImage string `toml:"-"` - Port uint16 `toml:"port"` - Tls tlsKong `toml:"tls"` + Image string `json:"-"` + KongImage string `json:"-"` + Port uint16 `json:"port"` + Tls tlsKong `json:"tls"` // TODO: replace [auth|studio].api_url - ExternalUrl string `toml:"external_url"` + ExternalUrl string `json:"external_url"` } tlsKong struct { - Enabled bool `toml:"enabled"` - CertPath string `toml:"cert_path"` - CertContent []byte `toml:"-"` - KeyPath string `toml:"key_path"` - KeyContent []byte `toml:"-"` + Enabled bool `json:"enabled"` + CertPath string `json:"cert_path"` + CertContent []byte `json:"-"` + KeyPath string `json:"key_path"` + KeyContent []byte `json:"-"` } ) diff --git a/pkg/config/auth.go b/pkg/config/auth.go index 3c6ee2fd47..e23f33da14 100644 --- a/pkg/config/auth.go +++ b/pkg/config/auth.go @@ -146,242 +146,242 @@ func (j JWK) ToPublicJWK() JWK { type ( auth struct { - Enabled bool `toml:"enabled"` - Image string `toml:"-"` - - SiteUrl string `toml:"site_url"` - AdditionalRedirectUrls []string `toml:"additional_redirect_urls"` - JwtExpiry uint `toml:"jwt_expiry"` - JwtIssuer string `toml:"jwt_issuer"` - EnableRefreshTokenRotation bool `toml:"enable_refresh_token_rotation"` - RefreshTokenReuseInterval uint `toml:"refresh_token_reuse_interval"` - EnableManualLinking bool `toml:"enable_manual_linking"` - EnableSignup bool `toml:"enable_signup"` - EnableAnonymousSignIns bool `toml:"enable_anonymous_sign_ins"` - MinimumPasswordLength uint `toml:"minimum_password_length"` - PasswordRequirements PasswordRequirements `toml:"password_requirements"` - SigningKeysPath string `toml:"signing_keys_path"` - SigningKeys []JWK `toml:"-"` - - 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"` - Web3 web3 `toml:"web3"` - OAuthServer OAuthServer `toml:"oauth_server"` + Enabled bool `json:"enabled"` + Image string `json:"-"` + + SiteUrl string `json:"site_url"` + AdditionalRedirectUrls []string `json:"additional_redirect_urls"` + JwtExpiry uint `json:"jwt_expiry"` + JwtIssuer string `json:"jwt_issuer"` + EnableRefreshTokenRotation bool `json:"enable_refresh_token_rotation"` + RefreshTokenReuseInterval uint `json:"refresh_token_reuse_interval"` + EnableManualLinking bool `json:"enable_manual_linking"` + EnableSignup bool `json:"enable_signup"` + EnableAnonymousSignIns bool `json:"enable_anonymous_sign_ins"` + MinimumPasswordLength uint `json:"minimum_password_length"` + PasswordRequirements PasswordRequirements `json:"password_requirements"` + SigningKeysPath string `json:"signing_keys_path"` + SigningKeys []JWK `json:"-"` + + RateLimit rateLimit `json:"rate_limit"` + Captcha *captcha `json:"captcha"` + Hook hook `json:"hook"` + MFA mfa `json:"mfa"` + Sessions sessions `json:"sessions"` + Email email `json:"email"` + Sms sms `json:"sms"` + External external `json:"external"` + Web3 web3 `json:"web3"` + OAuthServer OAuthServer `json:"oauth_server"` // Custom secrets can be injected from .env file - PublishableKey Secret `toml:"publishable_key"` - SecretKey Secret `toml:"secret_key"` - JwtSecret Secret `toml:"jwt_secret"` - AnonKey Secret `toml:"anon_key"` - ServiceRoleKey Secret `toml:"service_role_key"` + PublishableKey Secret `json:"publishable_key"` + SecretKey Secret `json:"secret_key"` + JwtSecret Secret `json:"jwt_secret"` + AnonKey Secret `json:"anon_key"` + ServiceRoleKey Secret `json:"service_role_key"` - ThirdParty thirdParty `toml:"third_party"` + ThirdParty thirdParty `json:"third_party"` } external map[string]provider thirdParty struct { - Firebase tpaFirebase `toml:"firebase"` - Auth0 tpaAuth0 `toml:"auth0"` - Cognito tpaCognito `toml:"aws_cognito"` - Clerk tpaClerk `toml:"clerk"` - WorkOs tpaWorkOs `toml:"workos"` + Firebase tpaFirebase `json:"firebase"` + Auth0 tpaAuth0 `json:"auth0"` + Cognito tpaCognito `json:"aws_cognito"` + Clerk tpaClerk `json:"clerk"` + WorkOs tpaWorkOs `json:"workos"` } 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"` - Web3 uint `toml:"web3"` + AnonymousUsers uint `json:"anonymous_users"` + TokenRefresh uint `json:"token_refresh"` + SignInSignUps uint `json:"sign_in_sign_ups"` + TokenVerifications uint `json:"token_verifications"` + EmailSent uint `json:"email_sent"` + SmsSent uint `json:"sms_sent"` + Web3 uint `json:"web3"` } tpaFirebase struct { - Enabled bool `toml:"enabled"` + Enabled bool `json:"enabled"` - ProjectID string `toml:"project_id"` + ProjectID string `json:"project_id"` } tpaAuth0 struct { - Enabled bool `toml:"enabled"` + Enabled bool `json:"enabled"` - Tenant string `toml:"tenant"` - TenantRegion string `toml:"tenant_region"` + Tenant string `json:"tenant"` + TenantRegion string `json:"tenant_region"` } tpaCognito struct { - Enabled bool `toml:"enabled"` + Enabled bool `json:"enabled"` - UserPoolID string `toml:"user_pool_id"` - UserPoolRegion string `toml:"user_pool_region"` + UserPoolID string `json:"user_pool_id"` + UserPoolRegion string `json:"user_pool_region"` } tpaClerk struct { - Enabled bool `toml:"enabled"` + Enabled bool `json:"enabled"` - Domain string `toml:"domain"` + Domain string `json:"domain"` } tpaWorkOs struct { - Enabled bool `toml:"enabled"` + Enabled bool `json:"enabled"` - IssuerUrl string `toml:"issuer_url"` + IssuerUrl string `json:"issuer_url"` } email struct { - EnableSignup bool `toml:"enable_signup"` - DoubleConfirmChanges bool `toml:"double_confirm_changes"` - EnableConfirmations bool `toml:"enable_confirmations"` - SecurePasswordChange bool `toml:"secure_password_change"` - Template map[string]emailTemplate `toml:"template"` - Notification map[string]notification `toml:"notification"` - Smtp *smtp `toml:"smtp"` - MaxFrequency time.Duration `toml:"max_frequency"` - OtpLength uint `toml:"otp_length"` - OtpExpiry uint `toml:"otp_expiry"` + EnableSignup bool `json:"enable_signup"` + DoubleConfirmChanges bool `json:"double_confirm_changes"` + EnableConfirmations bool `json:"enable_confirmations"` + SecurePasswordChange bool `json:"secure_password_change"` + Template map[string]emailTemplate `json:"template"` + Notification map[string]notification `json:"notification"` + Smtp *smtp `json:"smtp"` + MaxFrequency time.Duration `json:"max_frequency"` + OtpLength uint `json:"otp_length"` + OtpExpiry uint `json:"otp_expiry"` } smtp struct { - Enabled bool `toml:"enabled"` - Host string `toml:"host"` - Port uint16 `toml:"port"` - User string `toml:"user"` - Pass Secret `toml:"pass"` - AdminEmail openapi_types.Email `toml:"admin_email"` - SenderName string `toml:"sender_name"` + Enabled bool `json:"enabled"` + Host string `json:"host"` + Port uint16 `json:"port"` + User string `json:"user"` + Pass Secret `json:"pass"` + AdminEmail openapi_types.Email `json:"admin_email"` + SenderName string `json:"sender_name"` } emailTemplate struct { - Subject *string `toml:"subject"` - Content *string `toml:"content"` + Subject *string `json:"subject"` + Content *string `json:"content"` // Only content path is accepted in config.toml - ContentPath string `toml:"content_path"` + ContentPath string `json:"content_path"` } notification struct { - Enabled bool `toml:"enabled"` + Enabled bool `json:"enabled"` emailTemplate } sms struct { - EnableSignup bool `toml:"enable_signup"` - EnableConfirmations bool `toml:"enable_confirmations"` - Template string `toml:"template"` - Twilio twilioConfig `toml:"twilio"` - TwilioVerify twilioConfig `toml:"twilio_verify"` - Messagebird messagebirdConfig `toml:"messagebird"` - Textlocal textlocalConfig `toml:"textlocal"` - Vonage vonageConfig `toml:"vonage"` - TestOTP map[string]string `toml:"test_otp"` - MaxFrequency time.Duration `toml:"max_frequency"` + EnableSignup bool `json:"enable_signup"` + EnableConfirmations bool `json:"enable_confirmations"` + Template string `json:"template"` + Twilio twilioConfig `json:"twilio"` + TwilioVerify twilioConfig `json:"twilio_verify"` + Messagebird messagebirdConfig `json:"messagebird"` + Textlocal textlocalConfig `json:"textlocal"` + Vonage vonageConfig `json:"vonage"` + TestOTP map[string]string `json:"test_otp"` + MaxFrequency time.Duration `json:"max_frequency"` } captcha struct { - Enabled bool `toml:"enabled"` - Provider CaptchaProvider `toml:"provider"` - Secret Secret `toml:"secret"` + Enabled bool `json:"enabled"` + Provider CaptchaProvider `json:"provider"` + Secret Secret `json:"secret"` } hook struct { - MFAVerificationAttempt *hookConfig `toml:"mfa_verification_attempt"` - PasswordVerificationAttempt *hookConfig `toml:"password_verification_attempt"` - CustomAccessToken *hookConfig `toml:"custom_access_token"` - SendSMS *hookConfig `toml:"send_sms"` - SendEmail *hookConfig `toml:"send_email"` - BeforeUserCreated *hookConfig `toml:"before_user_created"` + MFAVerificationAttempt *hookConfig `json:"mfa_verification_attempt"` + PasswordVerificationAttempt *hookConfig `json:"password_verification_attempt"` + CustomAccessToken *hookConfig `json:"custom_access_token"` + SendSMS *hookConfig `json:"send_sms"` + SendEmail *hookConfig `json:"send_email"` + BeforeUserCreated *hookConfig `json:"before_user_created"` } factorTypeConfiguration struct { - EnrollEnabled bool `toml:"enroll_enabled"` - VerifyEnabled bool `toml:"verify_enabled"` + EnrollEnabled bool `json:"enroll_enabled"` + VerifyEnabled bool `json:"verify_enabled"` } phoneFactorTypeConfiguration struct { factorTypeConfiguration - OtpLength uint `toml:"otp_length"` - Template string `toml:"template"` - MaxFrequency time.Duration `toml:"max_frequency"` + OtpLength uint `json:"otp_length"` + Template string `json:"template"` + MaxFrequency time.Duration `json:"max_frequency"` } mfa struct { - TOTP factorTypeConfiguration `toml:"totp"` - Phone phoneFactorTypeConfiguration `toml:"phone"` - WebAuthn factorTypeConfiguration `toml:"web_authn"` - MaxEnrolledFactors uint `toml:"max_enrolled_factors"` + TOTP factorTypeConfiguration `json:"totp"` + Phone phoneFactorTypeConfiguration `json:"phone"` + WebAuthn factorTypeConfiguration `json:"web_authn"` + MaxEnrolledFactors uint `json:"max_enrolled_factors"` } hookConfig struct { - Enabled bool `toml:"enabled"` - URI string `toml:"uri"` - Secrets Secret `toml:"secrets"` + Enabled bool `json:"enabled"` + URI string `json:"uri"` + Secrets Secret `json:"secrets"` } sessions struct { - Timebox time.Duration `toml:"timebox"` - InactivityTimeout time.Duration `toml:"inactivity_timeout"` + Timebox time.Duration `json:"timebox"` + InactivityTimeout time.Duration `json:"inactivity_timeout"` } twilioConfig struct { - Enabled bool `toml:"enabled"` - AccountSid string `toml:"account_sid"` - MessageServiceSid string `toml:"message_service_sid"` - AuthToken Secret `toml:"auth_token"` + Enabled bool `json:"enabled"` + AccountSid string `json:"account_sid"` + MessageServiceSid string `json:"message_service_sid"` + AuthToken Secret `json:"auth_token"` } messagebirdConfig struct { - Enabled bool `toml:"enabled"` - Originator string `toml:"originator"` - AccessKey Secret `toml:"access_key"` + Enabled bool `json:"enabled"` + Originator string `json:"originator"` + AccessKey Secret `json:"access_key"` } textlocalConfig struct { - Enabled bool `toml:"enabled"` - Sender string `toml:"sender"` - ApiKey Secret `toml:"api_key"` + Enabled bool `json:"enabled"` + Sender string `json:"sender"` + ApiKey Secret `json:"api_key"` } vonageConfig struct { - Enabled bool `toml:"enabled"` - From string `toml:"from"` - ApiKey string `toml:"api_key"` - ApiSecret Secret `toml:"api_secret"` + Enabled bool `json:"enabled"` + From string `json:"from"` + ApiKey string `json:"api_key"` + ApiSecret Secret `json:"api_secret"` } provider struct { - Enabled bool `toml:"enabled"` - ClientId string `toml:"client_id"` - Secret Secret `toml:"secret"` - Url string `toml:"url"` - RedirectUri string `toml:"redirect_uri"` - SkipNonceCheck bool `toml:"skip_nonce_check"` - EmailOptional bool `toml:"email_optional"` + Enabled bool `json:"enabled"` + ClientId string `json:"client_id"` + Secret Secret `json:"secret"` + Url string `json:"url"` + RedirectUri string `json:"redirect_uri"` + SkipNonceCheck bool `json:"skip_nonce_check"` + EmailOptional bool `json:"email_optional"` } solana struct { - Enabled bool `toml:"enabled"` + Enabled bool `json:"enabled"` } ethereum struct { - Enabled bool `toml:"enabled"` + Enabled bool `json:"enabled"` } web3 struct { - Solana solana `toml:"solana"` - Ethereum ethereum `toml:"ethereum"` + Solana solana `json:"solana"` + Ethereum ethereum `json:"ethereum"` } OAuthServer struct { - Enabled bool `toml:"enabled"` - AllowDynamicRegistration bool `toml:"allow_dynamic_registration"` - AuthorizationUrlPath string `toml:"authorization_url_path"` + Enabled bool `json:"enabled"` + AllowDynamicRegistration bool `json:"allow_dynamic_registration"` + AuthorizationUrlPath string `json:"authorization_url_path"` } ) diff --git a/pkg/config/config.go b/pkg/config/config.go index 8cf2e4a278..91c3fdafca 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -138,112 +138,112 @@ func (g Glob) Files(fsys fs.FS) ([]string, error) { type ( // Common config fields between our "base" config and any "remote" branch specific baseConfig struct { - ProjectId string `toml:"project_id"` - Hostname string `toml:"-"` - Api api `toml:"api"` - Db db `toml:"db"` - Realtime realtime `toml:"realtime"` - Studio studio `toml:"studio"` - Inbucket inbucket `toml:"inbucket"` - Storage storage `toml:"storage"` - Auth auth `toml:"auth"` - EdgeRuntime edgeRuntime `toml:"edge_runtime"` - Functions FunctionConfig `toml:"functions"` - Analytics analytics `toml:"analytics"` - Experimental experimental `toml:"experimental"` + ProjectId string `json:"project_id"` + Hostname string `json:"-"` + Api api `json:"api"` + Db db `json:"db"` + Realtime realtime `json:"realtime"` + Studio studio `json:"studio"` + Inbucket inbucket `json:"inbucket"` + Storage storage `json:"storage"` + Auth auth `json:"auth"` + EdgeRuntime edgeRuntime `json:"edge_runtime"` + Functions FunctionConfig `json:"functions"` + Analytics analytics `json:"analytics"` + Experimental experimental `json:"experimental"` } config struct { baseConfig - Remotes map[string]baseConfig `toml:"remotes"` + Remotes map[string]baseConfig `json:"remotes"` } realtime struct { - Enabled bool `toml:"enabled"` - Image string `toml:"-"` - IpVersion AddressFamily `toml:"ip_version"` - MaxHeaderLength uint `toml:"max_header_length"` - TenantId string `toml:"-"` - EncryptionKey string `toml:"-"` - SecretKeyBase string `toml:"-"` + Enabled bool `json:"enabled"` + Image string `json:"-"` + IpVersion AddressFamily `json:"ip_version"` + MaxHeaderLength uint `json:"max_header_length"` + TenantId string `json:"-"` + EncryptionKey string `json:"-"` + SecretKeyBase string `json:"-"` } studio struct { - Enabled bool `toml:"enabled"` - Image string `toml:"-"` - Port uint16 `toml:"port"` - ApiUrl string `toml:"api_url"` - OpenaiApiKey Secret `toml:"openai_api_key"` - PgmetaImage string `toml:"-"` + Enabled bool `json:"enabled"` + Image string `json:"-"` + Port uint16 `json:"port"` + ApiUrl string `json:"api_url"` + OpenaiApiKey Secret `json:"openai_api_key"` + PgmetaImage string `json:"-"` } inbucket struct { - Enabled bool `toml:"enabled"` - Image string `toml:"-"` - Port uint16 `toml:"port"` - SmtpPort uint16 `toml:"smtp_port"` - Pop3Port uint16 `toml:"pop3_port"` - AdminEmail string `toml:"admin_email"` - SenderName string `toml:"sender_name"` + Enabled bool `json:"enabled"` + Image string `json:"-"` + Port uint16 `json:"port"` + SmtpPort uint16 `json:"smtp_port"` + Pop3Port uint16 `json:"pop3_port"` + AdminEmail string `json:"admin_email"` + SenderName string `json:"sender_name"` } edgeRuntime struct { - Enabled bool `toml:"enabled"` - Image string `toml:"-"` - Policy RequestPolicy `toml:"policy"` - InspectorPort uint16 `toml:"inspector_port"` - Secrets SecretsConfig `toml:"secrets"` - DenoVersion uint `toml:"deno_version"` + Enabled bool `json:"enabled"` + Image string `json:"-"` + Policy RequestPolicy `json:"policy"` + InspectorPort uint16 `json:"inspector_port"` + Secrets SecretsConfig `json:"secrets"` + DenoVersion uint `json:"deno_version"` } SecretsConfig map[string]Secret FunctionConfig map[string]function function struct { - Enabled bool `toml:"enabled" json:"-"` - VerifyJWT bool `toml:"verify_jwt" json:"verifyJWT"` - ImportMap string `toml:"import_map" json:"importMapPath,omitempty"` - Entrypoint string `toml:"entrypoint" json:"entrypointPath,omitempty"` - StaticFiles Glob `toml:"static_files" json:"staticFiles,omitempty"` + Enabled bool `json:"enabled"` + VerifyJWT bool `json:"verify_jwt"` + ImportMap string `json:"import_map"` + Entrypoint string `json:"entrypoint"` + StaticFiles Glob `json:"static_files"` } analytics struct { - Enabled bool `toml:"enabled"` - Image string `toml:"-"` - VectorImage string `toml:"-"` - Port uint16 `toml:"port"` - Backend LogflareBackend `toml:"backend"` - GcpProjectId string `toml:"gcp_project_id"` - GcpProjectNumber string `toml:"gcp_project_number"` - GcpJwtPath string `toml:"gcp_jwt_path"` - ApiKey string `toml:"-"` + Enabled bool `json:"enabled"` + Image string `json:"-"` + VectorImage string `json:"-"` + Port uint16 `json:"port"` + Backend LogflareBackend `json:"backend"` + GcpProjectId string `json:"gcp_project_id"` + GcpProjectNumber string `json:"gcp_project_number"` + GcpJwtPath string `json:"gcp_jwt_path"` + ApiKey string `json:"-"` // Deprecated together with syslog - VectorPort uint16 `toml:"vector_port"` + VectorPort uint16 `json:"vector_port"` } webhooks struct { - Enabled bool `toml:"enabled"` + Enabled bool `json:"enabled"` } inspect struct { - Rules []rule `toml:"rules"` + Rules []rule `json:"rules"` } rule struct { - Query string `toml:"query"` - Name string `toml:"name"` - Pass string `toml:"pass"` - Fail string `toml:"fail"` + Query string `json:"query"` + Name string `json:"name"` + Pass string `json:"pass"` + Fail string `json:"fail"` } experimental struct { - OrioleDBVersion string `toml:"orioledb_version"` - S3Host string `toml:"s3_host"` - S3Region string `toml:"s3_region"` - S3AccessKey string `toml:"s3_access_key"` - S3SecretKey string `toml:"s3_secret_key"` - Webhooks *webhooks `toml:"webhooks"` - Inspect inspect `toml:"inspect"` + OrioleDBVersion string `json:"orioledb_version"` + S3Host string `json:"s3_host"` + S3Region string `json:"s3_region"` + S3AccessKey string `json:"s3_access_key"` + S3SecretKey string `json:"s3_secret_key"` + Webhooks *webhooks `json:"webhooks"` + Inspect inspect `json:"inspect"` } ) @@ -551,7 +551,7 @@ func (c *config) load(v *viper.Viper) error { } } if err := v.UnmarshalExact(c, func(dc *mapstructure.DecoderConfig) { - dc.TagName = "toml" + dc.TagName = "json" dc.Squash = true dc.ZeroFields = true dc.DecodeHook = c.newDecodeHook(LoadEnvHook, ValidateFunctionsHook) diff --git a/pkg/config/db.go b/pkg/config/db.go index 122f5364bc..d98b9a4a86 100644 --- a/pkg/config/db.go +++ b/pkg/config/db.go @@ -44,74 +44,74 @@ func (r *SessionReplicationRole) UnmarshalText(text []byte) error { type ( settings struct { - EffectiveCacheSize *string `toml:"effective_cache_size"` - LogicalDecodingWorkMem *string `toml:"logical_decoding_work_mem"` - MaintenanceWorkMem *string `toml:"maintenance_work_mem"` - MaxConnections *uint `toml:"max_connections"` - MaxLocksPerTransaction *uint `toml:"max_locks_per_transaction"` - MaxParallelMaintenanceWorkers *uint `toml:"max_parallel_maintenance_workers"` - MaxParallelWorkers *uint `toml:"max_parallel_workers"` - MaxParallelWorkersPerGather *uint `toml:"max_parallel_workers_per_gather"` - MaxReplicationSlots *uint `toml:"max_replication_slots"` - MaxSlotWalKeepSize *string `toml:"max_slot_wal_keep_size"` - MaxStandbyArchiveDelay *string `toml:"max_standby_archive_delay"` - MaxStandbyStreamingDelay *string `toml:"max_standby_streaming_delay"` - MaxWalSize *string `toml:"max_wal_size"` - MaxWalSenders *uint `toml:"max_wal_senders"` - MaxWorkerProcesses *uint `toml:"max_worker_processes"` - SessionReplicationRole *SessionReplicationRole `toml:"session_replication_role"` - SharedBuffers *string `toml:"shared_buffers"` - StatementTimeout *string `toml:"statement_timeout"` - TrackActivityQuerySize *string `toml:"track_activity_query_size"` - TrackCommitTimestamp *bool `toml:"track_commit_timestamp"` - WalKeepSize *string `toml:"wal_keep_size"` - WalSenderTimeout *string `toml:"wal_sender_timeout"` - WorkMem *string `toml:"work_mem"` + EffectiveCacheSize *string `json:"effective_cache_size"` + LogicalDecodingWorkMem *string `json:"logical_decoding_work_mem"` + MaintenanceWorkMem *string `json:"maintenance_work_mem"` + MaxConnections *uint `json:"max_connections"` + MaxLocksPerTransaction *uint `json:"max_locks_per_transaction"` + MaxParallelMaintenanceWorkers *uint `json:"max_parallel_maintenance_workers"` + MaxParallelWorkers *uint `json:"max_parallel_workers"` + MaxParallelWorkersPerGather *uint `json:"max_parallel_workers_per_gather"` + MaxReplicationSlots *uint `json:"max_replication_slots"` + MaxSlotWalKeepSize *string `json:"max_slot_wal_keep_size"` + MaxStandbyArchiveDelay *string `json:"max_standby_archive_delay"` + MaxStandbyStreamingDelay *string `json:"max_standby_streaming_delay"` + MaxWalSize *string `json:"max_wal_size"` + MaxWalSenders *uint `json:"max_wal_senders"` + MaxWorkerProcesses *uint `json:"max_worker_processes"` + SessionReplicationRole *SessionReplicationRole `json:"session_replication_role"` + SharedBuffers *string `json:"shared_buffers"` + StatementTimeout *string `json:"statement_timeout"` + TrackActivityQuerySize *string `json:"track_activity_query_size"` + TrackCommitTimestamp *bool `json:"track_commit_timestamp"` + WalKeepSize *string `json:"wal_keep_size"` + WalSenderTimeout *string `json:"wal_sender_timeout"` + WorkMem *string `json:"work_mem"` } networkRestrictions struct { - Enabled bool `toml:"enabled"` - AllowedCidrs []string `toml:"allowed_cidrs"` - AllowedCidrsV6 []string `toml:"allowed_cidrs_v6"` + Enabled bool `json:"enabled"` + AllowedCidrs []string `json:"allowed_cidrs"` + AllowedCidrsV6 []string `json:"allowed_cidrs_v6"` } db struct { - Image string `toml:"-"` - Port uint16 `toml:"port"` - ShadowPort uint16 `toml:"shadow_port"` - HealthTimeout time.Duration `toml:"health_timeout"` - MajorVersion uint `toml:"major_version"` - Password string `toml:"-"` - RootKey Secret `toml:"root_key"` - Pooler pooler `toml:"pooler"` - Migrations migrations `toml:"migrations"` - Seed seed `toml:"seed"` - Settings settings `toml:"settings"` - NetworkRestrictions networkRestrictions `toml:"network_restrictions"` - Vault map[string]Secret `toml:"vault"` + Image string `json:"-"` + Port uint16 `json:"port"` + ShadowPort uint16 `json:"shadow_port"` + HealthTimeout time.Duration `json:"health_timeout"` + MajorVersion uint `json:"major_version"` + Password string `json:"-"` + RootKey Secret `json:"root_key"` + Pooler pooler `json:"pooler"` + Migrations migrations `json:"migrations"` + Seed seed `json:"seed"` + Settings settings `json:"settings"` + NetworkRestrictions networkRestrictions `json:"network_restrictions"` + Vault map[string]Secret `json:"vault"` } migrations struct { - Enabled bool `toml:"enabled"` - SchemaPaths Glob `toml:"schema_paths"` + Enabled bool `json:"enabled"` + SchemaPaths Glob `json:"schema_paths"` } seed struct { - Enabled bool `toml:"enabled"` - SqlPaths Glob `toml:"sql_paths"` + Enabled bool `json:"enabled"` + SqlPaths Glob `json:"sql_paths"` } pooler struct { - Enabled bool `toml:"enabled"` - Image string `toml:"-"` - Port uint16 `toml:"port"` - PoolMode PoolMode `toml:"pool_mode"` - DefaultPoolSize uint `toml:"default_pool_size"` - MaxClientConn uint `toml:"max_client_conn"` - ConnectionString string `toml:"-"` - TenantId string `toml:"-"` - EncryptionKey string `toml:"-"` - SecretKeyBase string `toml:"-"` + Enabled bool `json:"enabled"` + Image string `json:"-"` + Port uint16 `json:"port"` + PoolMode PoolMode `json:"pool_mode"` + DefaultPoolSize uint `json:"default_pool_size"` + MaxClientConn uint `json:"max_client_conn"` + ConnectionString string `json:"-"` + TenantId string `json:"-"` + EncryptionKey string `json:"-"` + SecretKeyBase string `json:"-"` } ) diff --git a/pkg/config/storage.go b/pkg/config/storage.go index 7fdffb3a85..8645e797e8 100644 --- a/pkg/config/storage.go +++ b/pkg/config/storage.go @@ -8,55 +8,55 @@ import ( type ( storage struct { - Enabled bool `toml:"enabled"` - Image string `toml:"-"` - TargetMigration string `toml:"-"` - ImgProxyImage string `toml:"-"` - FileSizeLimit sizeInBytes `toml:"file_size_limit"` - ImageTransformation *imageTransformation `toml:"image_transformation"` - S3Protocol *s3Protocol `toml:"s3_protocol"` - S3Credentials storageS3Credentials `toml:"-"` - Buckets BucketConfig `toml:"buckets"` - AnalyticsBuckets analyticsBuckets `toml:"analytics"` - VectorBuckets vectorBuckets `toml:"vector"` + Enabled bool `json:"enabled"` + Image string `json:"-"` + TargetMigration string `json:"-"` + ImgProxyImage string `json:"-"` + FileSizeLimit sizeInBytes `json:"file_size_limit"` + ImageTransformation *imageTransformation `json:"image_transformation"` + S3Protocol *s3Protocol `json:"s3_protocol"` + S3Credentials storageS3Credentials `json:"-"` + Buckets BucketConfig `json:"buckets"` + AnalyticsBuckets analyticsBuckets `json:"analytics"` + VectorBuckets vectorBuckets `json:"vector"` } imageTransformation struct { - Enabled bool `toml:"enabled"` + Enabled bool `json:"enabled"` } analyticsBuckets struct { - Enabled bool `toml:"enabled"` - MaxNamespaces uint `toml:"max_namespaces"` - MaxTables uint `toml:"max_tables"` - MaxCatalogs uint `toml:"max_catalogs"` - Buckets map[string]struct{} `toml:"buckets"` + Enabled bool `json:"enabled"` + MaxNamespaces uint `json:"max_namespaces"` + MaxTables uint `json:"max_tables"` + MaxCatalogs uint `json:"max_catalogs"` + Buckets map[string]struct{} `json:"buckets"` } vectorBuckets struct { - Enabled bool `toml:"enabled"` - MaxBuckets uint `toml:"max_buckets"` - MaxIndexes uint `toml:"max_indexes"` - Buckets map[string]struct{} `toml:"buckets"` + Enabled bool `json:"enabled"` + MaxBuckets uint `json:"max_buckets"` + MaxIndexes uint `json:"max_indexes"` + Buckets map[string]struct{} `json:"buckets"` } s3Protocol struct { - Enabled bool `toml:"enabled"` + Enabled bool `json:"enabled"` } storageS3Credentials struct { - AccessKeyId string `toml:"-"` - SecretAccessKey string `toml:"-"` - Region string `toml:"-"` + AccessKeyId string `json:"-"` + SecretAccessKey string `json:"-"` + Region string `json:"-"` } BucketConfig map[string]bucket bucket struct { - Public *bool `toml:"public"` - FileSizeLimit sizeInBytes `toml:"file_size_limit"` - AllowedMimeTypes []string `toml:"allowed_mime_types"` - ObjectsPath string `toml:"objects_path"` + Public *bool `json:"public"` + FileSizeLimit sizeInBytes `json:"file_size_limit"` + AllowedMimeTypes []string `json:"allowed_mime_types"` + ObjectsPath string `json:"objects_path"` } ) From 61a13874648eedd59cad2caba03f7035034f7c77 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Sat, 31 Jan 2026 02:53:05 +0800 Subject: [PATCH 007/117] chore: add jsonschema generation tool --- go.mod | 1 + go.sum | 2 ++ tools/jsonschema/main.go | 45 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 tools/jsonschema/main.go diff --git a/go.mod b/go.mod index 076ee3333e..d1c28a08db 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( github.com/golang-jwt/jwt/v5 v5.3.1 github.com/google/go-github/v62 v62.0.0 github.com/google/go-querystring v1.2.0 + github.com/google/jsonschema-go v0.4.2 github.com/google/uuid v1.6.0 github.com/h2non/gock v1.2.0 github.com/jackc/pgconn v1.14.3 diff --git a/go.sum b/go.sum index 35bb7a8b2b..30a8f520b5 100644 --- a/go.sum +++ b/go.sum @@ -499,6 +499,8 @@ github.com/google/go-querystring v1.2.0/go.mod h1:8IFJqpSRITyJ8QhQ13bmbeMBDfmeEJ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8= +github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= diff --git a/tools/jsonschema/main.go b/tools/jsonschema/main.go new file mode 100644 index 0000000000..507ae338e5 --- /dev/null +++ b/tools/jsonschema/main.go @@ -0,0 +1,45 @@ +package main + +import ( + "bytes" + "encoding/json" + "fmt" + "reflect" + + "github.com/google/jsonschema-go/jsonschema" + "github.com/supabase/cli/pkg/config" +) + +func main() { + if err := run(); err != nil { + panic(err) + } +} + +func run() error { + secret, err := jsonschema.For[config.Secret](&jsonschema.ForOptions{}) + if err != nil { + return err + } + secretSchema, err := json.Marshal(secret) + if err != nil { + return err + } + // Replace secret schema because TypeSchemas is not working + opts := &jsonschema.ForOptions{ + TypeSchemas: map[reflect.Type]*jsonschema.Schema{ + reflect.TypeFor[config.Secret](): {Type: "string"}, + }, + } + js, err := jsonschema.For[config.Config](opts) + if err != nil { + return err + } + data, err := json.Marshal(js) + if err != nil { + return err + } + result := bytes.ReplaceAll(data, secretSchema, []byte(`{"type":"string"}`)) + _, err = fmt.Println(string(result)) + return err +} From f084b6dbaf9faf983d1a0898abc8cfee18cdfa4c Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Sat, 31 Jan 2026 03:00:03 +0800 Subject: [PATCH 008/117] fix: inject read only config json to studio --- internal/start/start.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/start/start.go b/internal/start/start.go index c35efa2e36..aa409d44af 100644 --- a/internal/start/start.go +++ b/internal/start/start.go @@ -1147,6 +1147,10 @@ EOF } // Mount snippets directory for Studio to access + studioConfig, err := json.Marshal(utils.Config) + if err != nil { + return errors.Errorf("failed to marshal config: %w", err) + } hostSnippetsPath := filepath.Join(workdir, utils.SnippetsDir) containerSnippetsPath := utils.ToDockerPath(hostSnippetsPath) binds = append(binds, fmt.Sprintf("%s:%s:rw", hostSnippetsPath, containerSnippetsPath)) @@ -1171,6 +1175,7 @@ EOF fmt.Sprintf("NEXT_ANALYTICS_BACKEND_PROVIDER=%v", utils.Config.Analytics.Backend), "EDGE_FUNCTIONS_MANAGEMENT_FOLDER=" + utils.ToDockerPath(filepath.Join(workdir, utils.FunctionsDir)), "SNIPPETS_MANAGEMENT_FOLDER=" + containerSnippetsPath, + "SUPABASE_CONFIG=" + string(studioConfig), // Ref: https://github.com/vercel/next.js/issues/51684#issuecomment-1612834913 "HOSTNAME=0.0.0.0", }, From 744f0793fd9a626f7ed7ccda83eaf492165f563c Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Sat, 31 Jan 2026 03:33:18 +0800 Subject: [PATCH 009/117] chore: add back toml tags --- pkg/config/api.go | 28 ++-- pkg/config/auth.go | 312 +++++++++++++++++++++--------------------- pkg/config/config.go | 136 +++++++++--------- pkg/config/db.go | 106 +++++++------- pkg/config/storage.go | 58 ++++---- 5 files changed, 320 insertions(+), 320 deletions(-) diff --git a/pkg/config/api.go b/pkg/config/api.go index e8e8aaf843..3fd3b6f187 100644 --- a/pkg/config/api.go +++ b/pkg/config/api.go @@ -10,25 +10,25 @@ import ( type ( api struct { - Enabled bool `json:"enabled"` - Schemas []string `json:"schemas"` - ExtraSearchPath []string `json:"extra_search_path"` - MaxRows uint `json:"max_rows"` + Enabled bool `toml:"enabled" json:"enabled"` + Schemas []string `toml:"schemas" json:"schemas"` + ExtraSearchPath []string `toml:"extra_search_path" json:"extra_search_path"` + MaxRows uint `toml:"max_rows" json:"max_rows"` // Local only config - Image string `json:"-"` - KongImage string `json:"-"` - Port uint16 `json:"port"` - Tls tlsKong `json:"tls"` + Image string `toml:"-" json:"-"` + KongImage string `toml:"-" json:"-"` + Port uint16 `toml:"port" json:"port"` + Tls tlsKong `toml:"tls" json:"tls"` // TODO: replace [auth|studio].api_url - ExternalUrl string `json:"external_url"` + ExternalUrl string `toml:"external_url" json:"external_url"` } tlsKong struct { - Enabled bool `json:"enabled"` - CertPath string `json:"cert_path"` - CertContent []byte `json:"-"` - KeyPath string `json:"key_path"` - KeyContent []byte `json:"-"` + Enabled bool `toml:"enabled" json:"enabled"` + CertPath string `toml:"cert_path" json:"cert_path"` + CertContent []byte `toml:"-" json:"-"` + KeyPath string `toml:"key_path" json:"key_path"` + KeyContent []byte `toml:"-" json:"-"` } ) diff --git a/pkg/config/auth.go b/pkg/config/auth.go index e23f33da14..46df702d67 100644 --- a/pkg/config/auth.go +++ b/pkg/config/auth.go @@ -86,26 +86,26 @@ func (p *Algorithm) UnmarshalText(text []byte) error { } type JWK struct { - KeyType string `json:"kty"` - KeyID string `json:"kid,omitempty"` - Use string `json:"use,omitempty"` - KeyOps []string `json:"key_ops,omitempty"` - Algorithm Algorithm `json:"alg,omitempty"` - Extractable *bool `json:"ext,omitempty"` + KeyType string `toml:"kty" json:"kty"` + KeyID string `toml:"kid,omitempty" json:"kid,omitempty"` + Use string `toml:"use,omitempty" json:"use,omitempty"` + KeyOps []string `toml:"key_ops,omitempty" json:"key_ops,omitempty"` + Algorithm Algorithm `toml:"alg,omitempty" json:"alg,omitempty"` + Extractable *bool `toml:"ext,omitempty" json:"ext,omitempty"` // RSA specific fields - Modulus string `json:"n,omitempty"` - Exponent string `json:"e,omitempty"` + Modulus string `toml:"n,omitempty" json:"n,omitempty"` + Exponent string `toml:"e,omitempty" json:"e,omitempty"` // RSA private key fields - PrivateExponent string `json:"d,omitempty"` - FirstPrimeFactor string `json:"p,omitempty"` - SecondPrimeFactor string `json:"q,omitempty"` - FirstFactorCRTExponent string `json:"dp,omitempty"` - SecondFactorCRTExponent string `json:"dq,omitempty"` - FirstCRTCoefficient string `json:"qi,omitempty"` + PrivateExponent string `toml:"d,omitempty" json:"d,omitempty"` + FirstPrimeFactor string `toml:"p,omitempty" json:"p,omitempty"` + SecondPrimeFactor string `toml:"q,omitempty" json:"q,omitempty"` + FirstFactorCRTExponent string `toml:"dp,omitempty" json:"dp,omitempty"` + SecondFactorCRTExponent string `toml:"dq,omitempty" json:"dq,omitempty"` + FirstCRTCoefficient string `toml:"qi,omitempty" json:"qi,omitempty"` // EC specific fields - Curve string `json:"crv,omitempty"` - X string `json:"x,omitempty"` - Y string `json:"y,omitempty"` + Curve string `toml:"crv,omitempty" json:"crv,omitempty"` + X string `toml:"x,omitempty" json:"x,omitempty"` + Y string `toml:"y,omitempty" json:"y,omitempty"` } // ToPublicJWK converts a JWK to a public-only version by removing private key components @@ -146,242 +146,242 @@ func (j JWK) ToPublicJWK() JWK { type ( auth struct { - Enabled bool `json:"enabled"` - Image string `json:"-"` - - SiteUrl string `json:"site_url"` - AdditionalRedirectUrls []string `json:"additional_redirect_urls"` - JwtExpiry uint `json:"jwt_expiry"` - JwtIssuer string `json:"jwt_issuer"` - EnableRefreshTokenRotation bool `json:"enable_refresh_token_rotation"` - RefreshTokenReuseInterval uint `json:"refresh_token_reuse_interval"` - EnableManualLinking bool `json:"enable_manual_linking"` - EnableSignup bool `json:"enable_signup"` - EnableAnonymousSignIns bool `json:"enable_anonymous_sign_ins"` - MinimumPasswordLength uint `json:"minimum_password_length"` - PasswordRequirements PasswordRequirements `json:"password_requirements"` - SigningKeysPath string `json:"signing_keys_path"` - SigningKeys []JWK `json:"-"` - - RateLimit rateLimit `json:"rate_limit"` - Captcha *captcha `json:"captcha"` - Hook hook `json:"hook"` - MFA mfa `json:"mfa"` - Sessions sessions `json:"sessions"` - Email email `json:"email"` - Sms sms `json:"sms"` - External external `json:"external"` - Web3 web3 `json:"web3"` - OAuthServer OAuthServer `json:"oauth_server"` + Enabled bool `toml:"enabled" json:"enabled"` + Image string `toml:"-" json:"-"` + + SiteUrl string `toml:"site_url" json:"site_url"` + AdditionalRedirectUrls []string `toml:"additional_redirect_urls" json:"additional_redirect_urls"` + JwtExpiry uint `toml:"jwt_expiry" json:"jwt_expiry"` + JwtIssuer string `toml:"jwt_issuer" json:"jwt_issuer"` + EnableRefreshTokenRotation bool `toml:"enable_refresh_token_rotation" json:"enable_refresh_token_rotation"` + RefreshTokenReuseInterval uint `toml:"refresh_token_reuse_interval" json:"refresh_token_reuse_interval"` + EnableManualLinking bool `toml:"enable_manual_linking" json:"enable_manual_linking"` + EnableSignup bool `toml:"enable_signup" json:"enable_signup"` + EnableAnonymousSignIns bool `toml:"enable_anonymous_sign_ins" json:"enable_anonymous_sign_ins"` + MinimumPasswordLength uint `toml:"minimum_password_length" json:"minimum_password_length"` + PasswordRequirements PasswordRequirements `toml:"password_requirements" json:"password_requirements"` + SigningKeysPath string `toml:"signing_keys_path" json:"signing_keys_path"` + SigningKeys []JWK `toml:"-" json:"-"` + + RateLimit rateLimit `toml:"rate_limit" json:"rate_limit"` + Captcha *captcha `toml:"captcha" json:"captcha"` + Hook hook `toml:"hook" json:"hook"` + MFA mfa `toml:"mfa" json:"mfa"` + Sessions sessions `toml:"sessions" json:"sessions"` + Email email `toml:"email" json:"email"` + Sms sms `toml:"sms" json:"sms"` + External external `toml:"external" json:"external"` + Web3 web3 `toml:"web3" json:"web3"` + OAuthServer OAuthServer `toml:"oauth_server" json:"oauth_server"` // Custom secrets can be injected from .env file - PublishableKey Secret `json:"publishable_key"` - SecretKey Secret `json:"secret_key"` - JwtSecret Secret `json:"jwt_secret"` - AnonKey Secret `json:"anon_key"` - ServiceRoleKey Secret `json:"service_role_key"` + PublishableKey Secret `toml:"publishable_key" json:"publishable_key"` + SecretKey Secret `toml:"secret_key" json:"secret_key"` + JwtSecret Secret `toml:"jwt_secret" json:"jwt_secret"` + AnonKey Secret `toml:"anon_key" json:"anon_key"` + ServiceRoleKey Secret `toml:"service_role_key" json:"service_role_key"` - ThirdParty thirdParty `json:"third_party"` + ThirdParty thirdParty `toml:"third_party" json:"third_party"` } external map[string]provider thirdParty struct { - Firebase tpaFirebase `json:"firebase"` - Auth0 tpaAuth0 `json:"auth0"` - Cognito tpaCognito `json:"aws_cognito"` - Clerk tpaClerk `json:"clerk"` - WorkOs tpaWorkOs `json:"workos"` + Firebase tpaFirebase `toml:"firebase" json:"firebase"` + Auth0 tpaAuth0 `toml:"auth0" json:"auth0"` + Cognito tpaCognito `toml:"aws_cognito" json:"aws_cognito"` + Clerk tpaClerk `toml:"clerk" json:"clerk"` + WorkOs tpaWorkOs `toml:"workos" json:"workos"` } rateLimit struct { - AnonymousUsers uint `json:"anonymous_users"` - TokenRefresh uint `json:"token_refresh"` - SignInSignUps uint `json:"sign_in_sign_ups"` - TokenVerifications uint `json:"token_verifications"` - EmailSent uint `json:"email_sent"` - SmsSent uint `json:"sms_sent"` - Web3 uint `json:"web3"` + AnonymousUsers uint `toml:"anonymous_users" json:"anonymous_users"` + TokenRefresh uint `toml:"token_refresh" json:"token_refresh"` + SignInSignUps uint `toml:"sign_in_sign_ups" json:"sign_in_sign_ups"` + TokenVerifications uint `toml:"token_verifications" json:"token_verifications"` + EmailSent uint `toml:"email_sent" json:"email_sent"` + SmsSent uint `toml:"sms_sent" json:"sms_sent"` + Web3 uint `toml:"web3" json:"web3"` } tpaFirebase struct { - Enabled bool `json:"enabled"` + Enabled bool `toml:"enabled" json:"enabled"` - ProjectID string `json:"project_id"` + ProjectID string `toml:"project_id" json:"project_id"` } tpaAuth0 struct { - Enabled bool `json:"enabled"` + Enabled bool `toml:"enabled" json:"enabled"` - Tenant string `json:"tenant"` - TenantRegion string `json:"tenant_region"` + Tenant string `toml:"tenant" json:"tenant"` + TenantRegion string `toml:"tenant_region" json:"tenant_region"` } tpaCognito struct { - Enabled bool `json:"enabled"` + Enabled bool `toml:"enabled" json:"enabled"` - UserPoolID string `json:"user_pool_id"` - UserPoolRegion string `json:"user_pool_region"` + UserPoolID string `toml:"user_pool_id" json:"user_pool_id"` + UserPoolRegion string `toml:"user_pool_region" json:"user_pool_region"` } tpaClerk struct { - Enabled bool `json:"enabled"` + Enabled bool `toml:"enabled" json:"enabled"` - Domain string `json:"domain"` + Domain string `toml:"domain" json:"domain"` } tpaWorkOs struct { - Enabled bool `json:"enabled"` + Enabled bool `toml:"enabled" json:"enabled"` - IssuerUrl string `json:"issuer_url"` + IssuerUrl string `toml:"issuer_url" json:"issuer_url"` } email struct { - EnableSignup bool `json:"enable_signup"` - DoubleConfirmChanges bool `json:"double_confirm_changes"` - EnableConfirmations bool `json:"enable_confirmations"` - SecurePasswordChange bool `json:"secure_password_change"` - Template map[string]emailTemplate `json:"template"` - Notification map[string]notification `json:"notification"` - Smtp *smtp `json:"smtp"` - MaxFrequency time.Duration `json:"max_frequency"` - OtpLength uint `json:"otp_length"` - OtpExpiry uint `json:"otp_expiry"` + EnableSignup bool `toml:"enable_signup" json:"enable_signup"` + DoubleConfirmChanges bool `toml:"double_confirm_changes" json:"double_confirm_changes"` + EnableConfirmations bool `toml:"enable_confirmations" json:"enable_confirmations"` + SecurePasswordChange bool `toml:"secure_password_change" json:"secure_password_change"` + Template map[string]emailTemplate `toml:"template" json:"template"` + Notification map[string]notification `toml:"notification" json:"notification"` + Smtp *smtp `toml:"smtp" json:"smtp"` + MaxFrequency time.Duration `toml:"max_frequency" json:"max_frequency"` + OtpLength uint `toml:"otp_length" json:"otp_length"` + OtpExpiry uint `toml:"otp_expiry" json:"otp_expiry"` } smtp struct { - Enabled bool `json:"enabled"` - Host string `json:"host"` - Port uint16 `json:"port"` - User string `json:"user"` - Pass Secret `json:"pass"` - AdminEmail openapi_types.Email `json:"admin_email"` - SenderName string `json:"sender_name"` + Enabled bool `toml:"enabled" json:"enabled"` + Host string `toml:"host" json:"host"` + Port uint16 `toml:"port" json:"port"` + User string `toml:"user" json:"user"` + Pass Secret `toml:"pass" json:"pass"` + AdminEmail openapi_types.Email `toml:"admin_email" json:"admin_email"` + SenderName string `toml:"sender_name" json:"sender_name"` } emailTemplate struct { - Subject *string `json:"subject"` - Content *string `json:"content"` + Subject *string `toml:"subject" json:"subject"` + Content *string `toml:"content" json:"content"` // Only content path is accepted in config.toml - ContentPath string `json:"content_path"` + ContentPath string `toml:"content_path" json:"content_path"` } notification struct { - Enabled bool `json:"enabled"` + Enabled bool `toml:"enabled" json:"enabled"` emailTemplate } sms struct { - EnableSignup bool `json:"enable_signup"` - EnableConfirmations bool `json:"enable_confirmations"` - Template string `json:"template"` - Twilio twilioConfig `json:"twilio"` - TwilioVerify twilioConfig `json:"twilio_verify"` - Messagebird messagebirdConfig `json:"messagebird"` - Textlocal textlocalConfig `json:"textlocal"` - Vonage vonageConfig `json:"vonage"` - TestOTP map[string]string `json:"test_otp"` - MaxFrequency time.Duration `json:"max_frequency"` + EnableSignup bool `toml:"enable_signup" json:"enable_signup"` + EnableConfirmations bool `toml:"enable_confirmations" json:"enable_confirmations"` + Template string `toml:"template" json:"template"` + Twilio twilioConfig `toml:"twilio" json:"twilio"` + TwilioVerify twilioConfig `toml:"twilio_verify" json:"twilio_verify"` + Messagebird messagebirdConfig `toml:"messagebird" json:"messagebird"` + Textlocal textlocalConfig `toml:"textlocal" json:"textlocal"` + Vonage vonageConfig `toml:"vonage" json:"vonage"` + TestOTP map[string]string `toml:"test_otp" json:"test_otp"` + MaxFrequency time.Duration `toml:"max_frequency" json:"max_frequency"` } captcha struct { - Enabled bool `json:"enabled"` - Provider CaptchaProvider `json:"provider"` - Secret Secret `json:"secret"` + Enabled bool `toml:"enabled" json:"enabled"` + Provider CaptchaProvider `toml:"provider" json:"provider"` + Secret Secret `toml:"secret" json:"secret"` } hook struct { - MFAVerificationAttempt *hookConfig `json:"mfa_verification_attempt"` - PasswordVerificationAttempt *hookConfig `json:"password_verification_attempt"` - CustomAccessToken *hookConfig `json:"custom_access_token"` - SendSMS *hookConfig `json:"send_sms"` - SendEmail *hookConfig `json:"send_email"` - BeforeUserCreated *hookConfig `json:"before_user_created"` + MFAVerificationAttempt *hookConfig `toml:"mfa_verification_attempt" json:"mfa_verification_attempt"` + PasswordVerificationAttempt *hookConfig `toml:"password_verification_attempt" json:"password_verification_attempt"` + CustomAccessToken *hookConfig `toml:"custom_access_token" json:"custom_access_token"` + SendSMS *hookConfig `toml:"send_sms" json:"send_sms"` + SendEmail *hookConfig `toml:"send_email" json:"send_email"` + BeforeUserCreated *hookConfig `toml:"before_user_created" json:"before_user_created"` } factorTypeConfiguration struct { - EnrollEnabled bool `json:"enroll_enabled"` - VerifyEnabled bool `json:"verify_enabled"` + EnrollEnabled bool `toml:"enroll_enabled" json:"enroll_enabled"` + VerifyEnabled bool `toml:"verify_enabled" json:"verify_enabled"` } phoneFactorTypeConfiguration struct { factorTypeConfiguration - OtpLength uint `json:"otp_length"` - Template string `json:"template"` - MaxFrequency time.Duration `json:"max_frequency"` + OtpLength uint `toml:"otp_length" json:"otp_length"` + Template string `toml:"template" json:"template"` + MaxFrequency time.Duration `toml:"max_frequency" json:"max_frequency"` } mfa struct { - TOTP factorTypeConfiguration `json:"totp"` - Phone phoneFactorTypeConfiguration `json:"phone"` - WebAuthn factorTypeConfiguration `json:"web_authn"` - MaxEnrolledFactors uint `json:"max_enrolled_factors"` + TOTP factorTypeConfiguration `toml:"totp" json:"totp"` + Phone phoneFactorTypeConfiguration `toml:"phone" json:"phone"` + WebAuthn factorTypeConfiguration `toml:"web_authn" json:"web_authn"` + MaxEnrolledFactors uint `toml:"max_enrolled_factors" json:"max_enrolled_factors"` } hookConfig struct { - Enabled bool `json:"enabled"` - URI string `json:"uri"` - Secrets Secret `json:"secrets"` + Enabled bool `toml:"enabled" json:"enabled"` + URI string `toml:"uri" json:"uri"` + Secrets Secret `toml:"secrets" json:"secrets"` } sessions struct { - Timebox time.Duration `json:"timebox"` - InactivityTimeout time.Duration `json:"inactivity_timeout"` + Timebox time.Duration `toml:"timebox" json:"timebox"` + InactivityTimeout time.Duration `toml:"inactivity_timeout" json:"inactivity_timeout"` } twilioConfig struct { - Enabled bool `json:"enabled"` - AccountSid string `json:"account_sid"` - MessageServiceSid string `json:"message_service_sid"` - AuthToken Secret `json:"auth_token"` + Enabled bool `toml:"enabled" json:"enabled"` + AccountSid string `toml:"account_sid" json:"account_sid"` + MessageServiceSid string `toml:"message_service_sid" json:"message_service_sid"` + AuthToken Secret `toml:"auth_token" json:"auth_token"` } messagebirdConfig struct { - Enabled bool `json:"enabled"` - Originator string `json:"originator"` - AccessKey Secret `json:"access_key"` + Enabled bool `toml:"enabled" json:"enabled"` + Originator string `toml:"originator" json:"originator"` + AccessKey Secret `toml:"access_key" json:"access_key"` } textlocalConfig struct { - Enabled bool `json:"enabled"` - Sender string `json:"sender"` - ApiKey Secret `json:"api_key"` + Enabled bool `toml:"enabled" json:"enabled"` + Sender string `toml:"sender" json:"sender"` + ApiKey Secret `toml:"api_key" json:"api_key"` } vonageConfig struct { - Enabled bool `json:"enabled"` - From string `json:"from"` - ApiKey string `json:"api_key"` - ApiSecret Secret `json:"api_secret"` + Enabled bool `toml:"enabled" json:"enabled"` + From string `toml:"from" json:"from"` + ApiKey string `toml:"api_key" json:"api_key"` + ApiSecret Secret `toml:"api_secret" json:"api_secret"` } provider struct { - Enabled bool `json:"enabled"` - ClientId string `json:"client_id"` - Secret Secret `json:"secret"` - Url string `json:"url"` - RedirectUri string `json:"redirect_uri"` - SkipNonceCheck bool `json:"skip_nonce_check"` - EmailOptional bool `json:"email_optional"` + Enabled bool `toml:"enabled" json:"enabled"` + ClientId string `toml:"client_id" json:"client_id"` + Secret Secret `toml:"secret" json:"secret"` + Url string `toml:"url" json:"url"` + RedirectUri string `toml:"redirect_uri" json:"redirect_uri"` + SkipNonceCheck bool `toml:"skip_nonce_check" json:"skip_nonce_check"` + EmailOptional bool `toml:"email_optional" json:"email_optional"` } solana struct { - Enabled bool `json:"enabled"` + Enabled bool `toml:"enabled" json:"enabled"` } ethereum struct { - Enabled bool `json:"enabled"` + Enabled bool `toml:"enabled" json:"enabled"` } web3 struct { - Solana solana `json:"solana"` - Ethereum ethereum `json:"ethereum"` + Solana solana `toml:"solana" json:"solana"` + Ethereum ethereum `toml:"ethereum" json:"ethereum"` } OAuthServer struct { - Enabled bool `json:"enabled"` - AllowDynamicRegistration bool `json:"allow_dynamic_registration"` - AuthorizationUrlPath string `json:"authorization_url_path"` + Enabled bool `toml:"enabled" json:"enabled"` + AllowDynamicRegistration bool `toml:"allow_dynamic_registration" json:"allow_dynamic_registration"` + AuthorizationUrlPath string `toml:"authorization_url_path" json:"authorization_url_path"` } ) diff --git a/pkg/config/config.go b/pkg/config/config.go index 91c3fdafca..a49e84d7df 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -138,112 +138,112 @@ func (g Glob) Files(fsys fs.FS) ([]string, error) { type ( // Common config fields between our "base" config and any "remote" branch specific baseConfig struct { - ProjectId string `json:"project_id"` - Hostname string `json:"-"` - Api api `json:"api"` - Db db `json:"db"` - Realtime realtime `json:"realtime"` - Studio studio `json:"studio"` - Inbucket inbucket `json:"inbucket"` - Storage storage `json:"storage"` - Auth auth `json:"auth"` - EdgeRuntime edgeRuntime `json:"edge_runtime"` - Functions FunctionConfig `json:"functions"` - Analytics analytics `json:"analytics"` - Experimental experimental `json:"experimental"` + ProjectId string `toml:"project_id" json:"project_id"` + Hostname string `toml:"-" json:"-"` + Api api `toml:"api" json:"api"` + Db db `toml:"db" json:"db"` + Realtime realtime `toml:"realtime" json:"realtime"` + Studio studio `toml:"studio" json:"studio"` + Inbucket inbucket `toml:"inbucket" json:"inbucket"` + Storage storage `toml:"storage" json:"storage"` + Auth auth `toml:"auth" json:"auth"` + EdgeRuntime edgeRuntime `toml:"edge_runtime" json:"edge_runtime"` + Functions FunctionConfig `toml:"functions" json:"functions"` + Analytics analytics `toml:"analytics" json:"analytics"` + Experimental experimental `toml:"experimental" json:"experimental"` } config struct { baseConfig - Remotes map[string]baseConfig `json:"remotes"` + Remotes map[string]baseConfig `toml:"remotes" json:"remotes"` } realtime struct { - Enabled bool `json:"enabled"` - Image string `json:"-"` - IpVersion AddressFamily `json:"ip_version"` - MaxHeaderLength uint `json:"max_header_length"` - TenantId string `json:"-"` - EncryptionKey string `json:"-"` - SecretKeyBase string `json:"-"` + Enabled bool `toml:"enabled" json:"enabled"` + Image string `toml:"-" json:"-"` + IpVersion AddressFamily `toml:"ip_version" json:"ip_version"` + MaxHeaderLength uint `toml:"max_header_length" json:"max_header_length"` + TenantId string `toml:"-" json:"-"` + EncryptionKey string `toml:"-" json:"-"` + SecretKeyBase string `toml:"-" json:"-"` } studio struct { - Enabled bool `json:"enabled"` - Image string `json:"-"` - Port uint16 `json:"port"` - ApiUrl string `json:"api_url"` - OpenaiApiKey Secret `json:"openai_api_key"` - PgmetaImage string `json:"-"` + Enabled bool `toml:"enabled" json:"enabled"` + Image string `toml:"-" json:"-"` + Port uint16 `toml:"port" json:"port"` + ApiUrl string `toml:"api_url" json:"api_url"` + OpenaiApiKey Secret `toml:"openai_api_key" json:"openai_api_key"` + PgmetaImage string `toml:"-" json:"-"` } inbucket struct { - Enabled bool `json:"enabled"` - Image string `json:"-"` - Port uint16 `json:"port"` - SmtpPort uint16 `json:"smtp_port"` - Pop3Port uint16 `json:"pop3_port"` - AdminEmail string `json:"admin_email"` - SenderName string `json:"sender_name"` + Enabled bool `toml:"enabled" json:"enabled"` + Image string `toml:"-" json:"-"` + Port uint16 `toml:"port" json:"port"` + SmtpPort uint16 `toml:"smtp_port" json:"smtp_port"` + Pop3Port uint16 `toml:"pop3_port" json:"pop3_port"` + AdminEmail string `toml:"admin_email" json:"admin_email"` + SenderName string `toml:"sender_name" json:"sender_name"` } edgeRuntime struct { - Enabled bool `json:"enabled"` - Image string `json:"-"` - Policy RequestPolicy `json:"policy"` - InspectorPort uint16 `json:"inspector_port"` - Secrets SecretsConfig `json:"secrets"` - DenoVersion uint `json:"deno_version"` + Enabled bool `toml:"enabled" json:"enabled"` + Image string `toml:"-" json:"-"` + Policy RequestPolicy `toml:"policy" json:"policy"` + InspectorPort uint16 `toml:"inspector_port" json:"inspector_port"` + Secrets SecretsConfig `toml:"secrets" json:"secrets"` + DenoVersion uint `toml:"deno_version" json:"deno_version"` } SecretsConfig map[string]Secret FunctionConfig map[string]function function struct { - Enabled bool `json:"enabled"` - VerifyJWT bool `json:"verify_jwt"` - ImportMap string `json:"import_map"` - Entrypoint string `json:"entrypoint"` - StaticFiles Glob `json:"static_files"` + Enabled bool `toml:"enabled" json:"enabled"` + VerifyJWT bool `toml:"verify_jwt" json:"verify_jwt"` + ImportMap string `toml:"import_map" json:"import_map"` + Entrypoint string `toml:"entrypoint" json:"entrypoint"` + StaticFiles Glob `toml:"static_files" json:"static_files"` } analytics struct { - Enabled bool `json:"enabled"` - Image string `json:"-"` - VectorImage string `json:"-"` - Port uint16 `json:"port"` - Backend LogflareBackend `json:"backend"` - GcpProjectId string `json:"gcp_project_id"` - GcpProjectNumber string `json:"gcp_project_number"` - GcpJwtPath string `json:"gcp_jwt_path"` - ApiKey string `json:"-"` + Enabled bool `toml:"enabled" json:"enabled"` + Image string `toml:"-" json:"-"` + VectorImage string `toml:"-" json:"-"` + Port uint16 `toml:"port" json:"port"` + Backend LogflareBackend `toml:"backend" json:"backend"` + GcpProjectId string `toml:"gcp_project_id" json:"gcp_project_id"` + GcpProjectNumber string `toml:"gcp_project_number" json:"gcp_project_number"` + GcpJwtPath string `toml:"gcp_jwt_path" json:"gcp_jwt_path"` + ApiKey string `toml:"-" json:"-"` // Deprecated together with syslog - VectorPort uint16 `json:"vector_port"` + VectorPort uint16 `toml:"vector_port" json:"vector_port"` } webhooks struct { - Enabled bool `json:"enabled"` + Enabled bool `toml:"enabled" json:"enabled"` } inspect struct { - Rules []rule `json:"rules"` + Rules []rule `toml:"rules" json:"rules"` } rule struct { - Query string `json:"query"` - Name string `json:"name"` - Pass string `json:"pass"` - Fail string `json:"fail"` + Query string `toml:"query" json:"query"` + Name string `toml:"name" json:"name"` + Pass string `toml:"pass" json:"pass"` + Fail string `toml:"fail" json:"fail"` } experimental struct { - OrioleDBVersion string `json:"orioledb_version"` - S3Host string `json:"s3_host"` - S3Region string `json:"s3_region"` - S3AccessKey string `json:"s3_access_key"` - S3SecretKey string `json:"s3_secret_key"` - Webhooks *webhooks `json:"webhooks"` - Inspect inspect `json:"inspect"` + OrioleDBVersion string `toml:"orioledb_version" json:"orioledb_version"` + S3Host string `toml:"s3_host" json:"s3_host"` + S3Region string `toml:"s3_region" json:"s3_region"` + S3AccessKey string `toml:"s3_access_key" json:"s3_access_key"` + S3SecretKey string `toml:"s3_secret_key" json:"s3_secret_key"` + Webhooks *webhooks `toml:"webhooks" json:"webhooks"` + Inspect inspect `toml:"inspect" json:"inspect"` } ) diff --git a/pkg/config/db.go b/pkg/config/db.go index d98b9a4a86..84d4dc5043 100644 --- a/pkg/config/db.go +++ b/pkg/config/db.go @@ -44,74 +44,74 @@ func (r *SessionReplicationRole) UnmarshalText(text []byte) error { type ( settings struct { - EffectiveCacheSize *string `json:"effective_cache_size"` - LogicalDecodingWorkMem *string `json:"logical_decoding_work_mem"` - MaintenanceWorkMem *string `json:"maintenance_work_mem"` - MaxConnections *uint `json:"max_connections"` - MaxLocksPerTransaction *uint `json:"max_locks_per_transaction"` - MaxParallelMaintenanceWorkers *uint `json:"max_parallel_maintenance_workers"` - MaxParallelWorkers *uint `json:"max_parallel_workers"` - MaxParallelWorkersPerGather *uint `json:"max_parallel_workers_per_gather"` - MaxReplicationSlots *uint `json:"max_replication_slots"` - MaxSlotWalKeepSize *string `json:"max_slot_wal_keep_size"` - MaxStandbyArchiveDelay *string `json:"max_standby_archive_delay"` - MaxStandbyStreamingDelay *string `json:"max_standby_streaming_delay"` - MaxWalSize *string `json:"max_wal_size"` - MaxWalSenders *uint `json:"max_wal_senders"` - MaxWorkerProcesses *uint `json:"max_worker_processes"` - SessionReplicationRole *SessionReplicationRole `json:"session_replication_role"` - SharedBuffers *string `json:"shared_buffers"` - StatementTimeout *string `json:"statement_timeout"` - TrackActivityQuerySize *string `json:"track_activity_query_size"` - TrackCommitTimestamp *bool `json:"track_commit_timestamp"` - WalKeepSize *string `json:"wal_keep_size"` - WalSenderTimeout *string `json:"wal_sender_timeout"` - WorkMem *string `json:"work_mem"` + EffectiveCacheSize *string `toml:"effective_cache_size" json:"effective_cache_size"` + LogicalDecodingWorkMem *string `toml:"logical_decoding_work_mem" json:"logical_decoding_work_mem"` + MaintenanceWorkMem *string `toml:"maintenance_work_mem" json:"maintenance_work_mem"` + MaxConnections *uint `toml:"max_connections" json:"max_connections"` + MaxLocksPerTransaction *uint `toml:"max_locks_per_transaction" json:"max_locks_per_transaction"` + MaxParallelMaintenanceWorkers *uint `toml:"max_parallel_maintenance_workers" json:"max_parallel_maintenance_workers"` + MaxParallelWorkers *uint `toml:"max_parallel_workers" json:"max_parallel_workers"` + MaxParallelWorkersPerGather *uint `toml:"max_parallel_workers_per_gather" json:"max_parallel_workers_per_gather"` + MaxReplicationSlots *uint `toml:"max_replication_slots" json:"max_replication_slots"` + MaxSlotWalKeepSize *string `toml:"max_slot_wal_keep_size" json:"max_slot_wal_keep_size"` + MaxStandbyArchiveDelay *string `toml:"max_standby_archive_delay" json:"max_standby_archive_delay"` + MaxStandbyStreamingDelay *string `toml:"max_standby_streaming_delay" json:"max_standby_streaming_delay"` + MaxWalSize *string `toml:"max_wal_size" json:"max_wal_size"` + MaxWalSenders *uint `toml:"max_wal_senders" json:"max_wal_senders"` + MaxWorkerProcesses *uint `toml:"max_worker_processes" json:"max_worker_processes"` + SessionReplicationRole *SessionReplicationRole `toml:"session_replication_role" json:"session_replication_role"` + SharedBuffers *string `toml:"shared_buffers" json:"shared_buffers"` + StatementTimeout *string `toml:"statement_timeout" json:"statement_timeout"` + TrackActivityQuerySize *string `toml:"track_activity_query_size" json:"track_activity_query_size"` + TrackCommitTimestamp *bool `toml:"track_commit_timestamp" json:"track_commit_timestamp"` + WalKeepSize *string `toml:"wal_keep_size" json:"wal_keep_size"` + WalSenderTimeout *string `toml:"wal_sender_timeout" json:"wal_sender_timeout"` + WorkMem *string `toml:"work_mem" json:"work_mem"` } networkRestrictions struct { - Enabled bool `json:"enabled"` - AllowedCidrs []string `json:"allowed_cidrs"` - AllowedCidrsV6 []string `json:"allowed_cidrs_v6"` + Enabled bool `toml:"enabled" json:"enabled"` + AllowedCidrs []string `toml:"allowed_cidrs" json:"allowed_cidrs"` + AllowedCidrsV6 []string `toml:"allowed_cidrs_v6" json:"allowed_cidrs_v6"` } db struct { - Image string `json:"-"` - Port uint16 `json:"port"` - ShadowPort uint16 `json:"shadow_port"` - HealthTimeout time.Duration `json:"health_timeout"` - MajorVersion uint `json:"major_version"` - Password string `json:"-"` - RootKey Secret `json:"root_key"` - Pooler pooler `json:"pooler"` - Migrations migrations `json:"migrations"` - Seed seed `json:"seed"` - Settings settings `json:"settings"` - NetworkRestrictions networkRestrictions `json:"network_restrictions"` - Vault map[string]Secret `json:"vault"` + Image string `toml:"-" json:"-"` + Port uint16 `toml:"port" json:"port"` + ShadowPort uint16 `toml:"shadow_port" json:"shadow_port"` + HealthTimeout time.Duration `toml:"health_timeout" json:"health_timeout"` + MajorVersion uint `toml:"major_version" json:"major_version"` + Password string `toml:"-" json:"-"` + RootKey Secret `toml:"root_key" json:"root_key"` + Pooler pooler `toml:"pooler" json:"pooler"` + Migrations migrations `toml:"migrations" json:"migrations"` + Seed seed `toml:"seed" json:"seed"` + Settings settings `toml:"settings" json:"settings"` + NetworkRestrictions networkRestrictions `toml:"network_restrictions" json:"network_restrictions"` + Vault map[string]Secret `toml:"vault" json:"vault"` } migrations struct { - Enabled bool `json:"enabled"` - SchemaPaths Glob `json:"schema_paths"` + Enabled bool `toml:"enabled" json:"enabled"` + SchemaPaths Glob `toml:"schema_paths" json:"schema_paths"` } seed struct { - Enabled bool `json:"enabled"` - SqlPaths Glob `json:"sql_paths"` + Enabled bool `toml:"enabled" json:"enabled"` + SqlPaths Glob `toml:"sql_paths" json:"sql_paths"` } pooler struct { - Enabled bool `json:"enabled"` - Image string `json:"-"` - Port uint16 `json:"port"` - PoolMode PoolMode `json:"pool_mode"` - DefaultPoolSize uint `json:"default_pool_size"` - MaxClientConn uint `json:"max_client_conn"` - ConnectionString string `json:"-"` - TenantId string `json:"-"` - EncryptionKey string `json:"-"` - SecretKeyBase string `json:"-"` + Enabled bool `toml:"enabled" json:"enabled"` + Image string `toml:"-" json:"-"` + Port uint16 `toml:"port" json:"port"` + PoolMode PoolMode `toml:"pool_mode" json:"pool_mode"` + DefaultPoolSize uint `toml:"default_pool_size" json:"default_pool_size"` + MaxClientConn uint `toml:"max_client_conn" json:"max_client_conn"` + ConnectionString string `toml:"-" json:"-"` + TenantId string `toml:"-" json:"-"` + EncryptionKey string `toml:"-" json:"-"` + SecretKeyBase string `toml:"-" json:"-"` } ) diff --git a/pkg/config/storage.go b/pkg/config/storage.go index 8645e797e8..740c525f43 100644 --- a/pkg/config/storage.go +++ b/pkg/config/storage.go @@ -8,55 +8,55 @@ import ( type ( storage struct { - Enabled bool `json:"enabled"` - Image string `json:"-"` - TargetMigration string `json:"-"` - ImgProxyImage string `json:"-"` - FileSizeLimit sizeInBytes `json:"file_size_limit"` - ImageTransformation *imageTransformation `json:"image_transformation"` - S3Protocol *s3Protocol `json:"s3_protocol"` - S3Credentials storageS3Credentials `json:"-"` - Buckets BucketConfig `json:"buckets"` - AnalyticsBuckets analyticsBuckets `json:"analytics"` - VectorBuckets vectorBuckets `json:"vector"` + Enabled bool `toml:"enabled" json:"enabled"` + Image string `toml:"-" json:"-"` + TargetMigration string `toml:"-" json:"-"` + ImgProxyImage string `toml:"-" json:"-"` + FileSizeLimit sizeInBytes `toml:"file_size_limit" json:"file_size_limit"` + ImageTransformation *imageTransformation `toml:"image_transformation" json:"image_transformation"` + S3Protocol *s3Protocol `toml:"s3_protocol" json:"s3_protocol"` + S3Credentials storageS3Credentials `toml:"-" json:"-"` + Buckets BucketConfig `toml:"buckets" json:"buckets"` + AnalyticsBuckets analyticsBuckets `toml:"analytics" json:"analytics"` + VectorBuckets vectorBuckets `toml:"vector" json:"vector"` } imageTransformation struct { - Enabled bool `json:"enabled"` + Enabled bool `toml:"enabled" json:"enabled"` } analyticsBuckets struct { - Enabled bool `json:"enabled"` - MaxNamespaces uint `json:"max_namespaces"` - MaxTables uint `json:"max_tables"` - MaxCatalogs uint `json:"max_catalogs"` - Buckets map[string]struct{} `json:"buckets"` + Enabled bool `toml:"enabled" json:"enabled"` + MaxNamespaces uint `toml:"max_namespaces" json:"max_namespaces"` + MaxTables uint `toml:"max_tables" json:"max_tables"` + MaxCatalogs uint `toml:"max_catalogs" json:"max_catalogs"` + Buckets map[string]struct{} `toml:"buckets" json:"buckets"` } vectorBuckets struct { - Enabled bool `json:"enabled"` - MaxBuckets uint `json:"max_buckets"` - MaxIndexes uint `json:"max_indexes"` - Buckets map[string]struct{} `json:"buckets"` + Enabled bool `toml:"enabled" json:"enabled"` + MaxBuckets uint `toml:"max_buckets" json:"max_buckets"` + MaxIndexes uint `toml:"max_indexes" json:"max_indexes"` + Buckets map[string]struct{} `toml:"buckets" json:"buckets"` } s3Protocol struct { - Enabled bool `json:"enabled"` + Enabled bool `toml:"enabled" json:"enabled"` } storageS3Credentials struct { - AccessKeyId string `json:"-"` - SecretAccessKey string `json:"-"` - Region string `json:"-"` + AccessKeyId string `toml:"-" json:"-"` + SecretAccessKey string `toml:"-" json:"-"` + Region string `toml:"-" json:"-"` } BucketConfig map[string]bucket bucket struct { - Public *bool `json:"public"` - FileSizeLimit sizeInBytes `json:"file_size_limit"` - AllowedMimeTypes []string `json:"allowed_mime_types"` - ObjectsPath string `json:"objects_path"` + Public *bool `toml:"public" json:"public"` + FileSizeLimit sizeInBytes `toml:"file_size_limit" json:"file_size_limit"` + AllowedMimeTypes []string `toml:"allowed_mime_types" json:"allowed_mime_types"` + ObjectsPath string `toml:"objects_path" json:"objects_path"` } ) From 7395389ed9c5ae36b67b5b3c8aecc23cfec39ec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=83=A5=EB=83=90=EC=B1=A0?= Date: Tue, 3 Feb 2026 19:00:04 +0900 Subject: [PATCH 010/117] fix: bump edge-runtime to 1.70.1 (#4797) --- 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 bb587fe420..e48b8fc45f 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -7,7 +7,7 @@ FROM postgrest/postgrest:v14.3 AS postgrest FROM supabase/postgres-meta:v0.95.2 AS pgmeta FROM supabase/studio:2026.01.27-sha-2a37755 AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy -FROM supabase/edge-runtime:v1.70.0 AS edgeruntime +FROM supabase/edge-runtime:v1.70.1 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.186.0 AS gotrue From 3b638d33be155a9bf06079311f3c8c7e3dcd305d Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Tue, 3 Feb 2026 22:09:37 +0800 Subject: [PATCH 011/117] fix: set sslmode for pgdelta target --- internal/db/diff/pgdelta.go | 7 +++++-- internal/db/diff/templates/pgdelta.ts | 25 +++++++++++++------------ 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/internal/db/diff/pgdelta.go b/internal/db/diff/pgdelta.go index 12153068f6..0403dd91f9 100644 --- a/internal/db/diff/pgdelta.go +++ b/internal/db/diff/pgdelta.go @@ -23,12 +23,15 @@ var pgDeltaScript string func DiffPgDelta(ctx context.Context, source, target pgconn.Config, schema []string, options ...func(*pgx.ConnConfig)) (string, error) { env := []string{ "SOURCE=" + utils.ToPostgresURL(source), - "TARGET=" + utils.ToPostgresURL(target), } if ca, err := types.GetRootCA(ctx, utils.ToPostgresURL(target), options...); err != nil { return "", err } else if len(ca) > 0 { - env = append(env, "PGDELTA_TARGET_SSLROOTCERT="+ca) + target.RuntimeParams["sslmode"] = "require" + env = append(env, + "TARGET="+utils.ToPostgresURL(target), + "PGDELTA_TARGET_SSLROOTCERT="+ca, + ) } if len(schema) > 0 { env = append(env, "INCLUDED_SCHEMAS="+strings.Join(schema, ",")) diff --git a/internal/db/diff/templates/pgdelta.ts b/internal/db/diff/templates/pgdelta.ts index cfdac0aa42..3b3ddf05e2 100644 --- a/internal/db/diff/templates/pgdelta.ts +++ b/internal/db/diff/templates/pgdelta.ts @@ -4,20 +4,21 @@ import { supabase } from "npm:@supabase/pg-delta@1.0.0-alpha.2/integrations/supa const source = Deno.env.get("SOURCE"); const target = Deno.env.get("TARGET"); +const opts = { ...supabase, role: "postgres" }; const includedSchemas = Deno.env.get("INCLUDED_SCHEMAS"); if (includedSchemas) { - supabase.filter = { schema: includedSchemas.split(",") }; + opts.filter = { schema: includedSchemas.split(",") }; } -supabase.role = "postgres"; +opts.filter = { + and: [ + opts.filter, + { not: { owner: "cli_login_postgres" } }, + { not: { member: "cli_login_postgres" } }, + ], +}; -try { - const result = await createPlan(source, target, supabase); - const statements = result?.plan.statements ?? []; - for (const sql of statements) { - console.log(`${sql};`); - } -} catch (e) { - console.error(e); - // Force close event loop - throw new Error(""); +const result = await createPlan(source, target, opts); +const statements = result?.plan.statements ?? []; +for (const sql of statements) { + console.log(`${sql};`); } From 5322e6653860de5fb017acbac7ddd77eff10ae85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 14:20:52 +0000 Subject: [PATCH 012/117] fix(docker): bump the docker-minor group across 1 directory with 5 updates (#4792) Bumps the docker-minor group with 5 updates in the /pkg/config/templates directory: | Package | From | To | | --- | --- | --- | | postgrest/postgrest | `v14.3` | `v14.4` | | supabase/studio | `2026.01.27-sha-2a37755` | `2026.02.02-sha-b0b7db6` | | supabase/realtime | `v2.73.2` | `v2.74.1` | | supabase/storage-api | `v1.35.3` | `v1.36.1` | | supabase/logflare | `1.30.5` | `1.30.7` | Updates `postgrest/postgrest` from v14.3 to v14.4 Updates `supabase/studio` from 2026.01.27-sha-2a37755 to 2026.02.02-sha-b0b7db6 Updates `supabase/realtime` from v2.73.2 to v2.74.1 Updates `supabase/storage-api` from v1.35.3 to v1.36.1 Updates `supabase/logflare` from 1.30.5 to 1.30.7 --- updated-dependencies: - dependency-name: postgrest/postgrest dependency-version: v14.4 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/studio dependency-version: 2026.02.02-sha-b0b7db6 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/realtime dependency-version: v2.74.1 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/storage-api dependency-version: v1.36.1 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/logflare dependency-version: 1.30.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: docker-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index e48b8fc45f..f19be0e258 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -3,17 +3,17 @@ FROM supabase/postgres:17.6.1.075 AS pg # 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 postgrest/postgrest:v14.3 AS postgrest +FROM postgrest/postgrest:v14.4 AS postgrest FROM supabase/postgres-meta:v0.95.2 AS pgmeta -FROM supabase/studio:2026.01.27-sha-2a37755 AS studio +FROM supabase/studio:2026.02.02-sha-b0b7db6 AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy FROM supabase/edge-runtime:v1.70.1 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.186.0 AS gotrue -FROM supabase/realtime:v2.73.2 AS realtime -FROM supabase/storage-api:v1.35.3 AS storage -FROM supabase/logflare:1.30.5 AS logflare +FROM supabase/realtime:v2.74.2 AS realtime +FROM supabase/storage-api:v1.36.2 AS storage +FROM supabase/logflare:1.30.7 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 9324afd86b6df6a1380cd09977bb42a17537798b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 00:13:43 +0000 Subject: [PATCH 013/117] fix(docker): bump supabase/postgres from 17.6.1.075 to 17.6.1.079 in /pkg/config/templates (#4800) fix(docker): bump supabase/postgres in /pkg/config/templates Bumps supabase/postgres from 17.6.1.075 to 17.6.1.079. --- updated-dependencies: - dependency-name: supabase/postgres dependency-version: 17.6.1.079 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 f19be0e258..f772850e20 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:17.6.1.075 AS pg +FROM supabase/postgres:17.6.1.079 AS pg # 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 86c94973f9d62f0c2a20cd701e864971260b292a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 00:19:30 +0000 Subject: [PATCH 014/117] fix(docker): bump supabase/realtime from v2.74.2 to v2.74.4 in /pkg/config/templates in the docker-minor group (#4799) fix(docker): bump supabase/realtime Bumps the docker-minor group in /pkg/config/templates with 1 update: supabase/realtime. Updates `supabase/realtime` from v2.74.2 to v2.74.4 --- updated-dependencies: - dependency-name: supabase/realtime dependency-version: v2.74.4 dependency-type: direct:production dependency-group: docker-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 f772850e20..78ae1b6e79 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -11,7 +11,7 @@ FROM supabase/edge-runtime:v1.70.1 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.186.0 AS gotrue -FROM supabase/realtime:v2.74.2 AS realtime +FROM supabase/realtime:v2.74.4 AS realtime FROM supabase/storage-api:v1.36.2 AS storage FROM supabase/logflare:1.30.7 AS logflare # Append to JobImages when adding new dependencies below From c9dcfb5c5b4a5c535af7f53cc550f2526a761de7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 11:42:42 +0800 Subject: [PATCH 015/117] chore(deps): bump github.com/charmbracelet/bubbles from 0.21.0 to 0.21.1 in the go-minor group across 1 directory (#4801) chore(deps): bump github.com/charmbracelet/bubbles Bumps the go-minor group with 1 update in the / directory: [github.com/charmbracelet/bubbles](https://github.com/charmbracelet/bubbles). Updates `github.com/charmbracelet/bubbles` from 0.21.0 to 0.21.1 - [Release notes](https://github.com/charmbracelet/bubbles/releases) - [Commits](https://github.com/charmbracelet/bubbles/compare/v0.21.0...v0.21.1) --- updated-dependencies: - dependency-name: github.com/charmbracelet/bubbles dependency-version: 0.21.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 16 ++++++++-------- go.sum | 36 ++++++++++++++++++------------------ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index d95d9660b3..2299f14251 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/Netflix/go-env v0.1.2 github.com/andybalholm/brotli v1.2.0 github.com/cenkalti/backoff/v4 v4.3.0 - github.com/charmbracelet/bubbles v0.21.0 + github.com/charmbracelet/bubbles v0.21.1 github.com/charmbracelet/bubbletea v1.3.10 github.com/charmbracelet/glamour v0.10.0 github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 @@ -121,17 +121,17 @@ require ( github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/charithe/durationcheck v0.0.10 // indirect - github.com/charmbracelet/colorprofile v0.3.1 // indirect + github.com/charmbracelet/colorprofile v0.4.1 // indirect github.com/charmbracelet/harmonica v0.2.0 // indirect - github.com/charmbracelet/x/ansi v0.10.1 // indirect - github.com/charmbracelet/x/cellbuf v0.0.13 // indirect + github.com/charmbracelet/x/ansi v0.11.5 // indirect + github.com/charmbracelet/x/cellbuf v0.0.15 // indirect github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf // indirect - github.com/charmbracelet/x/term v0.2.1 // indirect + github.com/charmbracelet/x/term v0.2.2 // indirect github.com/chavacava/garif v0.1.0 // indirect github.com/ckaznocha/intrange v0.3.1 // indirect - github.com/clipperhouse/displaywidth v0.6.2 // indirect + github.com/clipperhouse/displaywidth v0.9.0 // indirect github.com/clipperhouse/stringish v0.1.1 // indirect - github.com/clipperhouse/uax29/v2 v2.3.0 // indirect + github.com/clipperhouse/uax29/v2 v2.5.0 // indirect github.com/cloudflare/circl v1.6.1 // indirect github.com/containerd/console v1.0.5 // indirect github.com/containerd/containerd/api v1.9.0 // indirect @@ -267,7 +267,7 @@ require ( github.com/leodido/go-urn v1.4.0 // indirect github.com/leonklingele/grouper v1.1.2 // indirect github.com/lib/pq v1.10.9 // indirect - github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/lucasb-eyer/go-colorful v1.3.0 // indirect github.com/macabu/inamedparam v0.2.0 // indirect github.com/mailru/easyjson v0.9.0 // indirect github.com/manuelarte/funcorder v0.2.1 // indirect diff --git a/go.sum b/go.sum index baae9c767f..b1024fe790 100644 --- a/go.sum +++ b/go.sum @@ -112,8 +112,8 @@ github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE= github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= -github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8= -github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA= +github.com/aymanbagabas/go-udiff v0.3.1 h1:LV+qyBQ2pqe0u42ZsUEtPiCaUoqgA9gYRDs3vj1nolY= +github.com/aymanbagabas/go-udiff v0.3.1/go.mod h1:G0fsKmG+P6ylD0r6N/KgQD/nWzgfnl8ZBcNLgcbrw8E= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v0.0.0-20150223135152-b965b613227f/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -161,28 +161,28 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charithe/durationcheck v0.0.10 h1:wgw73BiocdBDQPik+zcEoBG/ob8uyBHf2iyoHGPf5w4= github.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ= -github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs= -github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg= +github.com/charmbracelet/bubbles v0.21.1 h1:nj0decPiixaZeL9diI4uzzQTkkz1kYY8+jgzCZXSmW0= +github.com/charmbracelet/bubbles v0.21.1/go.mod h1:HHvIYRCpbkCJw2yo0vNX1O5loCwSr9/mWS8GYSg50Sk= github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= -github.com/charmbracelet/colorprofile v0.3.1 h1:k8dTHMd7fgw4bnFd7jXTLZrSU/CQrKnL3m+AxCzDz40= -github.com/charmbracelet/colorprofile v0.3.1/go.mod h1:/GkGusxNs8VB/RSOh3fu0TJmQ4ICMMPApIIVn0KszZ0= +github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk= +github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk= github.com/charmbracelet/glamour v0.10.0 h1:MtZvfwsYCx8jEPFJm3rIBFIMZUfUJ765oX8V6kXldcY= github.com/charmbracelet/glamour v0.10.0/go.mod h1:f+uf+I/ChNmqo087elLnVdCiVgjSKWuXa/l6NU2ndYk= github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 h1:ZR7e0ro+SZZiIZD7msJyA+NjkCNNavuiPBLgerbOziE= github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834/go.mod h1:aKC/t2arECF6rNOnaKaVU6y4t4ZeHQzqfxedE/VkVhA= -github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ= -github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE= -github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k= -github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= +github.com/charmbracelet/x/ansi v0.11.5 h1:NBWeBpj/lJPE3Q5l+Lusa4+mH6v7487OP8K0r1IhRg4= +github.com/charmbracelet/x/ansi v0.11.5/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ= +github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI= +github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q= github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ= github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U= github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf h1:rLG0Yb6MQSDKdB52aGX55JT1oi0P0Kuaj7wi1bLUpnI= github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf/go.mod h1:B3UgsnsBZS/eX42BlaNiJkD1pPOUa+oF1IYC6Yd2CEU= -github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= -github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= +github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= +github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= github.com/chavacava/garif v0.1.0 h1:2JHa3hbYf5D9dsgseMKAmc/MZ109otzgNFk5s87H9Pc= github.com/chavacava/garif v0.1.0/go.mod h1:XMyYCkEL58DF0oyW4qDjjnPWONs2HBqYKI+UIPD+Gww= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -190,12 +190,12 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/ckaznocha/intrange v0.3.1 h1:j1onQyXvHUsPWujDH6WIjhyH26gkRt/txNlV7LspvJs= github.com/ckaznocha/intrange v0.3.1/go.mod h1:QVepyz1AkUoFQkpEqksSYpNpUo3c5W7nWh/s6SHIJJk= -github.com/clipperhouse/displaywidth v0.6.2 h1:ZDpTkFfpHOKte4RG5O/BOyf3ysnvFswpyYrV7z2uAKo= -github.com/clipperhouse/displaywidth v0.6.2/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o= +github.com/clipperhouse/displaywidth v0.9.0 h1:Qb4KOhYwRiN3viMv1v/3cTBlz3AcAZX3+y9OLhMtAtA= +github.com/clipperhouse/displaywidth v0.9.0/go.mod h1:aCAAqTlh4GIVkhQnJpbL0T/WfcrJXHcj8C0yjYcjOZA= github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= -github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= -github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= +github.com/clipperhouse/uax29/v2 v2.5.0 h1:x7T0T4eTHDONxFJsL94uKNKPHrclyFI0lm7+w94cO8U= +github.com/clipperhouse/uax29/v2 v2.5.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= 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.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= @@ -698,8 +698,8 @@ github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= -github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= +github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/macabu/inamedparam v0.2.0 h1:VyPYpOc10nkhI2qeNUdh3Zket4fcZjEWe35poddBCpE= github.com/macabu/inamedparam v0.2.0/go.mod h1:+Pee9/YfGe5LJ62pYXqB89lJ+0k5bsR8Wgz/C0Zlq3U= github.com/magiconair/properties v1.5.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= From df1203c130b7ecb8b869a44f786a713121dc7e5f Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Wed, 4 Feb 2026 17:49:42 +0800 Subject: [PATCH 016/117] chore: upgrade pgdelta to prerelease --- internal/db/diff/templates/pgdelta.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/internal/db/diff/templates/pgdelta.ts b/internal/db/diff/templates/pgdelta.ts index 3b3ddf05e2..a8bbd65b4c 100644 --- a/internal/db/diff/templates/pgdelta.ts +++ b/internal/db/diff/templates/pgdelta.ts @@ -1,5 +1,5 @@ -import { createPlan } from "npm:@supabase/pg-delta@1.0.0-alpha.2"; -import { supabase } from "npm:@supabase/pg-delta@1.0.0-alpha.2/integrations/supabase"; +import { createPlan } from "npm:@supabase/pg-delta@1.0.0-alpha.3"; +import { supabase } from "npm:@supabase/pg-delta@1.0.0-alpha.3/integrations/supabase"; const source = Deno.env.get("SOURCE"); const target = Deno.env.get("TARGET"); @@ -9,13 +9,6 @@ const includedSchemas = Deno.env.get("INCLUDED_SCHEMAS"); if (includedSchemas) { opts.filter = { schema: includedSchemas.split(",") }; } -opts.filter = { - and: [ - opts.filter, - { not: { owner: "cli_login_postgres" } }, - { not: { member: "cli_login_postgres" } }, - ], -}; const result = await createPlan(source, target, opts); const statements = result?.plan.statements ?? []; From 087fa5091353a75032b2b50e04dda656f8bdce91 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 00:13:42 +0000 Subject: [PATCH 017/117] fix(docker): bump supabase/postgres from 17.6.1.079 to 17.6.1.080 in /pkg/config/templates (#4809) fix(docker): bump supabase/postgres in /pkg/config/templates Bumps supabase/postgres from 17.6.1.079 to 17.6.1.080. --- updated-dependencies: - dependency-name: supabase/postgres dependency-version: 17.6.1.080 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 78ae1b6e79..80be28ab8f 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:17.6.1.079 AS pg +FROM supabase/postgres:17.6.1.080 AS pg # 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 31b8ffab1905f9d8c5acce1b32dec17e538c18cb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 00:19:14 +0000 Subject: [PATCH 018/117] fix(docker): bump the docker-minor group in /pkg/config/templates with 4 updates (#4808) fix(docker): bump the docker-minor group Bumps the docker-minor group in /pkg/config/templates with 4 updates: supabase/studio, supabase/realtime, supabase/storage-api and supabase/logflare. Updates `supabase/studio` from 2026.02.02-sha-b0b7db6 to 2026.02.04-sha-fba1944 Updates `supabase/realtime` from v2.74.4 to v2.74.7 Updates `supabase/storage-api` from v1.36.2 to v1.37.0 Updates `supabase/logflare` from 1.30.7 to 1.30.8 --- updated-dependencies: - dependency-name: supabase/studio dependency-version: 2026.02.04-sha-fba1944 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/realtime dependency-version: v2.74.7 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/storage-api dependency-version: v1.37.0 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/logflare dependency-version: 1.30.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: docker-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 80be28ab8f..b79c943766 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -5,15 +5,15 @@ FROM library/kong:2.8.1 AS kong FROM axllent/mailpit:v1.22.3 AS mailpit FROM postgrest/postgrest:v14.4 AS postgrest FROM supabase/postgres-meta:v0.95.2 AS pgmeta -FROM supabase/studio:2026.02.02-sha-b0b7db6 AS studio +FROM supabase/studio:2026.02.04-sha-fba1944 AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy FROM supabase/edge-runtime:v1.70.1 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.186.0 AS gotrue -FROM supabase/realtime:v2.74.4 AS realtime -FROM supabase/storage-api:v1.36.2 AS storage -FROM supabase/logflare:1.30.7 AS logflare +FROM supabase/realtime:v2.74.7 AS realtime +FROM supabase/storage-api:v1.37.0 AS storage +FROM supabase/logflare:1.30.8 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 e21ac038ff5abc15e9cf343cb604e66be4fc802e Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Thu, 5 Feb 2026 11:06:17 +0800 Subject: [PATCH 019/117] chore: update e2e tests --- .github/workflows/ci.yml | 3 + tests/README.md | 23 +++++++ tests/auth.sh | 26 ++++++++ tests/postgrest.sh | 66 +++++++++++++++++++ .../migrations/0_create_todos_table.sql | 26 ++++++++ 5 files changed, 144 insertions(+) create mode 100644 tests/README.md create mode 100755 tests/auth.sh create mode 100755 tests/postgrest.sh create mode 100644 tests/supabase/migrations/0_create_todos_table.sql diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3ddfd3ef5d..7d594f66c8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -79,6 +79,9 @@ jobs: - run: ./main start env: SUPABASE_INTERNAL_IMAGE_REGISTRY: ghcr.io + - run: ./main --workdir tests migrations up + - run: ./tests/auth.sh + - run: ./tests/postgrest.sh link: name: Link diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000000..86ae3c34b1 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,23 @@ +## End-to-End tests from client lib to local stack + +### Auth test + +1. Run user signup tests + +```bash +./tests/auth.sh +``` + +### PostgREST test + +1. Create todos table + +```bash +supabase --workdir tests migrations up +``` + +2. Run RLS policy tests + +```bash +./tests/postgrest.sh +``` diff --git a/tests/auth.sh b/tests/auth.sh new file mode 100755 index 0000000000..493f01a793 --- /dev/null +++ b/tests/auth.sh @@ -0,0 +1,26 @@ +#!/bin/bash +set -eou pipefail + +# 1. Publishable and secret keys are accepted as `apikey` header +output=$(curl 'http://127.0.0.1:54321/auth/v1/signup' \ + -H "apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH" \ + -H "Content-Type: application/json" \ + -d '{"email":"user@example.com","password":"aSecurePassword123"}' \ +) +if [[ $(echo "$output" | jq '.role') -ne "authenticated" ]]; then + echo "User sign up with publishable key should succeed." >&2 + echo "$output" | jq + exit 1 +fi + +# 2. Legacy anon and service_role key are accepted as `apikey` header +output=$(curl 'http://127.0.0.1:54321/auth/v1/signup' \ + -H "apikey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0" \ + -H "Content-Type: application/json" \ + -d '{"email":"user@example.com","password":"aSecurePassword123"}' \ +) +if [[ $(echo "$output" | jq '.role') -ne "authenticated" ]]; then + echo "User sign up with legacy key should succeed." >&2 + echo "$output" | jq + exit 1 +fi diff --git a/tests/postgrest.sh b/tests/postgrest.sh new file mode 100755 index 0000000000..29c65061ab --- /dev/null +++ b/tests/postgrest.sh @@ -0,0 +1,66 @@ +#!/bin/bash +set -eou pipefail + +# 0. Create test table with RLS +# supabase --workdir tests migrations up + +# 1. Create todo as service role +output=$(curl 'http://127.0.0.1:54321/rest/v1/todos' \ + -H "apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz" \ + -H "Content-Type: application/json" \ + -H "Prefer: return=representation" \ + -d '{"task": "New task", "done": false}' +) +if [[ $(echo "$output" | jq 'length') -ne "1" ]]; then + echo "Creating todo as service role should succeed." >&2 + echo "$output" | jq + exit 1 +fi + +# 2. Create todo as anon role should fail +output=$(curl 'http://127.0.0.1:54321/rest/v1/todos' \ + -H "apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH" \ + -H "Content-Type: application/json" \ + -d '{"task": "New task", "done": false}' +) +if [[ $(echo "$output" | jq '.code') -ne "42501" ]]; then + echo "Creating todo as anon role should fail." >&2 + echo "$output" | jq + exit 1 +fi + +# 3. List todos as anon role +output=$(curl -G 'http://127.0.0.1:54321/rest/v1/todos' \ + -H "apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH" \ + -H "Content-Type: application/json" \ +) +if [[ $(echo "$output" | jq 'length') -ne "1" ]]; then + echo "Listing todos as anon role should succeed." >&2 + echo "$output" | jq + exit 1 +fi + +# 4. Delete todo as anon role should fail +output=$(curl -X DELETE 'http://127.0.0.1:54321/rest/v1/todos?id=eq.1' \ + -H "apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH" \ + -H "Content-Type: application/json" \ + -H "Prefer: return=representation" \ +) +if [[ $(echo "$output" | jq 'length') -ne "1" ]]; then + echo "Deleting todo as anon role should fail." >&2 + echo "$output" | jq + exit 1 +fi + +# 5. Delete todo as authenticated role (custom jwt) +output=$(curl -X DELETE 'http://127.0.0.1:54321/rest/v1/todos?id=eq.1' \ + -H "apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH" \ + -H "Authorization: Bearer eyJhbGciOiJFUzI1NiIsImtpZCI6ImI4MTI2OWYxLTIxZDgtNGYyZS1iNzE5LWMyMjQwYTg0MGQ5MCIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NzAyNjE4NTcsImlhdCI6MTc3MDI2MDA1NywiaXNfYW5vbnltb3VzIjp0cnVlLCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9.iYBqhBe9frFxmuatOzX5EtkX4h0-dFcC_d8dGeZImRA_LdVV1_fyP0MUJYm9ttR2ipL2zQ7WrjR7dbU2kBb9YQ" \ + -H "Content-Type: application/json" \ + -H "Prefer: return=representation" \ +) +if [[ $(echo "$output" | jq 'length') -ne "1" ]]; then + echo "Deleting todo as authenticated role should succeed." >&2 + echo "$output" | jq + exit 1 +fi diff --git a/tests/supabase/migrations/0_create_todos_table.sql b/tests/supabase/migrations/0_create_todos_table.sql new file mode 100644 index 0000000000..2b471133ae --- /dev/null +++ b/tests/supabase/migrations/0_create_todos_table.sql @@ -0,0 +1,26 @@ +-- Create a test table +CREATE TABLE IF NOT EXISTS public.todos ( + id SERIAL PRIMARY KEY, + task TEXT NOT NULL, + done BOOLEAN DEFAULT false, + created_at TIMESTAMPTZ DEFAULT now() +); + +-- Enable RLS +ALTER TABLE public.todos ENABLE ROW LEVEL SECURITY; + +-- Allow anon to read all todos +CREATE POLICY "Allow anon read" ON public.todos FOR SELECT TO anon USING (true); + +-- Allow authenticated users full access +CREATE POLICY "Allow authenticated full access" ON public.todos FOR ALL TO authenticated USING (true) WITH CHECK (true); + +-- Grant permissions +GRANT SELECT ON public.todos TO anon; +GRANT ALL ON public.todos TO authenticated; +GRANT USAGE, SELECT ON SEQUENCE public.todos_id_seq TO authenticated; + +-- Insert sample data +-- INSERT INTO public.todos (task, done) VALUES +-- ('Learn PostgREST', false), +-- ('Setup Supabase locally', true); From c269b3c4d56286fe2b8b1e4e380d1bb0ba639c50 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Thu, 5 Feb 2026 11:09:11 +0800 Subject: [PATCH 020/117] chore: add storage tests --- .github/workflows/ci.yml | 1 + tests/README.md | 8 ++++ tests/auth.sh | 16 +++---- tests/postgrest.sh | 48 +++++++++---------- tests/storage.sh | 36 ++++++++++++++ .../migrations/0_create_todos_table.sql | 5 -- 6 files changed, 77 insertions(+), 37 deletions(-) create mode 100755 tests/storage.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7d594f66c8..dc9ae5d8b8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -82,6 +82,7 @@ jobs: - run: ./main --workdir tests migrations up - run: ./tests/auth.sh - run: ./tests/postgrest.sh + - run: ./tests/storage.sh link: name: Link diff --git a/tests/README.md b/tests/README.md index 86ae3c34b1..ac7e6920ac 100644 --- a/tests/README.md +++ b/tests/README.md @@ -21,3 +21,11 @@ supabase --workdir tests migrations up ```bash ./tests/postgrest.sh ``` + +### Storage test + +1. Run storage bucket tests + +```bash +./tests/storage.sh +``` diff --git a/tests/auth.sh b/tests/auth.sh index 493f01a793..4087c9b8a1 100755 --- a/tests/auth.sh +++ b/tests/auth.sh @@ -3,24 +3,24 @@ set -eou pipefail # 1. Publishable and secret keys are accepted as `apikey` header output=$(curl 'http://127.0.0.1:54321/auth/v1/signup' \ - -H "apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH" \ - -H "Content-Type: application/json" \ + -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ + -H 'Content-Type: application/json' \ -d '{"email":"user@example.com","password":"aSecurePassword123"}' \ ) -if [[ $(echo "$output" | jq '.role') -ne "authenticated" ]]; then - echo "User sign up with publishable key should succeed." >&2 +if [[ $(echo "$output" | jq '.role') != 'authenticated' ]]; then + echo 'User sign up with publishable key should succeed.' >&2 echo "$output" | jq exit 1 fi # 2. Legacy anon and service_role key are accepted as `apikey` header output=$(curl 'http://127.0.0.1:54321/auth/v1/signup' \ - -H "apikey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0" \ - -H "Content-Type: application/json" \ + -H 'apikey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0' \ + -H 'Content-Type: application/json' \ -d '{"email":"user@example.com","password":"aSecurePassword123"}' \ ) -if [[ $(echo "$output" | jq '.role') -ne "authenticated" ]]; then - echo "User sign up with legacy key should succeed." >&2 +if [[ $(echo "$output" | jq '.role') != 'authenticated' ]]; then + echo 'User sign up with legacy key should succeed.' >&2 echo "$output" | jq exit 1 fi diff --git a/tests/postgrest.sh b/tests/postgrest.sh index 29c65061ab..21c91f1c2e 100755 --- a/tests/postgrest.sh +++ b/tests/postgrest.sh @@ -6,61 +6,61 @@ set -eou pipefail # 1. Create todo as service role output=$(curl 'http://127.0.0.1:54321/rest/v1/todos' \ - -H "apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz" \ - -H "Content-Type: application/json" \ - -H "Prefer: return=representation" \ + -H 'apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz' \ + -H 'Content-Type: application/json' \ + -H 'Prefer: return=representation' \ -d '{"task": "New task", "done": false}' ) -if [[ $(echo "$output" | jq 'length') -ne "1" ]]; then - echo "Creating todo as service role should succeed." >&2 +if [[ $(echo "$output" | jq 'length') != '1' ]]; then + echo 'Creating todo as service role should succeed.' >&2 echo "$output" | jq exit 1 fi # 2. Create todo as anon role should fail output=$(curl 'http://127.0.0.1:54321/rest/v1/todos' \ - -H "apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH" \ - -H "Content-Type: application/json" \ + -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ + -H 'Content-Type: application/json' \ -d '{"task": "New task", "done": false}' ) -if [[ $(echo "$output" | jq '.code') -ne "42501" ]]; then - echo "Creating todo as anon role should fail." >&2 +if [[ $(echo "$output" | jq '.code') != '42501' ]]; then + echo 'Creating todo as anon role should fail.' >&2 echo "$output" | jq exit 1 fi # 3. List todos as anon role output=$(curl -G 'http://127.0.0.1:54321/rest/v1/todos' \ - -H "apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH" \ - -H "Content-Type: application/json" \ + -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ + -H 'Content-Type: application/json' \ ) -if [[ $(echo "$output" | jq 'length') -ne "1" ]]; then - echo "Listing todos as anon role should succeed." >&2 +if [[ $(echo "$output" | jq 'length') != '1' ]]; then + echo 'Listing todos as anon role should succeed.' >&2 echo "$output" | jq exit 1 fi # 4. Delete todo as anon role should fail output=$(curl -X DELETE 'http://127.0.0.1:54321/rest/v1/todos?id=eq.1' \ - -H "apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH" \ - -H "Content-Type: application/json" \ - -H "Prefer: return=representation" \ + -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ + -H 'Content-Type: application/json' \ + -H 'Prefer: return=representation' \ ) -if [[ $(echo "$output" | jq 'length') -ne "1" ]]; then - echo "Deleting todo as anon role should fail." >&2 +if [[ $(echo "$output" | jq 'length') != '1' ]]; then + echo 'Deleting todo as anon role should fail.' >&2 echo "$output" | jq exit 1 fi # 5. Delete todo as authenticated role (custom jwt) output=$(curl -X DELETE 'http://127.0.0.1:54321/rest/v1/todos?id=eq.1' \ - -H "apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH" \ - -H "Authorization: Bearer eyJhbGciOiJFUzI1NiIsImtpZCI6ImI4MTI2OWYxLTIxZDgtNGYyZS1iNzE5LWMyMjQwYTg0MGQ5MCIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NzAyNjE4NTcsImlhdCI6MTc3MDI2MDA1NywiaXNfYW5vbnltb3VzIjp0cnVlLCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9.iYBqhBe9frFxmuatOzX5EtkX4h0-dFcC_d8dGeZImRA_LdVV1_fyP0MUJYm9ttR2ipL2zQ7WrjR7dbU2kBb9YQ" \ - -H "Content-Type: application/json" \ - -H "Prefer: return=representation" \ + -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ + -H 'Authorization: Bearer eyJhbGciOiJFUzI1NiIsImtpZCI6ImI4MTI2OWYxLTIxZDgtNGYyZS1iNzE5LWMyMjQwYTg0MGQ5MCIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NzAyNjE4NTcsImlhdCI6MTc3MDI2MDA1NywiaXNfYW5vbnltb3VzIjp0cnVlLCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9.iYBqhBe9frFxmuatOzX5EtkX4h0-dFcC_d8dGeZImRA_LdVV1_fyP0MUJYm9ttR2ipL2zQ7WrjR7dbU2kBb9YQ' \ + -H 'Content-Type: application/json' \ + -H 'Prefer: return=representation' \ ) -if [[ $(echo "$output" | jq 'length') -ne "1" ]]; then - echo "Deleting todo as authenticated role should succeed." >&2 +if [[ $(echo "$output" | jq 'length') != '1' ]]; then + echo 'Deleting todo as authenticated role should succeed.' >&2 echo "$output" | jq exit 1 fi diff --git a/tests/storage.sh b/tests/storage.sh new file mode 100755 index 0000000000..44786f7f42 --- /dev/null +++ b/tests/storage.sh @@ -0,0 +1,36 @@ +#!/bin/bash +set -eou pipefail + +# 1. Create test bucket as service role +output=$(curl 'http://127.0.0.1:54321/storage/v1/bucket' \ + -H 'apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz' \ + -H 'Content-Type: application/json' \ + -d '{"name":"test"}' \ +) +if [[ $(echo "$output" | jq '.name') != 'test' ]]; then + echo 'Creating storage bucket as service role should succeed.' >&2 + echo "$output" | jq + exit 1 +fi + +# 2. Create test bucket as service role (legacy key) +output=$(curl -X DELETE 'http://127.0.0.1:54321/storage/v1/bucket/test' \ + -H 'apikey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU' \ + -H 'Content-Type: application/json' \ +) +if [[ $(echo "$output" | jq '.message') != 'Successfully deleted' ]]; then + echo 'Deleting storage bucket as service role should succeed.' >&2 + echo "$output" | jq + exit 1 +fi + +# 3. Unauthenticated requests are rejected +output=$(curl 'http://127.0.0.1:54321/storage/v1/bucket' \ + -H 'Content-Type: application/json' \ + -d '{"name":"test"}' \ +) +if [[ $(echo "$output" | jq '.error') != 'Unauthorized' ]]; then + echo 'Unauthenticated requests should be rejected.' >&2 + echo "$output" | jq + exit 1 +fi diff --git a/tests/supabase/migrations/0_create_todos_table.sql b/tests/supabase/migrations/0_create_todos_table.sql index 2b471133ae..46a601433d 100644 --- a/tests/supabase/migrations/0_create_todos_table.sql +++ b/tests/supabase/migrations/0_create_todos_table.sql @@ -19,8 +19,3 @@ CREATE POLICY "Allow authenticated full access" ON public.todos FOR ALL TO authe GRANT SELECT ON public.todos TO anon; GRANT ALL ON public.todos TO authenticated; GRANT USAGE, SELECT ON SEQUENCE public.todos_id_seq TO authenticated; - --- Insert sample data --- INSERT INTO public.todos (task, done) VALUES --- ('Learn PostgREST', false), --- ('Setup Supabase locally', true); From 4ef7770590e0d2ce11610325f6d0188b2fa09823 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Thu, 5 Feb 2026 11:24:09 +0800 Subject: [PATCH 021/117] chore: add gitignore file --- tests/supabase/.gitignore | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/supabase/.gitignore diff --git a/tests/supabase/.gitignore b/tests/supabase/.gitignore new file mode 100644 index 0000000000..a735017e0d --- /dev/null +++ b/tests/supabase/.gitignore @@ -0,0 +1,13 @@ +# Supabase +.branches +.temp +.env + +# Supabase +.branches +.temp + +# dotenvx +.env.keys +.env.local +.env.*.local From 3724a469694da799f3ee4b98b8d56a33d06fbcde Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Thu, 5 Feb 2026 11:43:28 +0800 Subject: [PATCH 022/117] chore: add realtime test --- tests/auth.sh | 4 ++-- tests/realtime.sh | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100755 tests/realtime.sh diff --git a/tests/auth.sh b/tests/auth.sh index 4087c9b8a1..a97af9b94d 100755 --- a/tests/auth.sh +++ b/tests/auth.sh @@ -7,7 +7,7 @@ output=$(curl 'http://127.0.0.1:54321/auth/v1/signup' \ -H 'Content-Type: application/json' \ -d '{"email":"user@example.com","password":"aSecurePassword123"}' \ ) -if [[ $(echo "$output" | jq '.role') != 'authenticated' ]]; then +if [[ $(echo "$output" | jq '.user.role') != 'authenticated' ]]; then echo 'User sign up with publishable key should succeed.' >&2 echo "$output" | jq exit 1 @@ -19,7 +19,7 @@ output=$(curl 'http://127.0.0.1:54321/auth/v1/signup' \ -H 'Content-Type: application/json' \ -d '{"email":"user@example.com","password":"aSecurePassword123"}' \ ) -if [[ $(echo "$output" | jq '.role') != 'authenticated' ]]; then +if [[ $(echo "$output" | jq '.user.role') != 'authenticated' ]]; then echo 'User sign up with legacy key should succeed.' >&2 echo "$output" | jq exit 1 diff --git a/tests/realtime.sh b/tests/realtime.sh new file mode 100755 index 0000000000..4577cb36e5 --- /dev/null +++ b/tests/realtime.sh @@ -0,0 +1,28 @@ +#!/bin/bash +set -eou pipefail + +# 1. Join realtime with legacy key +output=$(echo '{"topic":"realtime:room1","ref":1,"event":"phx_join","payload":{"config":{"broadcast":{"ack":true},"presence":{"enabled":true},"private":false}}}' |\ + websocat 'ws://127.0.0.1:54321/realtime/v1/websocket?apikey=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0&vsn=1.0.0' \ +) +if [[ $(echo "$output" | jq '.payload.status') != 'ok' ]]; then + echo 'Joining realtime with legacy key should succeed.' >&2 + echo "$output" | jq + exit 1 +fi + +# 2. Join realtime with publishable key +output=$(echo '{"topic":"realtime:room1","ref":1,"event":"phx_join","payload":{"config":{"broadcast":{"ack":true},"presence":{"enabled":true},"private":false}}}' |\ + websocat 'ws://127.0.0.1:54321/realtime/v1/websocket?apikey=sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH&vsn=1.0.0' \ +) +if [[ $(echo "$output" | jq '.payload.status') != 'ok' ]]; then + echo 'Joining realtime as anon should succeed.' >&2 + echo "$output" | jq + exit 1 +fi + +## 3. Broadcast with secret key +curl -f 'http://127.0.0.1:54321/realtime/v1/api/broadcast' \ + -H 'apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz' \ + -H 'Content-Type: application/json' \ + -d '{"messages":[{"topic":"room1","event":"my_event","payload":{"foo":"bar"},"private":true}]}' From ba26dcefc6a9a9efd21b1a8b1bd822f6afec8fc8 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Thu, 5 Feb 2026 11:59:45 +0800 Subject: [PATCH 023/117] chore: add edge function tests --- .github/workflows/ci.yml | 5 ++-- tests/auth.sh | 4 ++-- tests/edge-runtime.sh | 50 ++++++++++++++++++++++++++++++++++++++++ tests/postgrest.sh | 10 ++++---- tests/realtime.sh | 4 ++-- tests/storage.sh | 6 ++--- 6 files changed, 65 insertions(+), 14 deletions(-) create mode 100755 tests/edge-runtime.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc9ae5d8b8..b43f180eaf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -76,13 +76,14 @@ jobs: - run: go build main.go - run: ./main init - run: sed -i '/\[db.pooler\]/{n;s/.*/enabled = true/}' supabase/config.toml - - run: ./main start + - run: ./main start --workdir tests env: SUPABASE_INTERNAL_IMAGE_REGISTRY: ghcr.io - - run: ./main --workdir tests migrations up - run: ./tests/auth.sh - run: ./tests/postgrest.sh - run: ./tests/storage.sh + - run: ./tests/realtime.sh + - run: ./tests/edge-runtime.sh link: name: Link diff --git a/tests/auth.sh b/tests/auth.sh index a97af9b94d..cdbd07f456 100755 --- a/tests/auth.sh +++ b/tests/auth.sh @@ -7,7 +7,7 @@ output=$(curl 'http://127.0.0.1:54321/auth/v1/signup' \ -H 'Content-Type: application/json' \ -d '{"email":"user@example.com","password":"aSecurePassword123"}' \ ) -if [[ $(echo "$output" | jq '.user.role') != 'authenticated' ]]; then +if [[ $(echo "$output" | jq -r '.user.role') != 'authenticated' ]]; then echo 'User sign up with publishable key should succeed.' >&2 echo "$output" | jq exit 1 @@ -19,7 +19,7 @@ output=$(curl 'http://127.0.0.1:54321/auth/v1/signup' \ -H 'Content-Type: application/json' \ -d '{"email":"user@example.com","password":"aSecurePassword123"}' \ ) -if [[ $(echo "$output" | jq '.user.role') != 'authenticated' ]]; then +if [[ $(echo "$output" | jq -r '.user.role') != 'authenticated' ]]; then echo 'User sign up with legacy key should succeed.' >&2 echo "$output" | jq exit 1 diff --git a/tests/edge-runtime.sh b/tests/edge-runtime.sh new file mode 100755 index 0000000000..ad1d829a86 --- /dev/null +++ b/tests/edge-runtime.sh @@ -0,0 +1,50 @@ +#!/bin/bash +set -eou pipefail + +# 1. POST request with publishable key +output=$(curl 'http://127.0.0.1:54321/functions/v1/hello-world' \ + -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ + -H 'Content-Type: application/json' \ + -d '{"name":"Functions"}' \ +) +if [[ $(echo "$output" | jq -r '.message') != 'Hello Functions!' ]]; then + echo 'Edge Function request with publishable key should succeed.' >&2 + echo "$output" | jq + exit 1 +fi + +# 2. POST request with legacy key +output=$(curl 'http://127.0.0.1:54321/functions/v1/hello-world' \ + -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0' \ + -H 'Content-Type: application/json' \ + -d '{"name":"Functions"}' \ +) +if [[ $(echo "$output" | jq -r '.message') != 'Hello Functions!' ]]; then + echo 'Edge Function request with anon key should succeed.' >&2 + echo "$output" | jq + exit 1 +fi + +# 3. POST request with secret key +output=$(curl 'http://127.0.0.1:54321/functions/v1/hello-world' \ + -H 'apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz' \ + -H 'Content-Type: application/json' \ + -d '{"name":"Functions"}' \ +) +if [[ $(echo "$output" | jq -r '.message') != 'Hello Functions!' ]]; then + echo 'Edge Function request with secret key should succeed.' >&2 + echo "$output" | jq + exit 1 +fi + +# 4. POST request with service role key +output=$(curl 'http://127.0.0.1:54321/functions/v1/hello-world' \ + -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU' \ + -H 'Content-Type: application/json' \ + -d '{"name":"Functions"}' \ +) +if [[ $(echo "$output" | jq -r '.message') != 'Hello Functions!' ]]; then + echo 'Edge Function request with service role key should succeed.' >&2 + echo "$output" | jq + exit 1 +fi diff --git a/tests/postgrest.sh b/tests/postgrest.sh index 21c91f1c2e..32691d2542 100755 --- a/tests/postgrest.sh +++ b/tests/postgrest.sh @@ -11,7 +11,7 @@ output=$(curl 'http://127.0.0.1:54321/rest/v1/todos' \ -H 'Prefer: return=representation' \ -d '{"task": "New task", "done": false}' ) -if [[ $(echo "$output" | jq 'length') != '1' ]]; then +if [[ $(echo "$output" | jq -r 'length') != '1' ]]; then echo 'Creating todo as service role should succeed.' >&2 echo "$output" | jq exit 1 @@ -23,7 +23,7 @@ output=$(curl 'http://127.0.0.1:54321/rest/v1/todos' \ -H 'Content-Type: application/json' \ -d '{"task": "New task", "done": false}' ) -if [[ $(echo "$output" | jq '.code') != '42501' ]]; then +if [[ $(echo "$output" | jq -r '.code') != '42501' ]]; then echo 'Creating todo as anon role should fail.' >&2 echo "$output" | jq exit 1 @@ -34,7 +34,7 @@ output=$(curl -G 'http://127.0.0.1:54321/rest/v1/todos' \ -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ -H 'Content-Type: application/json' \ ) -if [[ $(echo "$output" | jq 'length') != '1' ]]; then +if [[ $(echo "$output" | jq -r 'length') != '1' ]]; then echo 'Listing todos as anon role should succeed.' >&2 echo "$output" | jq exit 1 @@ -46,7 +46,7 @@ output=$(curl -X DELETE 'http://127.0.0.1:54321/rest/v1/todos?id=eq.1' \ -H 'Content-Type: application/json' \ -H 'Prefer: return=representation' \ ) -if [[ $(echo "$output" | jq 'length') != '1' ]]; then +if [[ $(echo "$output" | jq -r 'length') != '1' ]]; then echo 'Deleting todo as anon role should fail.' >&2 echo "$output" | jq exit 1 @@ -59,7 +59,7 @@ output=$(curl -X DELETE 'http://127.0.0.1:54321/rest/v1/todos?id=eq.1' \ -H 'Content-Type: application/json' \ -H 'Prefer: return=representation' \ ) -if [[ $(echo "$output" | jq 'length') != '1' ]]; then +if [[ $(echo "$output" | jq -r 'length') != '1' ]]; then echo 'Deleting todo as authenticated role should succeed.' >&2 echo "$output" | jq exit 1 diff --git a/tests/realtime.sh b/tests/realtime.sh index 4577cb36e5..e43d71b92e 100755 --- a/tests/realtime.sh +++ b/tests/realtime.sh @@ -5,7 +5,7 @@ set -eou pipefail output=$(echo '{"topic":"realtime:room1","ref":1,"event":"phx_join","payload":{"config":{"broadcast":{"ack":true},"presence":{"enabled":true},"private":false}}}' |\ websocat 'ws://127.0.0.1:54321/realtime/v1/websocket?apikey=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0&vsn=1.0.0' \ ) -if [[ $(echo "$output" | jq '.payload.status') != 'ok' ]]; then +if [[ $(echo "$output" | jq -r '.payload.status') != 'ok' ]]; then echo 'Joining realtime with legacy key should succeed.' >&2 echo "$output" | jq exit 1 @@ -15,7 +15,7 @@ fi output=$(echo '{"topic":"realtime:room1","ref":1,"event":"phx_join","payload":{"config":{"broadcast":{"ack":true},"presence":{"enabled":true},"private":false}}}' |\ websocat 'ws://127.0.0.1:54321/realtime/v1/websocket?apikey=sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH&vsn=1.0.0' \ ) -if [[ $(echo "$output" | jq '.payload.status') != 'ok' ]]; then +if [[ $(echo "$output" | jq -r '.payload.status') != 'ok' ]]; then echo 'Joining realtime as anon should succeed.' >&2 echo "$output" | jq exit 1 diff --git a/tests/storage.sh b/tests/storage.sh index 44786f7f42..1fc9d302b8 100755 --- a/tests/storage.sh +++ b/tests/storage.sh @@ -7,7 +7,7 @@ output=$(curl 'http://127.0.0.1:54321/storage/v1/bucket' \ -H 'Content-Type: application/json' \ -d '{"name":"test"}' \ ) -if [[ $(echo "$output" | jq '.name') != 'test' ]]; then +if [[ $(echo "$output" | jq -r '.name') != 'test' ]]; then echo 'Creating storage bucket as service role should succeed.' >&2 echo "$output" | jq exit 1 @@ -18,7 +18,7 @@ output=$(curl -X DELETE 'http://127.0.0.1:54321/storage/v1/bucket/test' \ -H 'apikey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU' \ -H 'Content-Type: application/json' \ ) -if [[ $(echo "$output" | jq '.message') != 'Successfully deleted' ]]; then +if [[ $(echo "$output" | jq -r '.message') != 'Successfully deleted' ]]; then echo 'Deleting storage bucket as service role should succeed.' >&2 echo "$output" | jq exit 1 @@ -29,7 +29,7 @@ output=$(curl 'http://127.0.0.1:54321/storage/v1/bucket' \ -H 'Content-Type: application/json' \ -d '{"name":"test"}' \ ) -if [[ $(echo "$output" | jq '.error') != 'Unauthorized' ]]; then +if [[ $(echo "$output" | jq -r '.error') != 'Unauthorized' ]]; then echo 'Unauthenticated requests should be rejected.' >&2 echo "$output" | jq exit 1 From 1460d92a56c92f67356d0164c4014e26351374fe Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Thu, 5 Feb 2026 12:02:10 +0800 Subject: [PATCH 024/117] chore: add missing function --- tests/README.md | 16 ++++++++++ tests/supabase/functions/hello-world/.npmrc | 3 ++ .../supabase/functions/hello-world/deno.json | 5 +++ tests/supabase/functions/hello-world/index.ts | 32 +++++++++++++++++++ 4 files changed, 56 insertions(+) create mode 100644 tests/supabase/functions/hello-world/.npmrc create mode 100644 tests/supabase/functions/hello-world/deno.json create mode 100644 tests/supabase/functions/hello-world/index.ts diff --git a/tests/README.md b/tests/README.md index ac7e6920ac..079624a066 100644 --- a/tests/README.md +++ b/tests/README.md @@ -29,3 +29,19 @@ supabase --workdir tests migrations up ```bash ./tests/storage.sh ``` + +### Realtime test + +1. Join a room and broadcast + +```bash +./tests/realtime.sh +``` + +### Edge Function test + +1. Invoke hello-world function + +```bash +./tests/edge-runtime.sh +``` diff --git a/tests/supabase/functions/hello-world/.npmrc b/tests/supabase/functions/hello-world/.npmrc new file mode 100644 index 0000000000..48c6388638 --- /dev/null +++ b/tests/supabase/functions/hello-world/.npmrc @@ -0,0 +1,3 @@ +# Configuration for private npm package dependencies +# For more information on using private registries with Edge Functions, see: +# https://supabase.com/docs/guides/functions/import-maps#importing-from-private-registries diff --git a/tests/supabase/functions/hello-world/deno.json b/tests/supabase/functions/hello-world/deno.json new file mode 100644 index 0000000000..758d0703d1 --- /dev/null +++ b/tests/supabase/functions/hello-world/deno.json @@ -0,0 +1,5 @@ +{ + "imports": { + "@supabase/functions-js": "jsr:@supabase/functions-js@^2" + } +} diff --git a/tests/supabase/functions/hello-world/index.ts b/tests/supabase/functions/hello-world/index.ts new file mode 100644 index 0000000000..d928d9b5bb --- /dev/null +++ b/tests/supabase/functions/hello-world/index.ts @@ -0,0 +1,32 @@ +// Follow this setup guide to integrate the Deno language server with your editor: +// https://deno.land/manual/getting_started/setup_your_environment +// This enables autocomplete, go to definition, etc. + +// Setup type definitions for built-in Supabase Runtime APIs +import "@supabase/functions-js/edge-runtime.d.ts" + +console.log("Hello from Functions!") + +Deno.serve(async (req) => { + const { name } = await req.json() + const data = { + message: `Hello ${name}!`, + } + + return new Response( + JSON.stringify(data), + { headers: { "Content-Type": "application/json" } }, + ) +}) + +/* To invoke locally: + + 1. Run `supabase start` (see: https://supabase.com/docs/reference/cli/supabase-start) + 2. Make an HTTP request: + + curl -i --location --request POST 'http://127.0.0.1:54321/functions/v1/hello-world' \ + --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0' \ + --header 'Content-Type: application/json' \ + --data '{"name":"Functions"}' + +*/ From f5e04aaf2014591f1f263f2d6589c945370f77c6 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Thu, 5 Feb 2026 12:52:20 +0800 Subject: [PATCH 025/117] chore: run all tests --- .github/workflows/ci.yml | 6 +----- tests/README.md | 20 +++++++++++++------- tests/all.sh | 11 +++++++++++ tests/auth.sh | 32 +++++++++++++++++++++++++++++--- tests/edge-runtime.sh | 5 +++++ tests/postgrest.sh | 12 +++++++----- tests/realtime.sh | 2 ++ tests/storage.sh | 2 ++ 8 files changed, 70 insertions(+), 20 deletions(-) create mode 100755 tests/all.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b43f180eaf..968852046d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -79,11 +79,7 @@ jobs: - run: ./main start --workdir tests env: SUPABASE_INTERNAL_IMAGE_REGISTRY: ghcr.io - - run: ./tests/auth.sh - - run: ./tests/postgrest.sh - - run: ./tests/storage.sh - - run: ./tests/realtime.sh - - run: ./tests/edge-runtime.sh + - run: ./tests/all.sh ./main link: name: Link diff --git a/tests/README.md b/tests/README.md index 079624a066..5535ab0c36 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,22 +1,28 @@ ## End-to-End tests from client lib to local stack -### Auth test +1. Start local stack -1. Run user signup tests +```bash +supabase --workdir tests start +``` + +2. Run all tests ```bash -./tests/auth.sh +./tests/all.sh supabase ``` -### PostgREST test +### Auth test -1. Create todos table +1. Run user signup tests ```bash -supabase --workdir tests migrations up +./tests/auth.sh ``` -2. Run RLS policy tests +### PostgREST test + +1. Run RLS policy tests ```bash ./tests/postgrest.sh diff --git a/tests/all.sh b/tests/all.sh new file mode 100755 index 0000000000..c7771f2a81 --- /dev/null +++ b/tests/all.sh @@ -0,0 +1,11 @@ +#!/bin/bash +set -eou pipefail + +dotenv=$("$@" --workdir tests status -o env) +source <(echo "$dotenv" | sed 's/^/export /') + +./tests/auth.sh +./tests/postgrest.sh +./tests/storage.sh +./tests/realtime.sh +./tests/edge-runtime.sh diff --git a/tests/auth.sh b/tests/auth.sh index cdbd07f456..f72179b52f 100755 --- a/tests/auth.sh +++ b/tests/auth.sh @@ -1,7 +1,9 @@ #!/bin/bash set -eou pipefail -# 1. Publishable and secret keys are accepted as `apikey` header +echo "Running Auth tests..." + +# 1. Create user with publishable key output=$(curl 'http://127.0.0.1:54321/auth/v1/signup' \ -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ -H 'Content-Type: application/json' \ @@ -13,9 +15,21 @@ if [[ $(echo "$output" | jq -r '.user.role') != 'authenticated' ]]; then exit 1 fi -# 2. Legacy anon and service_role key are accepted as `apikey` header +# 2. Delete user with secret key +user_id=$(echo "$output" | jq -r '.user.id') +output=$(curl -X DELETE "http://127.0.0.1:54321/auth/v1/admin/users/$user_id" \ + -H "apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz" \ + -H 'Content-Type: application/json' \ +) +if [[ "$output" != '{}' ]]; then + echo 'User deletion with secret key should succeed.' >&2 + echo "$output" | jq + exit 1 +fi + +# 3. Create user with legacy anon key output=$(curl 'http://127.0.0.1:54321/auth/v1/signup' \ - -H 'apikey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0' \ + -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0' \ -H 'Content-Type: application/json' \ -d '{"email":"user@example.com","password":"aSecurePassword123"}' \ ) @@ -24,3 +38,15 @@ if [[ $(echo "$output" | jq -r '.user.role') != 'authenticated' ]]; then echo "$output" | jq exit 1 fi + +# 4. Delete user with legacy service role key +user_id=$(echo "$output" | jq -r '.user.id') +output=$(curl -X DELETE "http://127.0.0.1:54321/auth/v1/admin/users/$user_id" \ + -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU" \ + -H 'Content-Type: application/json' \ +) +if [[ "$output" != '{}' ]]; then + echo 'User deletion with legacy key should succeed.' >&2 + echo "$output" | jq + exit 1 +fi diff --git a/tests/edge-runtime.sh b/tests/edge-runtime.sh index ad1d829a86..1c1a25b5c1 100755 --- a/tests/edge-runtime.sh +++ b/tests/edge-runtime.sh @@ -1,6 +1,11 @@ #!/bin/bash set -eou pipefail +# 0. Serve Edge Functions +# supabase --workdir tests functions serve + +echo "Running Edge Function tests..." + # 1. POST request with publishable key output=$(curl 'http://127.0.0.1:54321/functions/v1/hello-world' \ -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ diff --git a/tests/postgrest.sh b/tests/postgrest.sh index 32691d2542..b97043df0b 100755 --- a/tests/postgrest.sh +++ b/tests/postgrest.sh @@ -4,12 +4,14 @@ set -eou pipefail # 0. Create test table with RLS # supabase --workdir tests migrations up +echo "Running PostgREST tests..." + # 1. Create todo as service role output=$(curl 'http://127.0.0.1:54321/rest/v1/todos' \ -H 'apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz' \ -H 'Content-Type: application/json' \ -H 'Prefer: return=representation' \ - -d '{"task": "New task", "done": false}' + -d '{"task": "New task", "done": false}' \ ) if [[ $(echo "$output" | jq -r 'length') != '1' ]]; then echo 'Creating todo as service role should succeed.' >&2 @@ -21,7 +23,7 @@ fi output=$(curl 'http://127.0.0.1:54321/rest/v1/todos' \ -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ -H 'Content-Type: application/json' \ - -d '{"task": "New task", "done": false}' + -d '{"task": "New task", "done": false}' \ ) if [[ $(echo "$output" | jq -r '.code') != '42501' ]]; then echo 'Creating todo as anon role should fail.' >&2 @@ -46,16 +48,16 @@ output=$(curl -X DELETE 'http://127.0.0.1:54321/rest/v1/todos?id=eq.1' \ -H 'Content-Type: application/json' \ -H 'Prefer: return=representation' \ ) -if [[ $(echo "$output" | jq -r 'length') != '1' ]]; then +if [[ $(echo "$output" | jq -r 'length') != '0' ]]; then echo 'Deleting todo as anon role should fail.' >&2 echo "$output" | jq exit 1 fi # 5. Delete todo as authenticated role (custom jwt) -output=$(curl -X DELETE 'http://127.0.0.1:54321/rest/v1/todos?id=eq.1' \ +output=$(curl -X DELETE 'http://127.0.0.1:54321/rest/v1/todos?id=not.eq.0' \ -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ - -H 'Authorization: Bearer eyJhbGciOiJFUzI1NiIsImtpZCI6ImI4MTI2OWYxLTIxZDgtNGYyZS1iNzE5LWMyMjQwYTg0MGQ5MCIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NzAyNjE4NTcsImlhdCI6MTc3MDI2MDA1NywiaXNfYW5vbnltb3VzIjp0cnVlLCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9.iYBqhBe9frFxmuatOzX5EtkX4h0-dFcC_d8dGeZImRA_LdVV1_fyP0MUJYm9ttR2ipL2zQ7WrjR7dbU2kBb9YQ' \ + -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU" \ -H 'Content-Type: application/json' \ -H 'Prefer: return=representation' \ ) diff --git a/tests/realtime.sh b/tests/realtime.sh index e43d71b92e..65586829d5 100755 --- a/tests/realtime.sh +++ b/tests/realtime.sh @@ -1,6 +1,8 @@ #!/bin/bash set -eou pipefail +echo "Running Realtime tests..." + # 1. Join realtime with legacy key output=$(echo '{"topic":"realtime:room1","ref":1,"event":"phx_join","payload":{"config":{"broadcast":{"ack":true},"presence":{"enabled":true},"private":false}}}' |\ websocat 'ws://127.0.0.1:54321/realtime/v1/websocket?apikey=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0&vsn=1.0.0' \ diff --git a/tests/storage.sh b/tests/storage.sh index 1fc9d302b8..135c9536ca 100755 --- a/tests/storage.sh +++ b/tests/storage.sh @@ -1,6 +1,8 @@ #!/bin/bash set -eou pipefail +echo "Running Storage tests..." + # 1. Create test bucket as service role output=$(curl 'http://127.0.0.1:54321/storage/v1/bucket' \ -H 'apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz' \ From 781003b9067546489db346287353b870b40fd33c Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Thu, 5 Feb 2026 13:09:33 +0800 Subject: [PATCH 026/117] chore: glob test files --- .github/workflows/ci.yml | 5 ++++- e2e-test.sh | 13 +++++++++++++ tests/all.sh | 11 ----------- tests/auth.sh | 10 ++++------ tests/edge-runtime.sh | 10 ++++------ tests/postgrest.sh | 12 +++++------- tests/realtime.sh | 4 +--- tests/storage.sh | 8 +++----- 8 files changed, 34 insertions(+), 39 deletions(-) create mode 100755 e2e-test.sh delete mode 100755 tests/all.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 968852046d..1b85234166 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -79,7 +79,10 @@ jobs: - run: ./main start --workdir tests env: SUPABASE_INTERNAL_IMAGE_REGISTRY: ghcr.io - - run: ./tests/all.sh ./main + - run: | + sudo apt-get update + sudo apt-get -y websocat + - run: ./e2e-test.sh ./main link: name: Link diff --git a/e2e-test.sh b/e2e-test.sh new file mode 100755 index 0000000000..b28d67f996 --- /dev/null +++ b/e2e-test.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -eou pipefail + +dotenv=$("${1:-supabase}" --workdir tests status -o env) +source <(echo "$dotenv" | sed 's/^/export /') + +for tc in ./tests/*.sh; do + echo "Running $tc" >&2 + exec "$tc" & +done + +wait +echo "All tests have completed." diff --git a/tests/all.sh b/tests/all.sh deleted file mode 100755 index c7771f2a81..0000000000 --- a/tests/all.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -set -eou pipefail - -dotenv=$("$@" --workdir tests status -o env) -source <(echo "$dotenv" | sed 's/^/export /') - -./tests/auth.sh -./tests/postgrest.sh -./tests/storage.sh -./tests/realtime.sh -./tests/edge-runtime.sh diff --git a/tests/auth.sh b/tests/auth.sh index f72179b52f..738ea381b0 100755 --- a/tests/auth.sh +++ b/tests/auth.sh @@ -1,10 +1,8 @@ #!/bin/bash set -eou pipefail -echo "Running Auth tests..." - # 1. Create user with publishable key -output=$(curl 'http://127.0.0.1:54321/auth/v1/signup' \ +output=$(curl -sS 'http://127.0.0.1:54321/auth/v1/signup' \ -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ -H 'Content-Type: application/json' \ -d '{"email":"user@example.com","password":"aSecurePassword123"}' \ @@ -17,7 +15,7 @@ fi # 2. Delete user with secret key user_id=$(echo "$output" | jq -r '.user.id') -output=$(curl -X DELETE "http://127.0.0.1:54321/auth/v1/admin/users/$user_id" \ +output=$(curl -sS -X DELETE "http://127.0.0.1:54321/auth/v1/admin/users/$user_id" \ -H "apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz" \ -H 'Content-Type: application/json' \ ) @@ -28,7 +26,7 @@ if [[ "$output" != '{}' ]]; then fi # 3. Create user with legacy anon key -output=$(curl 'http://127.0.0.1:54321/auth/v1/signup' \ +output=$(curl -sS 'http://127.0.0.1:54321/auth/v1/signup' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0' \ -H 'Content-Type: application/json' \ -d '{"email":"user@example.com","password":"aSecurePassword123"}' \ @@ -41,7 +39,7 @@ fi # 4. Delete user with legacy service role key user_id=$(echo "$output" | jq -r '.user.id') -output=$(curl -X DELETE "http://127.0.0.1:54321/auth/v1/admin/users/$user_id" \ +output=$(curl -sS -X DELETE "http://127.0.0.1:54321/auth/v1/admin/users/$user_id" \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU" \ -H 'Content-Type: application/json' \ ) diff --git a/tests/edge-runtime.sh b/tests/edge-runtime.sh index 1c1a25b5c1..cbc657fbea 100755 --- a/tests/edge-runtime.sh +++ b/tests/edge-runtime.sh @@ -4,10 +4,8 @@ set -eou pipefail # 0. Serve Edge Functions # supabase --workdir tests functions serve -echo "Running Edge Function tests..." - # 1. POST request with publishable key -output=$(curl 'http://127.0.0.1:54321/functions/v1/hello-world' \ +output=$(curl -sS 'http://127.0.0.1:54321/functions/v1/hello-world' \ -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ -H 'Content-Type: application/json' \ -d '{"name":"Functions"}' \ @@ -19,7 +17,7 @@ if [[ $(echo "$output" | jq -r '.message') != 'Hello Functions!' ]]; then fi # 2. POST request with legacy key -output=$(curl 'http://127.0.0.1:54321/functions/v1/hello-world' \ +output=$(curl -sS 'http://127.0.0.1:54321/functions/v1/hello-world' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0' \ -H 'Content-Type: application/json' \ -d '{"name":"Functions"}' \ @@ -31,7 +29,7 @@ if [[ $(echo "$output" | jq -r '.message') != 'Hello Functions!' ]]; then fi # 3. POST request with secret key -output=$(curl 'http://127.0.0.1:54321/functions/v1/hello-world' \ +output=$(curl -sS 'http://127.0.0.1:54321/functions/v1/hello-world' \ -H 'apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz' \ -H 'Content-Type: application/json' \ -d '{"name":"Functions"}' \ @@ -43,7 +41,7 @@ if [[ $(echo "$output" | jq -r '.message') != 'Hello Functions!' ]]; then fi # 4. POST request with service role key -output=$(curl 'http://127.0.0.1:54321/functions/v1/hello-world' \ +output=$(curl -sS 'http://127.0.0.1:54321/functions/v1/hello-world' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU' \ -H 'Content-Type: application/json' \ -d '{"name":"Functions"}' \ diff --git a/tests/postgrest.sh b/tests/postgrest.sh index b97043df0b..4a4ef9a18e 100755 --- a/tests/postgrest.sh +++ b/tests/postgrest.sh @@ -4,10 +4,8 @@ set -eou pipefail # 0. Create test table with RLS # supabase --workdir tests migrations up -echo "Running PostgREST tests..." - # 1. Create todo as service role -output=$(curl 'http://127.0.0.1:54321/rest/v1/todos' \ +output=$(curl -sS 'http://127.0.0.1:54321/rest/v1/todos' \ -H 'apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz' \ -H 'Content-Type: application/json' \ -H 'Prefer: return=representation' \ @@ -20,7 +18,7 @@ if [[ $(echo "$output" | jq -r 'length') != '1' ]]; then fi # 2. Create todo as anon role should fail -output=$(curl 'http://127.0.0.1:54321/rest/v1/todos' \ +output=$(curl -sS 'http://127.0.0.1:54321/rest/v1/todos' \ -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ -H 'Content-Type: application/json' \ -d '{"task": "New task", "done": false}' \ @@ -32,7 +30,7 @@ if [[ $(echo "$output" | jq -r '.code') != '42501' ]]; then fi # 3. List todos as anon role -output=$(curl -G 'http://127.0.0.1:54321/rest/v1/todos' \ +output=$(curl -sS -G 'http://127.0.0.1:54321/rest/v1/todos' \ -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ -H 'Content-Type: application/json' \ ) @@ -43,7 +41,7 @@ if [[ $(echo "$output" | jq -r 'length') != '1' ]]; then fi # 4. Delete todo as anon role should fail -output=$(curl -X DELETE 'http://127.0.0.1:54321/rest/v1/todos?id=eq.1' \ +output=$(curl -sS -X DELETE 'http://127.0.0.1:54321/rest/v1/todos?id=eq.1' \ -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ -H 'Content-Type: application/json' \ -H 'Prefer: return=representation' \ @@ -55,7 +53,7 @@ if [[ $(echo "$output" | jq -r 'length') != '0' ]]; then fi # 5. Delete todo as authenticated role (custom jwt) -output=$(curl -X DELETE 'http://127.0.0.1:54321/rest/v1/todos?id=not.eq.0' \ +output=$(curl -sS -X DELETE 'http://127.0.0.1:54321/rest/v1/todos?id=not.eq.0' \ -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU" \ -H 'Content-Type: application/json' \ diff --git a/tests/realtime.sh b/tests/realtime.sh index 65586829d5..ddcd147f30 100755 --- a/tests/realtime.sh +++ b/tests/realtime.sh @@ -1,8 +1,6 @@ #!/bin/bash set -eou pipefail -echo "Running Realtime tests..." - # 1. Join realtime with legacy key output=$(echo '{"topic":"realtime:room1","ref":1,"event":"phx_join","payload":{"config":{"broadcast":{"ack":true},"presence":{"enabled":true},"private":false}}}' |\ websocat 'ws://127.0.0.1:54321/realtime/v1/websocket?apikey=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0&vsn=1.0.0' \ @@ -24,7 +22,7 @@ if [[ $(echo "$output" | jq -r '.payload.status') != 'ok' ]]; then fi ## 3. Broadcast with secret key -curl -f 'http://127.0.0.1:54321/realtime/v1/api/broadcast' \ +curl -sSf 'http://127.0.0.1:54321/realtime/v1/api/broadcast' \ -H 'apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz' \ -H 'Content-Type: application/json' \ -d '{"messages":[{"topic":"room1","event":"my_event","payload":{"foo":"bar"},"private":true}]}' diff --git a/tests/storage.sh b/tests/storage.sh index 135c9536ca..ce876d9235 100755 --- a/tests/storage.sh +++ b/tests/storage.sh @@ -1,10 +1,8 @@ #!/bin/bash set -eou pipefail -echo "Running Storage tests..." - # 1. Create test bucket as service role -output=$(curl 'http://127.0.0.1:54321/storage/v1/bucket' \ +output=$(curl -sS 'http://127.0.0.1:54321/storage/v1/bucket' \ -H 'apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz' \ -H 'Content-Type: application/json' \ -d '{"name":"test"}' \ @@ -16,7 +14,7 @@ if [[ $(echo "$output" | jq -r '.name') != 'test' ]]; then fi # 2. Create test bucket as service role (legacy key) -output=$(curl -X DELETE 'http://127.0.0.1:54321/storage/v1/bucket/test' \ +output=$(curl -sS -X DELETE 'http://127.0.0.1:54321/storage/v1/bucket/test' \ -H 'apikey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU' \ -H 'Content-Type: application/json' \ ) @@ -27,7 +25,7 @@ if [[ $(echo "$output" | jq -r '.message') != 'Successfully deleted' ]]; then fi # 3. Unauthenticated requests are rejected -output=$(curl 'http://127.0.0.1:54321/storage/v1/bucket' \ +output=$(curl -sS 'http://127.0.0.1:54321/storage/v1/bucket' \ -H 'Content-Type: application/json' \ -d '{"name":"test"}' \ ) From 8e3e27b654d0af2c1da945b396b7e87174d9e151 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Thu, 5 Feb 2026 13:26:41 +0800 Subject: [PATCH 027/117] chore: remove hardcoded keys --- .github/workflows/ci.yml | 4 +--- e2e-test.sh | 7 +++++-- tests/README.md | 4 ++-- tests/auth.sh | 8 ++++---- tests/edge-runtime.sh | 8 ++++---- tests/postgrest.sh | 12 ++++++------ tests/realtime.sh | 6 +++--- tests/storage.sh | 4 ++-- 8 files changed, 27 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b85234166..f3439672fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -79,9 +79,7 @@ jobs: - run: ./main start --workdir tests env: SUPABASE_INTERNAL_IMAGE_REGISTRY: ghcr.io - - run: | - sudo apt-get update - sudo apt-get -y websocat + - run: sudo apt-get update && sudo apt-get install -y websocat - run: ./e2e-test.sh ./main link: diff --git a/e2e-test.sh b/e2e-test.sh index b28d67f996..80254f1be7 100755 --- a/e2e-test.sh +++ b/e2e-test.sh @@ -2,7 +2,7 @@ set -eou pipefail dotenv=$("${1:-supabase}" --workdir tests status -o env) -source <(echo "$dotenv" | sed 's/^/export /') +export $(echo "$dotenv" | xargs) for tc in ./tests/*.sh; do echo "Running $tc" >&2 @@ -10,4 +10,7 @@ for tc in ./tests/*.sh; do done wait -echo "All tests have completed." +status="$?" + +echo "All tests have completed." >&2 +exit "$status" diff --git a/tests/README.md b/tests/README.md index 5535ab0c36..6a77e64721 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,4 +1,4 @@ -## End-to-End tests from client lib to local stack +## Local e2e tests 1. Start local stack @@ -9,7 +9,7 @@ supabase --workdir tests start 2. Run all tests ```bash -./tests/all.sh supabase +./e2e-test.sh supabase ``` ### Auth test diff --git a/tests/auth.sh b/tests/auth.sh index 738ea381b0..f255ff26b0 100755 --- a/tests/auth.sh +++ b/tests/auth.sh @@ -3,7 +3,7 @@ set -eou pipefail # 1. Create user with publishable key output=$(curl -sS 'http://127.0.0.1:54321/auth/v1/signup' \ - -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ + -H "apikey: $PUBLISHABLE_KEY" \ -H 'Content-Type: application/json' \ -d '{"email":"user@example.com","password":"aSecurePassword123"}' \ ) @@ -16,7 +16,7 @@ fi # 2. Delete user with secret key user_id=$(echo "$output" | jq -r '.user.id') output=$(curl -sS -X DELETE "http://127.0.0.1:54321/auth/v1/admin/users/$user_id" \ - -H "apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz" \ + -H "apikey: $SECRET_KEY" \ -H 'Content-Type: application/json' \ ) if [[ "$output" != '{}' ]]; then @@ -27,7 +27,7 @@ fi # 3. Create user with legacy anon key output=$(curl -sS 'http://127.0.0.1:54321/auth/v1/signup' \ - -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0' \ + -H "Authorization: Bearer $ANON_KEY" \ -H 'Content-Type: application/json' \ -d '{"email":"user@example.com","password":"aSecurePassword123"}' \ ) @@ -40,7 +40,7 @@ fi # 4. Delete user with legacy service role key user_id=$(echo "$output" | jq -r '.user.id') output=$(curl -sS -X DELETE "http://127.0.0.1:54321/auth/v1/admin/users/$user_id" \ - -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU" \ + -H "Authorization: Bearer $SERVICE_ROLE_KEY" \ -H 'Content-Type: application/json' \ ) if [[ "$output" != '{}' ]]; then diff --git a/tests/edge-runtime.sh b/tests/edge-runtime.sh index cbc657fbea..803ab8e556 100755 --- a/tests/edge-runtime.sh +++ b/tests/edge-runtime.sh @@ -6,7 +6,7 @@ set -eou pipefail # 1. POST request with publishable key output=$(curl -sS 'http://127.0.0.1:54321/functions/v1/hello-world' \ - -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ + -H "apikey: $PUBLISHABLE_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Functions"}' \ ) @@ -18,7 +18,7 @@ fi # 2. POST request with legacy key output=$(curl -sS 'http://127.0.0.1:54321/functions/v1/hello-world' \ - -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0' \ + -H "Authorization: Bearer $ANON_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Functions"}' \ ) @@ -30,7 +30,7 @@ fi # 3. POST request with secret key output=$(curl -sS 'http://127.0.0.1:54321/functions/v1/hello-world' \ - -H 'apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz' \ + -H "apikey: $SECRET_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Functions"}' \ ) @@ -42,7 +42,7 @@ fi # 4. POST request with service role key output=$(curl -sS 'http://127.0.0.1:54321/functions/v1/hello-world' \ - -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU' \ + -H "Authorization: Bearer $SERVICE_ROLE_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Functions"}' \ ) diff --git a/tests/postgrest.sh b/tests/postgrest.sh index 4a4ef9a18e..822e2437b9 100755 --- a/tests/postgrest.sh +++ b/tests/postgrest.sh @@ -6,7 +6,7 @@ set -eou pipefail # 1. Create todo as service role output=$(curl -sS 'http://127.0.0.1:54321/rest/v1/todos' \ - -H 'apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz' \ + -H "apikey: $SECRET_KEY" \ -H 'Content-Type: application/json' \ -H 'Prefer: return=representation' \ -d '{"task": "New task", "done": false}' \ @@ -19,7 +19,7 @@ fi # 2. Create todo as anon role should fail output=$(curl -sS 'http://127.0.0.1:54321/rest/v1/todos' \ - -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ + -H "apikey: $PUBLISHABLE_KEY" \ -H 'Content-Type: application/json' \ -d '{"task": "New task", "done": false}' \ ) @@ -31,7 +31,7 @@ fi # 3. List todos as anon role output=$(curl -sS -G 'http://127.0.0.1:54321/rest/v1/todos' \ - -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ + -H "apikey: $PUBLISHABLE_KEY" \ -H 'Content-Type: application/json' \ ) if [[ $(echo "$output" | jq -r 'length') != '1' ]]; then @@ -42,7 +42,7 @@ fi # 4. Delete todo as anon role should fail output=$(curl -sS -X DELETE 'http://127.0.0.1:54321/rest/v1/todos?id=eq.1' \ - -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ + -H "apikey: $PUBLISHABLE_KEY" \ -H 'Content-Type: application/json' \ -H 'Prefer: return=representation' \ ) @@ -54,8 +54,8 @@ fi # 5. Delete todo as authenticated role (custom jwt) output=$(curl -sS -X DELETE 'http://127.0.0.1:54321/rest/v1/todos?id=not.eq.0' \ - -H 'apikey: sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH' \ - -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU" \ + -H "apikey: $PUBLISHABLE_KEY" \ + -H "Authorization: Bearer $SERVICE_ROLE_KEY" \ -H 'Content-Type: application/json' \ -H 'Prefer: return=representation' \ ) diff --git a/tests/realtime.sh b/tests/realtime.sh index ddcd147f30..7d4ea8752b 100755 --- a/tests/realtime.sh +++ b/tests/realtime.sh @@ -3,7 +3,7 @@ set -eou pipefail # 1. Join realtime with legacy key output=$(echo '{"topic":"realtime:room1","ref":1,"event":"phx_join","payload":{"config":{"broadcast":{"ack":true},"presence":{"enabled":true},"private":false}}}' |\ - websocat 'ws://127.0.0.1:54321/realtime/v1/websocket?apikey=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0&vsn=1.0.0' \ + websocat "ws://127.0.0.1:54321/realtime/v1/websocket?apikey=$ANON_KEY&vsn=1.0.0" \ ) if [[ $(echo "$output" | jq -r '.payload.status') != 'ok' ]]; then echo 'Joining realtime with legacy key should succeed.' >&2 @@ -13,7 +13,7 @@ fi # 2. Join realtime with publishable key output=$(echo '{"topic":"realtime:room1","ref":1,"event":"phx_join","payload":{"config":{"broadcast":{"ack":true},"presence":{"enabled":true},"private":false}}}' |\ - websocat 'ws://127.0.0.1:54321/realtime/v1/websocket?apikey=sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH&vsn=1.0.0' \ + websocat "ws://127.0.0.1:54321/realtime/v1/websocket?apikey=$PUBLISHABLE_KEY&vsn=1.0.0" \ ) if [[ $(echo "$output" | jq -r '.payload.status') != 'ok' ]]; then echo 'Joining realtime as anon should succeed.' >&2 @@ -23,6 +23,6 @@ fi ## 3. Broadcast with secret key curl -sSf 'http://127.0.0.1:54321/realtime/v1/api/broadcast' \ - -H 'apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz' \ + -H "apikey: $SECRET_KEY" \ -H 'Content-Type: application/json' \ -d '{"messages":[{"topic":"room1","event":"my_event","payload":{"foo":"bar"},"private":true}]}' diff --git a/tests/storage.sh b/tests/storage.sh index ce876d9235..4b0f546cb4 100755 --- a/tests/storage.sh +++ b/tests/storage.sh @@ -3,7 +3,7 @@ set -eou pipefail # 1. Create test bucket as service role output=$(curl -sS 'http://127.0.0.1:54321/storage/v1/bucket' \ - -H 'apikey: sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz' \ + -H "apikey: $SECRET_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"test"}' \ ) @@ -15,7 +15,7 @@ fi # 2. Create test bucket as service role (legacy key) output=$(curl -sS -X DELETE 'http://127.0.0.1:54321/storage/v1/bucket/test' \ - -H 'apikey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU' \ + -H "apikey: $SERVICE_ROLE_KEY" \ -H 'Content-Type: application/json' \ ) if [[ $(echo "$output" | jq -r '.message') != 'Successfully deleted' ]]; then From 3d3e51c5e6d801425be7418449b2b98913ee7f30 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Thu, 5 Feb 2026 13:55:42 +0800 Subject: [PATCH 028/117] chore: add websocat install step --- .github/workflows/ci.yml | 6 +++++- tests/README.md | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f3439672fb..a8fa08a7de 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -79,7 +79,11 @@ jobs: - run: ./main start --workdir tests env: SUPABASE_INTERNAL_IMAGE_REGISTRY: ghcr.io - - run: sudo apt-get update && sudo apt-get install -y websocat + - name: Install websocat + run: | + sudo wget -qO /usr/local/bin/websocat https://github.com/vi/websocat/releases/latest/download/websocat.x86_64-unknown-linux-musl + sudo chmod a+x /usr/local/bin/websocat + websocat --version - run: ./e2e-test.sh ./main link: diff --git a/tests/README.md b/tests/README.md index 6a77e64721..edc070840b 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,5 +1,11 @@ ## Local e2e tests +0. Install websocat + +```bash +brew install websocat +``` + 1. Start local stack ```bash From d6ae34e6239826de9407c0a07a5ca9b5b976c05f Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Thu, 5 Feb 2026 16:12:11 +0800 Subject: [PATCH 029/117] chore: refactor api url --- tests/auth.sh | 8 ++++---- tests/edge-runtime.sh | 8 ++++---- tests/postgrest.sh | 10 +++++----- tests/realtime.sh | 2 +- tests/storage.sh | 6 +++--- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/auth.sh b/tests/auth.sh index f255ff26b0..17763e88f8 100755 --- a/tests/auth.sh +++ b/tests/auth.sh @@ -2,7 +2,7 @@ set -eou pipefail # 1. Create user with publishable key -output=$(curl -sS 'http://127.0.0.1:54321/auth/v1/signup' \ +output=$(curl -sS "$API_URL/auth/v1/signup" \ -H "apikey: $PUBLISHABLE_KEY" \ -H 'Content-Type: application/json' \ -d '{"email":"user@example.com","password":"aSecurePassword123"}' \ @@ -15,7 +15,7 @@ fi # 2. Delete user with secret key user_id=$(echo "$output" | jq -r '.user.id') -output=$(curl -sS -X DELETE "http://127.0.0.1:54321/auth/v1/admin/users/$user_id" \ +output=$(curl -sS -X DELETE "$API_URL/auth/v1/admin/users/$user_id" \ -H "apikey: $SECRET_KEY" \ -H 'Content-Type: application/json' \ ) @@ -26,7 +26,7 @@ if [[ "$output" != '{}' ]]; then fi # 3. Create user with legacy anon key -output=$(curl -sS 'http://127.0.0.1:54321/auth/v1/signup' \ +output=$(curl -sS "$API_URL/auth/v1/signup" \ -H "Authorization: Bearer $ANON_KEY" \ -H 'Content-Type: application/json' \ -d '{"email":"user@example.com","password":"aSecurePassword123"}' \ @@ -39,7 +39,7 @@ fi # 4. Delete user with legacy service role key user_id=$(echo "$output" | jq -r '.user.id') -output=$(curl -sS -X DELETE "http://127.0.0.1:54321/auth/v1/admin/users/$user_id" \ +output=$(curl -sS -X DELETE "$API_URL/auth/v1/admin/users/$user_id" \ -H "Authorization: Bearer $SERVICE_ROLE_KEY" \ -H 'Content-Type: application/json' \ ) diff --git a/tests/edge-runtime.sh b/tests/edge-runtime.sh index 803ab8e556..25a8afbb60 100755 --- a/tests/edge-runtime.sh +++ b/tests/edge-runtime.sh @@ -5,7 +5,7 @@ set -eou pipefail # supabase --workdir tests functions serve # 1. POST request with publishable key -output=$(curl -sS 'http://127.0.0.1:54321/functions/v1/hello-world' \ +output=$(curl -sS "$API_URL/functions/v1/hello-world" \ -H "apikey: $PUBLISHABLE_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Functions"}' \ @@ -17,7 +17,7 @@ if [[ $(echo "$output" | jq -r '.message') != 'Hello Functions!' ]]; then fi # 2. POST request with legacy key -output=$(curl -sS 'http://127.0.0.1:54321/functions/v1/hello-world' \ +output=$(curl -sS "$API_URL/functions/v1/hello-world" \ -H "Authorization: Bearer $ANON_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Functions"}' \ @@ -29,7 +29,7 @@ if [[ $(echo "$output" | jq -r '.message') != 'Hello Functions!' ]]; then fi # 3. POST request with secret key -output=$(curl -sS 'http://127.0.0.1:54321/functions/v1/hello-world' \ +output=$(curl -sS "$API_URL/functions/v1/hello-world" \ -H "apikey: $SECRET_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Functions"}' \ @@ -41,7 +41,7 @@ if [[ $(echo "$output" | jq -r '.message') != 'Hello Functions!' ]]; then fi # 4. POST request with service role key -output=$(curl -sS 'http://127.0.0.1:54321/functions/v1/hello-world' \ +output=$(curl -sS "$API_URL/functions/v1/hello-world" \ -H "Authorization: Bearer $SERVICE_ROLE_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"Functions"}' \ diff --git a/tests/postgrest.sh b/tests/postgrest.sh index 822e2437b9..5911c59544 100755 --- a/tests/postgrest.sh +++ b/tests/postgrest.sh @@ -5,7 +5,7 @@ set -eou pipefail # supabase --workdir tests migrations up # 1. Create todo as service role -output=$(curl -sS 'http://127.0.0.1:54321/rest/v1/todos' \ +output=$(curl -sS "$API_URL/rest/v1/todos" \ -H "apikey: $SECRET_KEY" \ -H 'Content-Type: application/json' \ -H 'Prefer: return=representation' \ @@ -18,7 +18,7 @@ if [[ $(echo "$output" | jq -r 'length') != '1' ]]; then fi # 2. Create todo as anon role should fail -output=$(curl -sS 'http://127.0.0.1:54321/rest/v1/todos' \ +output=$(curl -sS "$API_URL/rest/v1/todos" \ -H "apikey: $PUBLISHABLE_KEY" \ -H 'Content-Type: application/json' \ -d '{"task": "New task", "done": false}' \ @@ -30,7 +30,7 @@ if [[ $(echo "$output" | jq -r '.code') != '42501' ]]; then fi # 3. List todos as anon role -output=$(curl -sS -G 'http://127.0.0.1:54321/rest/v1/todos' \ +output=$(curl -sS -G "$API_URL/rest/v1/todos" \ -H "apikey: $PUBLISHABLE_KEY" \ -H 'Content-Type: application/json' \ ) @@ -41,7 +41,7 @@ if [[ $(echo "$output" | jq -r 'length') != '1' ]]; then fi # 4. Delete todo as anon role should fail -output=$(curl -sS -X DELETE 'http://127.0.0.1:54321/rest/v1/todos?id=eq.1' \ +output=$(curl -sS -X DELETE "$API_URL/rest/v1/todos?id=eq.1" \ -H "apikey: $PUBLISHABLE_KEY" \ -H 'Content-Type: application/json' \ -H 'Prefer: return=representation' \ @@ -53,7 +53,7 @@ if [[ $(echo "$output" | jq -r 'length') != '0' ]]; then fi # 5. Delete todo as authenticated role (custom jwt) -output=$(curl -sS -X DELETE 'http://127.0.0.1:54321/rest/v1/todos?id=not.eq.0' \ +output=$(curl -sS -X DELETE "$API_URL/rest/v1/todos?id=not.eq.0" \ -H "apikey: $PUBLISHABLE_KEY" \ -H "Authorization: Bearer $SERVICE_ROLE_KEY" \ -H 'Content-Type: application/json' \ diff --git a/tests/realtime.sh b/tests/realtime.sh index 7d4ea8752b..512bc009ce 100755 --- a/tests/realtime.sh +++ b/tests/realtime.sh @@ -22,7 +22,7 @@ if [[ $(echo "$output" | jq -r '.payload.status') != 'ok' ]]; then fi ## 3. Broadcast with secret key -curl -sSf 'http://127.0.0.1:54321/realtime/v1/api/broadcast' \ +curl -sSf "$API_URL/realtime/v1/api/broadcast" \ -H "apikey: $SECRET_KEY" \ -H 'Content-Type: application/json' \ -d '{"messages":[{"topic":"room1","event":"my_event","payload":{"foo":"bar"},"private":true}]}' diff --git a/tests/storage.sh b/tests/storage.sh index 4b0f546cb4..1a68fc8102 100755 --- a/tests/storage.sh +++ b/tests/storage.sh @@ -2,7 +2,7 @@ set -eou pipefail # 1. Create test bucket as service role -output=$(curl -sS 'http://127.0.0.1:54321/storage/v1/bucket' \ +output=$(curl -sS "$API_URL/storage/v1/bucket" \ -H "apikey: $SECRET_KEY" \ -H 'Content-Type: application/json' \ -d '{"name":"test"}' \ @@ -14,7 +14,7 @@ if [[ $(echo "$output" | jq -r '.name') != 'test' ]]; then fi # 2. Create test bucket as service role (legacy key) -output=$(curl -sS -X DELETE 'http://127.0.0.1:54321/storage/v1/bucket/test' \ +output=$(curl -sS -X DELETE "$API_URL/storage/v1/bucket/test" \ -H "apikey: $SERVICE_ROLE_KEY" \ -H 'Content-Type: application/json' \ ) @@ -25,7 +25,7 @@ if [[ $(echo "$output" | jq -r '.message') != 'Successfully deleted' ]]; then fi # 3. Unauthenticated requests are rejected -output=$(curl -sS 'http://127.0.0.1:54321/storage/v1/bucket' \ +output=$(curl -sS "$API_URL/storage/v1/bucket" \ -H 'Content-Type: application/json' \ -d '{"name":"test"}' \ ) From d9a824cfe69987df2b00305ae1b60e5714eb9a62 Mon Sep 17 00:00:00 2001 From: 7ttp <117663341+7ttp@users.noreply.github.com> Date: Thu, 5 Feb 2026 17:48:23 +0530 Subject: [PATCH 030/117] fix: prevent panic when signing keys array is empty --- pkg/config/apikeys.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/apikeys.go b/pkg/config/apikeys.go index 1149e5a8d1..cb1b457cab 100644 --- a/pkg/config/apikeys.go +++ b/pkg/config/apikeys.go @@ -74,7 +74,7 @@ func (a *auth) generateAPIKeys() error { func (a auth) generateJWT(role string) (string, error) { claims := CustomClaims{Issuer: "supabase-demo", Role: role} - if len(a.SigningKeysPath) > 0 { + if len(a.SigningKeysPath) > 0 && len(a.SigningKeys) > 0 { claims.ExpiresAt = jwt.NewNumericDate(time.Now().Add(time.Hour * 24 * 365 * 10)) // 10 years return GenerateAsymmetricJWT(a.SigningKeys[0], claims) } From 54bacea89cfc0983b472052cc13ced4100465d21 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 00:14:06 +0000 Subject: [PATCH 031/117] fix(docker): bump the docker-minor group in /pkg/config/templates with 2 updates (#4813) fix(docker): bump the docker-minor group Bumps the docker-minor group in /pkg/config/templates with 2 updates: supabase/realtime and supabase/storage-api. Updates `supabase/realtime` from v2.74.7 to v2.74.9 Updates `supabase/storage-api` from v1.37.0 to v1.37.5 --- updated-dependencies: - dependency-name: supabase/realtime dependency-version: v2.74.9 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/storage-api dependency-version: v1.37.5 dependency-type: direct:production dependency-group: docker-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index b79c943766..20c8b8d90a 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -11,8 +11,8 @@ FROM supabase/edge-runtime:v1.70.1 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.186.0 AS gotrue -FROM supabase/realtime:v2.74.7 AS realtime -FROM supabase/storage-api:v1.37.0 AS storage +FROM supabase/realtime:v2.74.9 AS realtime +FROM supabase/storage-api:v1.37.5 AS storage FROM supabase/logflare:1.30.8 AS logflare # Append to JobImages when adding new dependencies below FROM supabase/pgadmin-schema-diff:cli-0.0.5 AS differ From 72239e3fed7eaa93067491421a01e382d08bb5de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 00:19:34 +0000 Subject: [PATCH 032/117] fix(docker): bump supabase/postgres from 17.6.1.080 to 17.6.1.081 in /pkg/config/templates (#4814) fix(docker): bump supabase/postgres in /pkg/config/templates Bumps supabase/postgres from 17.6.1.080 to 17.6.1.081. --- updated-dependencies: - dependency-name: supabase/postgres dependency-version: 17.6.1.081 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 20c8b8d90a..122a7b67dd 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:17.6.1.080 AS pg +FROM supabase/postgres:17.6.1.081 AS pg # 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 8fe996e469e5fedf452121f5ed098ab36113bdf2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 7 Feb 2026 00:07:19 +0000 Subject: [PATCH 033/117] fix(docker): bump the docker-minor group in /pkg/config/templates with 2 updates (#4816) fix(docker): bump the docker-minor group Bumps the docker-minor group in /pkg/config/templates with 2 updates: supabase/realtime and supabase/storage-api. Updates `supabase/realtime` from v2.74.9 to v2.75.0 Updates `supabase/storage-api` from v1.37.5 to v1.37.6 --- updated-dependencies: - dependency-name: supabase/realtime dependency-version: v2.75.0 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/storage-api dependency-version: v1.37.6 dependency-type: direct:production dependency-group: docker-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 122a7b67dd..c46353d9c1 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -11,8 +11,8 @@ FROM supabase/edge-runtime:v1.70.1 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.186.0 AS gotrue -FROM supabase/realtime:v2.74.9 AS realtime -FROM supabase/storage-api:v1.37.5 AS storage +FROM supabase/realtime:v2.75.0 AS realtime +FROM supabase/storage-api:v1.37.6 AS storage FROM supabase/logflare:1.30.8 AS logflare # Append to JobImages when adding new dependencies below FROM supabase/pgadmin-schema-diff:cli-0.0.5 AS differ From ecf99c01a931ee7fe9f34a5c0e6192b2a6167009 Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Sat, 7 Feb 2026 17:16:53 +0800 Subject: [PATCH 034/117] chore: remove unused studio config marshalling Removed marshalling of studio config and related variable. --- internal/start/start.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/internal/start/start.go b/internal/start/start.go index aa409d44af..c35efa2e36 100644 --- a/internal/start/start.go +++ b/internal/start/start.go @@ -1147,10 +1147,6 @@ EOF } // Mount snippets directory for Studio to access - studioConfig, err := json.Marshal(utils.Config) - if err != nil { - return errors.Errorf("failed to marshal config: %w", err) - } hostSnippetsPath := filepath.Join(workdir, utils.SnippetsDir) containerSnippetsPath := utils.ToDockerPath(hostSnippetsPath) binds = append(binds, fmt.Sprintf("%s:%s:rw", hostSnippetsPath, containerSnippetsPath)) @@ -1175,7 +1171,6 @@ EOF fmt.Sprintf("NEXT_ANALYTICS_BACKEND_PROVIDER=%v", utils.Config.Analytics.Backend), "EDGE_FUNCTIONS_MANAGEMENT_FOLDER=" + utils.ToDockerPath(filepath.Join(workdir, utils.FunctionsDir)), "SNIPPETS_MANAGEMENT_FOLDER=" + containerSnippetsPath, - "SUPABASE_CONFIG=" + string(studioConfig), // Ref: https://github.com/vercel/next.js/issues/51684#issuecomment-1612834913 "HOSTNAME=0.0.0.0", }, From f7b79efc0bd36f4040fb52f83db1c2d8b38bbee3 Mon Sep 17 00:00:00 2001 From: Vaibhav <117663341+7ttp@users.noreply.github.com> Date: Sat, 7 Feb 2026 16:42:53 +0530 Subject: [PATCH 035/117] fix: add schema qualification hints for extension type errors (#4513) --- pkg/migration/file.go | 28 ++++++++++++- pkg/migration/file_test.go | 80 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/pkg/migration/file.go b/pkg/migration/file.go index fbd4a3b7fd..540c129e33 100644 --- a/pkg/migration/file.go +++ b/pkg/migration/file.go @@ -26,7 +26,10 @@ type MigrationFile struct { Statements []string } -var migrateFilePattern = regexp.MustCompile(`^([0-9]+)_(.*)\.sql$`) +var ( + migrateFilePattern = regexp.MustCompile(`^([0-9]+)_(.*)\.sql$`) + typeNamePattern = regexp.MustCompile(`type "([^"]+)" does not exist`) +) func NewMigrationFromFile(path string, fsys fs.FS) (*MigrationFile, error) { lines, err := parseFile(path, fsys) @@ -96,6 +99,14 @@ func (m *MigrationFile) ExecBatch(ctx context.Context, conn *pgx.Conn) error { if len(pgErr.Detail) > 0 { msg = append(msg, pgErr.Detail) } + // Provide helpful hint for extension type errors (SQLSTATE 42704: undefined_object) + if typeName := extractTypeName(pgErr.Message); len(typeName) > 0 && pgErr.Code == "42704" && !IsSchemaQualified(typeName) { + msg = append(msg, "") + msg = append(msg, "Hint: This type may be defined in a schema that's not in your search_path.") + msg = append(msg, " Use schema-qualified type references to avoid this error:") + msg = append(msg, fmt.Sprintf(" CREATE TABLE example (col extensions.%s);", typeName)) + msg = append(msg, " Learn more: supabase migration new --help") + } } msg = append(msg, fmt.Sprintf("At statement: %d", i), stat) return errors.Errorf("%w\n%s", err, strings.Join(msg, "\n")) @@ -120,6 +131,21 @@ func markError(stat string, pos int) string { return strings.Join(lines, "\n") } +// extractTypeName extracts the type name from PostgreSQL error messages like: +// 'type "ltree" does not exist' -> "ltree" +func extractTypeName(errMsg string) string { + matches := typeNamePattern.FindStringSubmatch(errMsg) + if len(matches) > 1 { + return matches[1] + } + return "" +} + +// IsSchemaQualified checks if a type name already contains a schema qualifier (e.g., "extensions.ltree") +func IsSchemaQualified(typeName string) bool { + return strings.Contains(typeName, ".") +} + func (m *MigrationFile) insertVersionSQL(conn *pgx.Conn, batch *pgconn.Batch) error { value := pgtype.TextArray{} if err := value.Set(m.Statements); err != nil { diff --git a/pkg/migration/file_test.go b/pkg/migration/file_test.go index 45bee71b65..703f26954c 100644 --- a/pkg/migration/file_test.go +++ b/pkg/migration/file_test.go @@ -77,4 +77,84 @@ func TestMigrationFile(t *testing.T) { assert.ErrorContains(t, err, "ERROR: schema \"public\" already exists (SQLSTATE 42P06)") assert.ErrorContains(t, err, "At statement: 0\ncreate schema public") }) + + t.Run("provides helpful hint for extension type errors", func(t *testing.T) { + migration := MigrationFile{ + Statements: []string{"CREATE TABLE test (path ltree NOT NULL)"}, + Version: "0", + } + // Setup mock postgres + conn := pgtest.NewConn() + defer conn.Close(t) + conn.Query(migration.Statements[0]). + ReplyError("42704", `type "ltree" does not exist`). + Query(INSERT_MIGRATION_VERSION, "0", "", migration.Statements). + Reply("INSERT 0 1") + // Run test + err := migration.ExecBatch(context.Background(), conn.MockClient(t)) + // Check error + assert.ErrorContains(t, err, `type "ltree" does not exist`) + assert.ErrorContains(t, err, "Hint: This type may be defined in a schema") + assert.ErrorContains(t, err, "extensions.ltree") + assert.ErrorContains(t, err, "supabase migration new --help") + assert.ErrorContains(t, err, "At statement: 0") + }) + + t.Run("skips hint for schema-qualified type errors", func(t *testing.T) { + migration := MigrationFile{ + Statements: []string{"CREATE TABLE test (path extensions.ltree NOT NULL)"}, + Version: "0", + } + // Setup mock postgres + conn := pgtest.NewConn() + defer conn.Close(t) + conn.Query(migration.Statements[0]). + ReplyError("42704", `type "extensions.ltree" does not exist`). + Query(INSERT_MIGRATION_VERSION, "0", "", migration.Statements). + Reply("INSERT 0 1") + // Run test + err := migration.ExecBatch(context.Background(), conn.MockClient(t)) + // Check error - should NOT contain hint since type is already schema-qualified + assert.ErrorContains(t, err, `type "extensions.ltree" does not exist`) + assert.NotContains(t, err.Error(), "Hint: This type may be defined in a schema") + }) +} + +func TestExtractTypeName(t *testing.T) { + t.Run("extracts type name from standard error message", func(t *testing.T) { + result := extractTypeName(`type "ltree" does not exist`) + assert.Equal(t, "ltree", result) + }) + + t.Run("extracts schema-qualified type name", func(t *testing.T) { + result := extractTypeName(`type "extensions.ltree" does not exist`) + assert.Equal(t, "extensions.ltree", result) + }) + + t.Run("extracts type with underscores", func(t *testing.T) { + result := extractTypeName(`type "my_custom_type" does not exist`) + assert.Equal(t, "my_custom_type", result) + }) + + t.Run("returns empty string for non-matching message", func(t *testing.T) { + result := extractTypeName(`column "name" does not exist`) + assert.Equal(t, "", result) + }) + + t.Run("returns empty string for empty message", func(t *testing.T) { + result := extractTypeName("") + assert.Equal(t, "", result) + }) + + t.Run("handles type names with numbers", func(t *testing.T) { + result := extractTypeName(`type "type123" does not exist`) + assert.Equal(t, "type123", result) + }) +} + +func TestIsSchemaQualified(t *testing.T) { + assert.True(t, IsSchemaQualified("extensions.ltree")) + assert.True(t, IsSchemaQualified("public.my_type")) + assert.False(t, IsSchemaQualified("ltree")) + assert.False(t, IsSchemaQualified("")) } From eb7f8ccab7d6ef603489a226aae6ff3dc2505a12 Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Sat, 7 Feb 2026 20:54:06 +0800 Subject: [PATCH 036/117] Revert "fix: set correct valid methods env var (#4781)" This reverts commit 3b18e9b9aa2d8cb0d422e985a45242f77ee96229. --- internal/start/start.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/start/start.go b/internal/start/start.go index c35efa2e36..39bdc67e09 100644 --- a/internal/start/start.go +++ b/internal/start/start.go @@ -627,7 +627,7 @@ EOF if keys, err := json.Marshal(utils.Config.Auth.SigningKeys); err == nil { env = append(env, "GOTRUE_JWT_KEYS="+string(keys)) // TODO: deprecate HS256 when it's no longer supported - env = append(env, "GOTRUE_JWT_VALIDMETHODS=HS256,RS256,ES256") + env = append(env, "GOTRUE_JWT_VALID_METHODS=HS256,RS256,ES256") } if utils.Config.Auth.Email.Smtp != nil && utils.Config.Auth.Email.Smtp.Enabled { From 521b09b3572a2c7a2b624f4a75d143a108d68297 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Feb 2026 00:07:16 +0000 Subject: [PATCH 037/117] fix(docker): bump supabase/storage-api from v1.37.6 to v1.37.7 in /pkg/config/templates in the docker-minor group (#4819) fix(docker): bump supabase/storage-api Bumps the docker-minor group in /pkg/config/templates with 1 update: supabase/storage-api. Updates `supabase/storage-api` from v1.37.6 to v1.37.7 --- updated-dependencies: - dependency-name: supabase/storage-api dependency-version: v1.37.7 dependency-type: direct:production dependency-group: docker-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 c46353d9c1..1fcb4a8fa3 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.7.4 AS supavisor FROM supabase/gotrue:v2.186.0 AS gotrue FROM supabase/realtime:v2.75.0 AS realtime -FROM supabase/storage-api:v1.37.6 AS storage +FROM supabase/storage-api:v1.37.7 AS storage FROM supabase/logflare:1.30.8 AS logflare # Append to JobImages when adding new dependencies below FROM supabase/pgadmin-schema-diff:cli-0.0.5 AS differ From 0ef2a1c28b8c9259f1d83a95791383160ccdf1d0 Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Sun, 8 Feb 2026 20:04:24 +0800 Subject: [PATCH 038/117] fix: set correct valid methods env var (#4821) Revert "Revert "fix: set correct valid methods env var (#4781)"" This reverts commit eb7f8ccab7d6ef603489a226aae6ff3dc2505a12. --- internal/start/start.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/start/start.go b/internal/start/start.go index 39bdc67e09..c35efa2e36 100644 --- a/internal/start/start.go +++ b/internal/start/start.go @@ -627,7 +627,7 @@ EOF if keys, err := json.Marshal(utils.Config.Auth.SigningKeys); err == nil { env = append(env, "GOTRUE_JWT_KEYS="+string(keys)) // TODO: deprecate HS256 when it's no longer supported - env = append(env, "GOTRUE_JWT_VALID_METHODS=HS256,RS256,ES256") + env = append(env, "GOTRUE_JWT_VALIDMETHODS=HS256,RS256,ES256") } if utils.Config.Auth.Email.Smtp != nil && utils.Config.Auth.Email.Smtp.Enabled { From a1db61c608180bca1e45ebb5fe7510d4fae982eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Feb 2026 00:15:43 +0000 Subject: [PATCH 039/117] fix(docker): bump supabase/realtime from v2.75.0 to v2.75.2 in /pkg/config/templates in the docker-minor group (#4822) fix(docker): bump supabase/realtime Bumps the docker-minor group in /pkg/config/templates with 1 update: supabase/realtime. Updates `supabase/realtime` from v2.75.0 to v2.75.2 --- updated-dependencies: - dependency-name: supabase/realtime dependency-version: v2.75.2 dependency-type: direct:production dependency-group: docker-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 1fcb4a8fa3..4f9fe60c4c 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -11,7 +11,7 @@ FROM supabase/edge-runtime:v1.70.1 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.186.0 AS gotrue -FROM supabase/realtime:v2.75.0 AS realtime +FROM supabase/realtime:v2.75.2 AS realtime FROM supabase/storage-api:v1.37.7 AS storage FROM supabase/logflare:1.30.8 AS logflare # Append to JobImages when adding new dependencies below From 8782075cb7bdad84248b4247c91245f29e1c1b97 Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Mon, 9 Feb 2026 11:23:03 +0800 Subject: [PATCH 040/117] chore: unit test for backup and restore (#4824) * chore: unit test for backup and restore * chore: reduce api mock boilerplate --- README.md | 2 +- internal/backups/list/list.go | 14 ++-- internal/backups/list/list_test.go | 97 ++++++++++++++++++++++++ internal/backups/restore/restore.go | 6 +- internal/backups/restore/restore_test.go | 53 +++++++++++++ internal/testing/apitest/platform.go | 11 +++ internal/testing/fstest/stdout.go | 26 +++++++ 7 files changed, 198 insertions(+), 11 deletions(-) create mode 100644 internal/backups/list/list_test.go create mode 100644 internal/backups/restore/restore_test.go create mode 100644 internal/testing/fstest/stdout.go diff --git a/README.md b/README.md index 71b140c741..da6cedb3d1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Supabase CLI -[![Coverage Status](https://coveralls.io/repos/github/supabase/cli/badge.svg?branch=main)](https://coveralls.io/github/supabase/cli?branch=main) [![Bitbucket Pipelines](https://img.shields.io/bitbucket/pipelines/supabase-cli/setup-cli/master?style=flat-square&label=Bitbucket%20Canary)](https://bitbucket.org/supabase-cli/setup-cli/pipelines) [![Gitlab Pipeline Status](https://img.shields.io/gitlab/pipeline-status/sweatybridge%2Fsetup-cli?label=Gitlab%20Canary) +[![Coverage Status](https://coveralls.io/repos/github/supabase/cli/badge.svg?branch=develop)](https://coveralls.io/github/supabase/cli?branch=develop) [![Bitbucket Pipelines](https://img.shields.io/bitbucket/pipelines/supabase-cli/setup-cli/master?style=flat-square&label=Bitbucket%20Canary)](https://bitbucket.org/supabase-cli/setup-cli/pipelines) [![Gitlab Pipeline Status](https://img.shields.io/gitlab/pipeline-status/sweatybridge%2Fsetup-cli?label=Gitlab%20Canary) ](https://gitlab.com/sweatybridge/setup-cli/-/pipelines) [Supabase](https://supabase.io) is an open source Firebase alternative. We're building the features of Firebase using enterprise-grade open source tools. diff --git a/internal/backups/list/list.go b/internal/backups/list/list.go index b4b16dd1c8..5df9ae252a 100644 --- a/internal/backups/list/list.go +++ b/internal/backups/list/list.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "os" + "strings" "github.com/go-errors/errors" "github.com/supabase/cli/internal/utils" @@ -45,21 +46,20 @@ const ( ) func listLogicalBackups(resp api.V1BackupsResponse) error { - table := `REGION|BACKUP TYPE|STATUS|CREATED AT (UTC) + var table strings.Builder + table.WriteString(`REGION|BACKUP TYPE|STATUS|CREATED AT (UTC) |-|-|-|-| -` +`) for _, backup := range resp.Backups { backupType := BACKUP_LOGICAL if backup.IsPhysicalBackup { backupType = BACKUP_PHYSICAL } - table += fmt.Sprintf( - "|`%s`|`%s`|`%s`|`%s`|\n", + fmt.Fprintf(&table, "|`%s`|`%s`|`%s`|`%s`|\n", utils.FormatRegion(resp.Region), backupType, backup.Status, - utils.FormatTimestamp(backup.InsertedAt), - ) + utils.FormatTimestamp(backup.InsertedAt)) } - return utils.RenderTable(table) + return utils.RenderTable(table.String()) } diff --git a/internal/backups/list/list_test.go b/internal/backups/list/list_test.go new file mode 100644 index 0000000000..a236959aa0 --- /dev/null +++ b/internal/backups/list/list_test.go @@ -0,0 +1,97 @@ +package list + +import ( + "context" + "errors" + "net/http" + "testing" + + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/flags" + "github.com/supabase/cli/pkg/api" +) + +func TestListBackup(t *testing.T) { + // Setup valid project ref + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("lists PITR backup", func(t *testing.T) { + t.Cleanup(fstest.MockStdout(t, ` + + REGION | WALG | PITR | EARLIEST TIMESTAMP | LATEST TIMESTAMP + ----------------------------|------|------|--------------------|------------------ + Southeast Asia (Singapore) | true | true | 0 | 0 + +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/database/backups"). + Reply(http.StatusOK). + JSON(api.V1BackupsResponse{ + Region: "ap-southeast-1", + WalgEnabled: true, + PitrEnabled: true, + }) + // Run test + err := Run(context.Background()) + assert.NoError(t, err) + }) + + t.Run("lists WALG backup", func(t *testing.T) { + t.Cleanup(fstest.MockStdout(t, ` + + REGION | BACKUP TYPE | STATUS | CREATED AT (UTC) + ----------------------------|-------------|-----------|--------------------- + Southeast Asia (Singapore) | PHYSICAL | COMPLETED | 2026-02-08 16:44:07 + +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/database/backups"). + Reply(http.StatusOK). + JSON(api.V1BackupsResponse{ + Region: "ap-southeast-1", + Backups: []struct { + InsertedAt string `json:"inserted_at"` + IsPhysicalBackup bool `json:"is_physical_backup"` + Status api.V1BackupsResponseBackupsStatus `json:"status"` + }{{ + InsertedAt: "2026-02-08 16:44:07", + IsPhysicalBackup: true, + Status: api.V1BackupsResponseBackupsStatusCOMPLETED, + }}, + }) + // Run test + err := Run(context.Background()) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/database/backups"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background()) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/database/backups"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background()) + assert.ErrorContains(t, err, "unexpected list backup status 503:") + }) +} diff --git a/internal/backups/restore/restore.go b/internal/backups/restore/restore.go index 8118f1bcde..6219039f92 100644 --- a/internal/backups/restore/restore.go +++ b/internal/backups/restore/restore.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "net/http" + "os" "github.com/go-errors/errors" "github.com/supabase/cli/internal/utils" @@ -13,12 +14,11 @@ import ( func Run(ctx context.Context, timestamp int64) error { body := api.V1RestorePitrBody{RecoveryTimeTargetUnix: timestamp} - resp, err := utils.GetSupabase().V1RestorePitrBackupWithResponse(ctx, flags.ProjectRef, body) - if err != nil { + if resp, err := utils.GetSupabase().V1RestorePitrBackupWithResponse(ctx, flags.ProjectRef, body); err != nil { return errors.Errorf("failed to restore backup: %w", err) } else if resp.StatusCode() != http.StatusCreated { return errors.Errorf("unexpected restore backup status %d: %s", resp.StatusCode(), string(resp.Body)) } - fmt.Println("Started PITR restore:", flags.ProjectRef) + fmt.Fprintln(os.Stderr, "Started PITR restore:", flags.ProjectRef) return nil } diff --git a/internal/backups/restore/restore_test.go b/internal/backups/restore/restore_test.go new file mode 100644 index 0000000000..e0ff3714e3 --- /dev/null +++ b/internal/backups/restore/restore_test.go @@ -0,0 +1,53 @@ +package restore + +import ( + "context" + "net/http" + "testing" + + "github.com/go-errors/errors" + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/flags" +) + +func TestRestoreBackup(t *testing.T) { + // Setup valid project ref + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("restores project to timestamp", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("/v1/projects/" + flags.ProjectRef + "/database/backups/restore-pitr"). + Reply(http.StatusCreated) + // Run test + err := Run(context.Background(), 0) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("/v1/projects/" + flags.ProjectRef + "/database/backups/restore-pitr"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), 0) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("/v1/projects/" + flags.ProjectRef + "/database/backups/restore-pitr"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), 0) + assert.ErrorContains(t, err, "unexpected restore backup status 503:") + }) +} diff --git a/internal/testing/apitest/platform.go b/internal/testing/apitest/platform.go index 54054108b4..6ae3d50ded 100644 --- a/internal/testing/apitest/platform.go +++ b/internal/testing/apitest/platform.go @@ -47,3 +47,14 @@ func AssertRequestsDone(t *testing.T) { fmt.Fprintln(os.Stderr, "Pending:", p.Request().Method, p.Request().URLStruct.Path) } } + +func MockPlatformAPI(t *testing.T) func() { + // Setup valid access token + token := RandomAccessToken(t) + t.Setenv("SUPABASE_ACCESS_TOKEN", string(token)) + teardown := func() { + AssertRequestsDone(t) + gock.OffAll() + } + return teardown +} diff --git a/internal/testing/fstest/stdout.go b/internal/testing/fstest/stdout.go new file mode 100644 index 0000000000..06c7bb3dc8 --- /dev/null +++ b/internal/testing/fstest/stdout.go @@ -0,0 +1,26 @@ +package fstest + +import ( + "io" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func MockStdout(t *testing.T, output string) func() { + r, w, err := os.Pipe() + require.NoError(t, err) + // Replace stdout + oldStdout := os.Stdout + teardown := func() { + os.Stdout = oldStdout + assert.NoError(t, w.Close()) + data, err := io.ReadAll(r) + assert.NoError(t, err) + assert.Equal(t, output, string(data)) + } + os.Stdout = w + return teardown +} From aae1f8cb18ed02138c1b2d3c126a5e7c0be6877d Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Mon, 9 Feb 2026 13:52:58 +0800 Subject: [PATCH 041/117] chore: add unit tests for network bans (#4825) * chore: add unit tests for network bans * fix: support output flag for network bans --- internal/bans/get/get.go | 19 +++++++- internal/bans/get/get_test.go | 86 +++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 internal/bans/get/get_test.go diff --git a/internal/bans/get/get.go b/internal/bans/get/get.go index 5b747325ca..c21558d709 100644 --- a/internal/bans/get/get.go +++ b/internal/bans/get/get.go @@ -3,8 +3,11 @@ package get import ( "context" "fmt" + "os" + "github.com/go-errors/errors" "github.com/spf13/afero" + "github.com/supabase/cli/internal/utils" "github.com/supabase/cli/internal/utils/flags" ) @@ -13,6 +16,18 @@ func Run(ctx context.Context, projectRef string, fsys afero.Fs) error { if err != nil { return err } - fmt.Printf("DB banned IPs: %+v\n", ips) - return nil + fmt.Fprintln(os.Stderr, "DB banned IPs:") + switch utils.OutputFormat.Value { + case utils.OutputPretty: + utils.OutputFormat.Value = utils.OutputJson + case utils.OutputToml: + return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, struct { + BannedIPs []string `toml:"banned_ips"` + }{ + BannedIPs: ips, + }) + case utils.OutputEnv: + return errors.New(utils.ErrEnvNotSupported) + } + return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, ips) } diff --git a/internal/bans/get/get_test.go b/internal/bans/get/get_test.go new file mode 100644 index 0000000000..21abb64e54 --- /dev/null +++ b/internal/bans/get/get_test.go @@ -0,0 +1,86 @@ +package get + +import ( + "context" + "net/http" + "testing" + + "github.com/go-errors/errors" + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/flags" + "github.com/supabase/cli/pkg/api" +) + +func TestGetBans(t *testing.T) { + t.Run("list network bans", func(t *testing.T) { + t.Cleanup(fstest.MockStdout(t, `[ + "192.168.0.1", + "192.168.0.2" +] +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("/v1/projects/" + flags.ProjectRef + "/network-bans/retrieve"). + Reply(http.StatusCreated). + JSON(api.NetworkBanResponse{ + BannedIpv4Addresses: []string{ + "192.168.0.1", + "192.168.0.2", + }, + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("outputs toml format", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputToml + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(fstest.MockStdout(t, `banned_ips = ["127.0.0.1"] +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("/v1/projects/" + flags.ProjectRef + "/network-bans/retrieve"). + Reply(http.StatusCreated). + JSON(api.NetworkBanResponse{ + BannedIpv4Addresses: []string{"127.0.0.1"}, + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("/v1/projects/" + flags.ProjectRef + "/network-bans/retrieve"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on env format", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("/v1/projects/" + flags.ProjectRef + "/network-bans/retrieve"). + Reply(http.StatusCreated). + JSON(api.NetworkBanResponse{ + BannedIpv4Addresses: []string{"127.0.0.1"}, + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorIs(t, err, utils.ErrEnvNotSupported) + }) +} From ac5ef1496a14f001c7e6b474fb0ec734805ee188 Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Mon, 9 Feb 2026 15:41:38 +0800 Subject: [PATCH 042/117] chore: add branches crud test (#4826) * chore: add branches crud test * chore: add list branch test * chore: unit test for all branch commands --- internal/branches/delete/delete.go | 8 +- internal/branches/delete/delete_test.go | 64 +++++++ internal/branches/disable/disable.go | 2 +- internal/branches/disable/disable_test.go | 52 ++++++ internal/branches/get/get_test.go | 204 ++++++++++++++++++++++ internal/branches/list/list.go | 13 +- internal/branches/list/list_test.go | 143 +++++++++++++++ internal/branches/pause/pause_test.go | 127 ++++++++++++++ internal/branches/unpause/unpause_test.go | 64 +++++++ internal/branches/update/update.go | 2 +- internal/branches/update/update_test.go | 109 ++++++++++++ internal/utils/connect.go | 4 +- 12 files changed, 778 insertions(+), 14 deletions(-) create mode 100644 internal/branches/delete/delete_test.go create mode 100644 internal/branches/disable/disable_test.go create mode 100644 internal/branches/get/get_test.go create mode 100644 internal/branches/list/list_test.go create mode 100644 internal/branches/pause/pause_test.go create mode 100644 internal/branches/unpause/unpause_test.go create mode 100644 internal/branches/update/update_test.go diff --git a/internal/branches/delete/delete.go b/internal/branches/delete/delete.go index 9b37302471..d73762cedf 100644 --- a/internal/branches/delete/delete.go +++ b/internal/branches/delete/delete.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "net/http" + "os" "github.com/go-errors/errors" "github.com/supabase/cli/internal/branches/pause" @@ -21,10 +22,9 @@ func Run(ctx context.Context, branchId string, force *bool) error { }) if err != nil { return errors.Errorf("failed to delete preview branch: %w", err) + } else if resp.StatusCode() != http.StatusOK { + return errors.Errorf("unexpected delete branch status %d: %s", resp.StatusCode(), string(resp.Body)) } - if resp.StatusCode() != http.StatusOK { - return errors.New("Unexpected error deleting preview branch: " + string(resp.Body)) - } - fmt.Println("Deleted preview branch:", projectRef) + fmt.Fprintln(os.Stderr, "Deleted preview branch:", projectRef) return nil } diff --git a/internal/branches/delete/delete_test.go b/internal/branches/delete/delete_test.go new file mode 100644 index 0000000000..cf3dade79c --- /dev/null +++ b/internal/branches/delete/delete_test.go @@ -0,0 +1,64 @@ +package delete + +import ( + "context" + "net/http" + "testing" + + "github.com/go-errors/errors" + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/flags" +) + +func TestDeleteBranch(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("deletes existing branch", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Delete("/v1/branches/" + flags.ProjectRef). + Reply(http.StatusOK) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("throws error on branch not found", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/branches/missing"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), "missing", nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Delete("/v1/branches/" + flags.ProjectRef). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Delete("/v1/branches/" + flags.ProjectRef). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorContains(t, err, "unexpected delete branch status 503:") + }) +} diff --git a/internal/branches/disable/disable.go b/internal/branches/disable/disable.go index d94c1e6c5a..9cbf38434e 100644 --- a/internal/branches/disable/disable.go +++ b/internal/branches/disable/disable.go @@ -17,7 +17,7 @@ func Run(ctx context.Context, fsys afero.Fs) error { return errors.Errorf("failed to disable preview branching: %w", err) } if resp.StatusCode() != http.StatusOK { - return errors.New("Unexpected error disabling preview branching: " + string(resp.Body)) + return errors.Errorf("unexpected disable branching status %d: %s", resp.StatusCode(), string(resp.Body)) } fmt.Println("Disabled preview branching for project:", flags.ProjectRef) return nil diff --git a/internal/branches/disable/disable_test.go b/internal/branches/disable/disable_test.go new file mode 100644 index 0000000000..2bc91cae0f --- /dev/null +++ b/internal/branches/disable/disable_test.go @@ -0,0 +1,52 @@ +package disable + +import ( + "context" + "net/http" + "testing" + + "github.com/go-errors/errors" + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/flags" +) + +func TestDisableBranching(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("disables branching", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Delete("/v1/projects/" + flags.ProjectRef + "/branches"). + Reply(http.StatusOK) + // Run test + err := Run(context.Background(), nil) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Delete("/v1/projects/" + flags.ProjectRef + "/branches"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Delete("/v1/projects/" + flags.ProjectRef + "/branches"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), nil) + assert.ErrorContains(t, err, "unexpected disable branching status 503:") + }) +} diff --git a/internal/branches/get/get_test.go b/internal/branches/get/get_test.go new file mode 100644 index 0000000000..7afd11cce7 --- /dev/null +++ b/internal/branches/get/get_test.go @@ -0,0 +1,204 @@ +package get + +import ( + "context" + "fmt" + "net/http" + "testing" + + "github.com/go-errors/errors" + "github.com/h2non/gock" + "github.com/oapi-codegen/nullable" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "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" +) + +func TestGetBranch(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("fetches branch details", func(t *testing.T) { + t.Cleanup(fstest.MockStdout(t, ` + + HOST | PORT | USER | PASSWORD | JWT SECRET | POSTGRES VERSION | STATUS + -----------|------|--------|----------|------------|------------------------------|---------------- + 127.0.0.1 | 5432 | ****** | ****** | ****** | supabase-postgres-17.4.1.074 | ACTIVE_HEALTHY + +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/branches/" + flags.ProjectRef). + Reply(http.StatusOK). + JSON(api.BranchDetailResponse{ + DbHost: "127.0.0.1", + DbPort: 5432, + PostgresVersion: "supabase-postgres-17.4.1.074", + Status: api.BranchDetailResponseStatusACTIVEHEALTHY, + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/branches/" + flags.ProjectRef). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/branches/" + flags.ProjectRef). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorContains(t, err, "unexpected get branch status 503:") + }) +} + +func TestTomlOutput(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + // Setup output format + utils.OutputFormat.Value = utils.OutputToml + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + + t.Run("encodes toml format", func(t *testing.T) { + t.Cleanup(fstest.MockStdout(t, fmt.Sprintf(`POSTGRES_URL = "postgresql://postgres:postgres@127.0.0.1:6543/postgres?connect_timeout=10" +POSTGRES_URL_NON_POOLING = "postgresql://postgres:postgres@127.0.0.1:5432/postgres?connect_timeout=10" +SUPABASE_ANON_KEY = "anon-key" +SUPABASE_JWT_SECRET = "secret-key" +SUPABASE_SERVICE_ROLE_KEY = "service-role-key" +SUPABASE_URL = "https://%s." +`, flags.ProjectRef))) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/branches/" + flags.ProjectRef). + Reply(http.StatusOK). + JSON(api.BranchDetailResponse{ + DbHost: "127.0.0.1", + DbPort: 5432, + DbUser: cast.Ptr("postgres"), + DbPass: cast.Ptr("postgres"), + JwtSecret: cast.Ptr("secret-key"), + Ref: flags.ProjectRef, + }) + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/api-keys"). + Reply(http.StatusOK). + JSON([]api.ApiKeyResponse{{ + Name: "anon", + ApiKey: nullable.NewNullableWithValue("anon-key"), + }, { + Name: "service_role", + ApiKey: nullable.NewNullableWithValue("service-role-key"), + }}) + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/config/database/pooler"). + Reply(http.StatusOK). + JSON([]api.SupavisorConfigResponse{{ + ConnectionString: "postgres://postgres:postgres@127.0.0.1:6543/postgres", + DatabaseType: api.SupavisorConfigResponseDatabaseTypePRIMARY, + PoolMode: api.SupavisorConfigResponsePoolModeTransaction, + }}) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/branches/" + flags.ProjectRef). + Reply(http.StatusOK). + JSON(api.BranchDetailResponse{ + Ref: flags.ProjectRef, + }) + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/api-keys"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on database not found", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/branches/" + flags.ProjectRef). + Reply(http.StatusOK). + JSON(api.BranchDetailResponse{ + Ref: flags.ProjectRef, + }) + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/api-keys"). + Reply(http.StatusOK). + JSON([]api.ApiKeyResponse{}) + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/config/database/pooler"). + Reply(http.StatusOK). + JSON([]api.SupavisorConfigResponse{}) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorIs(t, err, utils.ErrPrimaryNotFound) + }) +} + +func TestBranchDetail(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("get branch by name", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/branches/main"). + Reply(http.StatusOK). + JSON(api.BranchResponse{ProjectRef: flags.ProjectRef}) + gock.New(utils.DefaultApiHost). + Get("/v1/branches/" + flags.ProjectRef). + Reply(http.StatusOK). + JSON(api.BranchDetailResponse{}) + // Run test + _, err := getBranchDetail(context.Background(), "main") + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/branches/main"). + ReplyError(errNetwork) + // Run test + _, err := getBranchDetail(context.Background(), "main") + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on branch not found", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/branches/missing"). + Reply(http.StatusNotFound) + // Run test + _, err := getBranchDetail(context.Background(), "missing") + assert.ErrorContains(t, err, "unexpected find branch status 404:") + }) +} diff --git a/internal/branches/list/list.go b/internal/branches/list/list.go index 12dad2c0ba..1f9b545d23 100644 --- a/internal/branches/list/list.go +++ b/internal/branches/list/list.go @@ -37,16 +37,16 @@ func Run(ctx context.Context, fsys afero.Fs) error { } func ToMarkdown(branches []api.BranchResponse) string { - table := `|ID|NAME|DEFAULT|GIT BRANCH|WITH DATA|STATUS|CREATED AT (UTC)|UPDATED AT (UTC)| + var table strings.Builder + table.WriteString(`|ID|NAME|DEFAULT|GIT BRANCH|WITH DATA|STATUS|CREATED AT (UTC)|UPDATED AT (UTC)| |-|-|-|-|-|-|-|-| -` +`) for _, branch := range branches { gitBranch := " " if branch.GitBranch != nil { gitBranch = *branch.GitBranch } - table += fmt.Sprintf( - "|`%s`|`%s`|`%t`|`%s`|`%t`|`%s`|`%s`|`%s`|\n", + fmt.Fprintf(&table, "|`%s`|`%s`|`%t`|`%s`|`%t`|`%s`|`%s`|`%s`|\n", branch.ProjectRef, strings.ReplaceAll(branch.Name, "|", "\\|"), branch.IsDefault, @@ -54,10 +54,9 @@ func ToMarkdown(branches []api.BranchResponse) string { branch.WithData, branch.Status, utils.FormatTime(branch.CreatedAt), - utils.FormatTime(branch.UpdatedAt), - ) + utils.FormatTime(branch.UpdatedAt)) } - return table + return table.String() } type BranchFilter func(api.BranchResponse) bool diff --git a/internal/branches/list/list_test.go b/internal/branches/list/list_test.go new file mode 100644 index 0000000000..e7a111fa90 --- /dev/null +++ b/internal/branches/list/list_test.go @@ -0,0 +1,143 @@ +package list + +import ( + "context" + "net/http" + "testing" + "time" + + "github.com/go-errors/errors" + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "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" +) + +func TestListBranches(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("lists all branches", func(t *testing.T) { + t.Cleanup(fstest.MockStdout(t, ` + + ID | NAME | DEFAULT | GIT BRANCH | WITH DATA | STATUS | CREATED AT (UTC) | UPDATED AT (UTC) + ---------------------|---------|---------|------------|-----------|------------------|---------------------|--------------------- + staging-project-ref | Staging | false | develop | true | CREATING_PROJECT | 2026-01-02 03:04:05 | 2026-01-03 03:04:05 + +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/branches"). + Reply(http.StatusOK). + JSON([]api.BranchResponse{{ + GitBranch: cast.Ptr("develop"), + ProjectRef: "staging-project-ref", + Name: "Staging", + Persistent: true, + WithData: true, + Status: api.BranchResponseStatusCREATINGPROJECT, + CreatedAt: time.Date(2026, 01, 02, 03, 04, 05, 0, time.UTC), + UpdatedAt: time.Date(2026, 01, 03, 03, 04, 05, 0, time.UTC), + }}) + // Run test + err := Run(context.Background(), nil) + assert.NoError(t, err) + }) + + t.Run("encodes toml format", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputToml + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(fstest.MockStdout(t, `[[branches]] + CreatedAt = 0001-01-01T00:00:00Z + Id = "00000000-0000-0000-0000-000000000000" + IsDefault = true + Name = "Production" + ParentProjectRef = "production-project-ref" + Persistent = false + ProjectRef = "production-project-ref" + Status = "FUNCTIONS_DEPLOYED" + UpdatedAt = 0001-01-01T00:00:00Z + WithData = false +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/branches"). + Reply(http.StatusOK). + JSON([]api.BranchResponse{{ + Name: "Production", + IsDefault: true, + ParentProjectRef: "production-project-ref", + ProjectRef: "production-project-ref", + Status: api.BranchResponseStatusFUNCTIONSDEPLOYED, + }}) + // Run test + err := Run(context.Background(), nil) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/branches"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on env format", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/branches"). + Reply(http.StatusOK). + JSON([]api.BranchResponse{}) + // Run test + err := Run(context.Background(), nil) + assert.ErrorIs(t, err, utils.ErrEnvNotSupported) + }) +} + +func TestFilterBranch(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("filter branch by name", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/branches"). + Reply(http.StatusOK). + JSON([]api.BranchResponse{{ + Name: "Production", + IsDefault: true, + }, { + Name: "Staging", + Persistent: true, + }}) + // Run test + result, err := ListBranch(context.Background(), flags.ProjectRef, FilterByName("Production")) + assert.NoError(t, err) + assert.Len(t, result, 1) + assert.True(t, result[0].IsDefault) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/branches"). + Reply(http.StatusServiceUnavailable) + // Run test + _, err := ListBranch(context.Background(), flags.ProjectRef, FilterByName("Production")) + assert.ErrorContains(t, err, "unexpected list branch status 503:") + }) +} diff --git a/internal/branches/pause/pause_test.go b/internal/branches/pause/pause_test.go new file mode 100644 index 0000000000..20c442be9f --- /dev/null +++ b/internal/branches/pause/pause_test.go @@ -0,0 +1,127 @@ +package pause + +import ( + "context" + "errors" + "net/http" + "testing" + + "github.com/google/uuid" + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "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" +) + +func TestPauseBranch(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("pauses a branch", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("/v1/projects/" + flags.ProjectRef + "/pause"). + Reply(http.StatusOK) + // Run test + err := Run(context.Background(), flags.ProjectRef) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("/v1/projects/" + flags.ProjectRef + "/pause"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("/v1/projects/" + flags.ProjectRef + "/pause"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef) + assert.ErrorContains(t, err, "unexpected pause branch status 503:") + }) +} + +func TestBranchProjectRef(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("get by name", func(t *testing.T) { + branchRef := apitest.RandomProjectRef() + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/branches/develop"). + Reply(http.StatusOK). + JSON(api.BranchResponse{ProjectRef: branchRef}) + // run test + ref, err := GetBranchProjectRef(context.Background(), "develop") + assert.NoError(t, err) + assert.Equal(t, branchRef, ref) + }) + + t.Run("throws error on missing branch", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/branches/missing"). + Reply(http.StatusNotFound) + // Run test + _, err := GetBranchProjectRef(context.Background(), "missing") + assert.ErrorContains(t, err, "unexpected find branch status 404:") + }) + + t.Run("get by id", func(t *testing.T) { + brancRef := apitest.RandomProjectRef() + branchId, err := uuid.NewUUID() + require.NoError(t, err) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/branches/" + branchId.String()). + Reply(http.StatusOK). + JSON(api.BranchDetailResponse{Ref: brancRef}) + // Run test + ref, err := GetBranchProjectRef(context.Background(), branchId.String()) + assert.NoError(t, err) + assert.Equal(t, brancRef, ref) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + branchId, err := uuid.NewUUID() + require.NoError(t, err) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/branches/" + branchId.String()). + ReplyError(errNetwork) + // Run test + _, err = GetBranchProjectRef(context.Background(), branchId.String()) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + branchId, err := uuid.NewUUID() + require.NoError(t, err) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/branches/" + branchId.String()). + Reply(http.StatusServiceUnavailable) + // Run test + _, err = GetBranchProjectRef(context.Background(), branchId.String()) + assert.ErrorContains(t, err, "unexpected get branch status 503:") + }) +} diff --git a/internal/branches/unpause/unpause_test.go b/internal/branches/unpause/unpause_test.go new file mode 100644 index 0000000000..35851153e2 --- /dev/null +++ b/internal/branches/unpause/unpause_test.go @@ -0,0 +1,64 @@ +package unpause + +import ( + "context" + "net/http" + "testing" + + "github.com/go-errors/errors" + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/flags" +) + +func TestUnpauseBranch(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("unpause a branch", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("/v1/projects/" + flags.ProjectRef + "/restore"). + Reply(http.StatusOK) + // Run test + err := Run(context.Background(), flags.ProjectRef) + assert.NoError(t, err) + }) + + t.Run("throws error on missing branch", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/branches/missing"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), "missing") + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("/v1/projects/" + flags.ProjectRef + "/restore"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("/v1/projects/" + flags.ProjectRef + "/restore"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef) + assert.ErrorContains(t, err, "unexpected unpause branch status 503:") + }) +} diff --git a/internal/branches/update/update.go b/internal/branches/update/update.go index 20ec6f82d0..a467ae1d2a 100644 --- a/internal/branches/update/update.go +++ b/internal/branches/update/update.go @@ -24,7 +24,7 @@ func Run(ctx context.Context, branchId string, body api.UpdateBranchBody, fsys a } else if resp.JSON200 == nil { return errors.Errorf("unexpected update branch status %d: %s", resp.StatusCode(), string(resp.Body)) } - fmt.Println("Updated preview branch:") + fmt.Fprintln(os.Stderr, "Updated preview branch:") if utils.OutputFormat.Value == utils.OutputPretty { table := list.ToMarkdown([]api.BranchResponse{*resp.JSON200}) return utils.RenderTable(table) diff --git a/internal/branches/update/update_test.go b/internal/branches/update/update_test.go new file mode 100644 index 0000000000..070d82c9ff --- /dev/null +++ b/internal/branches/update/update_test.go @@ -0,0 +1,109 @@ +package update + +import ( + "context" + "errors" + "net/http" + "testing" + + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/flags" + "github.com/supabase/cli/pkg/api" +) + +func TestUpdateBranch(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("update branch attributes", func(t *testing.T) { + t.Cleanup(fstest.MockStdout(t, ` + + ID | NAME | DEFAULT | GIT BRANCH | WITH DATA | STATUS | CREATED AT (UTC) | UPDATED AT (UTC) + --------------------|------|---------|------------|-----------|------------------|---------------------|--------------------- + branch-project-ref | Dev | false | | false | CREATING_PROJECT | 0001-01-01 00:00:00 | 0001-01-01 00:00:00 + +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Patch("/v1/branches/" + flags.ProjectRef). + Reply(http.StatusOK). + JSON(api.BranchResponse{ + Name: "Dev", + ProjectRef: "branch-project-ref", + Status: api.BranchResponseStatusCREATINGPROJECT, + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, api.UpdateBranchBody{}, nil) + assert.NoError(t, err) + }) + + t.Run("encodes json format", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputJson + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(fstest.MockStdout(t, `{ + "created_at": "0001-01-01T00:00:00Z", + "id": "00000000-0000-0000-0000-000000000000", + "is_default": false, + "name": "Dev", + "parent_project_ref": "", + "persistent": false, + "project_ref": "branch-project-ref", + "status": "CREATING_PROJECT", + "updated_at": "0001-01-01T00:00:00Z", + "with_data": false +} +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Patch("/v1/branches/" + flags.ProjectRef). + Reply(http.StatusOK). + JSON(api.BranchResponse{ + Name: "Dev", + ProjectRef: "branch-project-ref", + Status: api.BranchResponseStatusCREATINGPROJECT, + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, api.UpdateBranchBody{}, nil) + assert.NoError(t, err) + }) + + t.Run("throws error on missing branch", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Patch("/v1/branches/" + flags.ProjectRef). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, api.UpdateBranchBody{}, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Patch("/v1/branches/" + flags.ProjectRef). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, api.UpdateBranchBody{}, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Patch("/v1/branches/" + flags.ProjectRef). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef, api.UpdateBranchBody{}, nil) + assert.ErrorContains(t, err, "unexpected update branch status 503:") + }) +} diff --git a/internal/utils/connect.go b/internal/utils/connect.go index 3b52d29da5..eca6b410aa 100644 --- a/internal/utils/connect.go +++ b/internal/utils/connect.go @@ -44,6 +44,8 @@ func ToPostgresURL(config pgconn.Config) string { ) } +var ErrPrimaryNotFound = errors.New("primary database not found") + func GetPoolerConfigPrimary(ctx context.Context, ref string) (api.SupavisorConfigResponse, error) { var result api.SupavisorConfigResponse resp, err := GetSupabase().V1GetPoolerConfigWithResponse(ctx, ref) @@ -57,7 +59,7 @@ func GetPoolerConfigPrimary(ctx context.Context, ref string) (api.SupavisorConfi return config, nil } } - return result, errors.Errorf("primary database not found: %s", ref) + return result, errors.New(ErrPrimaryNotFound) } func GetPoolerConfig(projectRef string) *pgconn.Config { From c5476b82d617c7c061fc5e3a539a26e157385f49 Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Mon, 9 Feb 2026 16:09:33 +0800 Subject: [PATCH 043/117] chore: unit test for ssl enforcement commands (#4827) * chore: unit test for ssl enforcement commands * chore: tidy up loose ends --- internal/backups/list/list_test.go | 22 +++++ internal/branches/update/update_test.go | 4 +- internal/ssl_enforcement/get/get.go | 35 ++++---- internal/ssl_enforcement/get/get_test.go | 82 +++++++++++++++++++ internal/ssl_enforcement/update/update.go | 32 +++----- .../ssl_enforcement/update/update_test.go | 82 +++++++++++++++++++ 6 files changed, 220 insertions(+), 37 deletions(-) create mode 100644 internal/ssl_enforcement/get/get_test.go create mode 100644 internal/ssl_enforcement/update/update_test.go diff --git a/internal/backups/list/list_test.go b/internal/backups/list/list_test.go index a236959aa0..70285ec6b1 100644 --- a/internal/backups/list/list_test.go +++ b/internal/backups/list/list_test.go @@ -72,6 +72,28 @@ func TestListBackup(t *testing.T) { assert.NoError(t, err) }) + t.Run("encodes json output", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputJson + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(fstest.MockStdout(t, `{ + "backups": null, + "physical_backup_data": {}, + "pitr_enabled": false, + "region": "ap-southeast-1", + "walg_enabled": false +} +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/database/backups"). + Reply(http.StatusOK). + JSON(api.V1BackupsResponse{Region: "ap-southeast-1"}) + // Run test + err := Run(context.Background()) + assert.NoError(t, err) + }) + t.Run("throws error on network error", func(t *testing.T) { errNetwork := errors.New("network error") t.Cleanup(apitest.MockPlatformAPI(t)) diff --git a/internal/branches/update/update_test.go b/internal/branches/update/update_test.go index 070d82c9ff..18382e94e0 100644 --- a/internal/branches/update/update_test.go +++ b/internal/branches/update/update_test.go @@ -77,10 +77,10 @@ func TestUpdateBranch(t *testing.T) { t.Cleanup(apitest.MockPlatformAPI(t)) // Setup mock api gock.New(utils.DefaultApiHost). - Patch("/v1/branches/" + flags.ProjectRef). + Get("/v1/projects/" + flags.ProjectRef + "/branches/missing"). ReplyError(errNetwork) // Run test - err := Run(context.Background(), flags.ProjectRef, api.UpdateBranchBody{}, nil) + err := Run(context.Background(), "missing", api.UpdateBranchBody{}, nil) assert.ErrorIs(t, err, errNetwork) }) diff --git a/internal/ssl_enforcement/get/get.go b/internal/ssl_enforcement/get/get.go index e6d58693ef..e16a6f29b4 100644 --- a/internal/ssl_enforcement/get/get.go +++ b/internal/ssl_enforcement/get/get.go @@ -3,29 +3,32 @@ package get import ( "context" "fmt" + "os" "github.com/go-errors/errors" "github.com/spf13/afero" "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/pkg/api" ) func Run(ctx context.Context, projectRef string, fsys afero.Fs) error { - // 1. Sanity checks. - // 2. get ssl enforcement config - { - resp, err := utils.GetSupabase().V1GetSslEnforcementConfigWithResponse(ctx, projectRef) - if err != nil { - return errors.Errorf("failed to retrieve SSL enforcement config: %w", err) - } - if resp.JSON200 == nil { - return errors.New("failed to retrieve SSL enforcement config; received: " + string(resp.Body)) - } + resp, err := utils.GetSupabase().V1GetSslEnforcementConfigWithResponse(ctx, projectRef) + if err != nil { + return errors.Errorf("failed to retrieve SSL enforcement config: %w", err) + } else if resp.JSON200 == nil { + return errors.Errorf("unexpected SSL enforcement status %d: %s", resp.StatusCode(), string(resp.Body)) + } + if utils.OutputFormat.Value != utils.OutputPretty { + return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, *resp.JSON200) + } + return PrintSSLStatus(*resp.JSON200) +} - if resp.JSON200.CurrentConfig.Database && resp.JSON200.AppliedSuccessfully { - fmt.Println("SSL is being enforced.") - } else { - fmt.Println("SSL is *NOT* being enforced.") - } - return nil +func PrintSSLStatus(ssl api.SslEnforcementResponse) error { + if ssl.CurrentConfig.Database && ssl.AppliedSuccessfully { + fmt.Println("SSL is being enforced.") + } else { + fmt.Println("SSL is *NOT* being enforced.") } + return nil } diff --git a/internal/ssl_enforcement/get/get_test.go b/internal/ssl_enforcement/get/get_test.go new file mode 100644 index 0000000000..7ec99b9d7a --- /dev/null +++ b/internal/ssl_enforcement/get/get_test.go @@ -0,0 +1,82 @@ +package get + +import ( + "context" + "errors" + "net/http" + "testing" + + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/flags" + "github.com/supabase/cli/pkg/api" +) + +func TestSSLEnforcement(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("get ssl enforcement", func(t *testing.T) { + t.Cleanup(fstest.MockStdout(t, "SSL is *NOT* being enforced.\n")) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/projects/" + flags.ProjectRef + "/ssl-enforcement"). + Reply(http.StatusOK). + JSON(api.SslEnforcementResponse{}) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("encodes env output", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(fstest.MockStdout(t, `APPLIEDSUCCESSFULLY="true" +CURRENTCONFIG_DATABASE="true" +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/projects/" + flags.ProjectRef + "/ssl-enforcement"). + Reply(http.StatusOK). + JSON(api.SslEnforcementResponse{ + AppliedSuccessfully: true, + CurrentConfig: struct { + Database bool `json:"database"` + }{ + Database: true, + }, + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/ssl-enforcement"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/ssl-enforcement"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorContains(t, err, "unexpected SSL enforcement status 503:") + }) +} diff --git a/internal/ssl_enforcement/update/update.go b/internal/ssl_enforcement/update/update.go index 8f1b5f56d9..7f0525136c 100644 --- a/internal/ssl_enforcement/update/update.go +++ b/internal/ssl_enforcement/update/update.go @@ -2,32 +2,26 @@ package update import ( "context" - "fmt" + "os" "github.com/go-errors/errors" "github.com/spf13/afero" + "github.com/supabase/cli/internal/ssl_enforcement/get" "github.com/supabase/cli/internal/utils" "github.com/supabase/cli/pkg/api" ) func Run(ctx context.Context, projectRef string, enforceDbSsl bool, fsys afero.Fs) error { - // 1. sanity checks - // 2. update restrictions - { - body := api.V1UpdateSslEnforcementConfigJSONRequestBody{} - body.RequestedConfig.Database = enforceDbSsl - resp, err := utils.GetSupabase().V1UpdateSslEnforcementConfigWithResponse(ctx, projectRef, body) - if err != nil { - return errors.Errorf("failed to update ssl enforcement: %w", err) - } - if resp.JSON200 == nil { - return errors.New("failed to update SSL enforcement confnig: " + string(resp.Body)) - } - if resp.JSON200.CurrentConfig.Database && resp.JSON200.AppliedSuccessfully { - fmt.Println("SSL is now being enforced.") - } else { - fmt.Println("SSL is *NOT* being enforced.") - } - return nil + body := api.V1UpdateSslEnforcementConfigJSONRequestBody{} + body.RequestedConfig.Database = enforceDbSsl + resp, err := utils.GetSupabase().V1UpdateSslEnforcementConfigWithResponse(ctx, projectRef, body) + if err != nil { + return errors.Errorf("failed to update ssl enforcement: %w", err) + } else if resp.JSON200 == nil { + return errors.Errorf("unexpected update SSL status %d: %s", resp.StatusCode(), string(resp.Body)) } + if utils.OutputFormat.Value != utils.OutputPretty { + return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, *resp.JSON200) + } + return get.PrintSSLStatus(*resp.JSON200) } diff --git a/internal/ssl_enforcement/update/update_test.go b/internal/ssl_enforcement/update/update_test.go new file mode 100644 index 0000000000..92a406a39c --- /dev/null +++ b/internal/ssl_enforcement/update/update_test.go @@ -0,0 +1,82 @@ +package update + +import ( + "context" + "errors" + "net/http" + "testing" + + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/flags" + "github.com/supabase/cli/pkg/api" +) + +func TestUpdateSSL(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("enable ssl enforcement", func(t *testing.T) { + t.Cleanup(fstest.MockStdout(t, "SSL is being enforced.\n")) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Put("v1/projects/" + flags.ProjectRef + "/ssl-enforcement"). + Reply(http.StatusOK). + JSON(api.SslEnforcementResponse{ + AppliedSuccessfully: true, + CurrentConfig: struct { + Database bool `json:"database"` + }{ + Database: true, + }, + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, true, nil) + assert.NoError(t, err) + }) + + t.Run("encodes toml format", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(fstest.MockStdout(t, `APPLIEDSUCCESSFULLY="false" +CURRENTCONFIG_DATABASE="false" +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Put("v1/projects/" + flags.ProjectRef + "/ssl-enforcement"). + Reply(http.StatusOK). + JSON(api.SslEnforcementResponse{}) + // Run test + err := Run(context.Background(), flags.ProjectRef, false, nil) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Put("/v1/projects/" + flags.ProjectRef + "/ssl-enforcement"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, false, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Put("/v1/projects/" + flags.ProjectRef + "/ssl-enforcement"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef, false, nil) + assert.ErrorContains(t, err, "unexpected update SSL status 503:") + }) +} From ce89d32ebcae04c87e9e606164af132d91c3f09d Mon Sep 17 00:00:00 2001 From: Inder Singh <85822513+singh-inder@users.noreply.github.com> Date: Mon, 9 Feb 2026 14:14:08 +0530 Subject: [PATCH 044/117] fix(studio): use postgres user for read write operations (#4828) --- internal/start/start.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/start/start.go b/internal/start/start.go index c35efa2e36..dd9ca740fe 100644 --- a/internal/start/start.go +++ b/internal/start/start.go @@ -1173,6 +1173,7 @@ EOF "SNIPPETS_MANAGEMENT_FOLDER=" + containerSnippetsPath, // Ref: https://github.com/vercel/next.js/issues/51684#issuecomment-1612834913 "HOSTNAME=0.0.0.0", + "POSTGRES_USER_READ_WRITE=postgres", }, Healthcheck: &container.HealthConfig{ Test: []string{"CMD-SHELL", `node --eval="fetch('http://127.0.0.1:3000/api/platform/profile').then((r) => {if (!r.ok) throw new Error(r.status)})"`}, From 46c97b43727b5071defff2b605483aefe0fb2fd4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Feb 2026 16:45:29 +0800 Subject: [PATCH 045/117] chore(deps): bump aws-actions/configure-aws-credentials from 5.1.1 to 6.0.0 in the actions-major group (#4807) chore(deps): bump aws-actions/configure-aws-credentials Bumps the actions-major group with 1 update: [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials). Updates `aws-actions/configure-aws-credentials` from 5.1.1 to 6.0.0 - [Release notes](https://github.com/aws-actions/configure-aws-credentials/releases) - [Changelog](https://github.com/aws-actions/configure-aws-credentials/blob/main/CHANGELOG.md) - [Commits](https://github.com/aws-actions/configure-aws-credentials/compare/v5.1.1...v6.0.0) --- updated-dependencies: - dependency-name: aws-actions/configure-aws-credentials dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/mirror-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mirror-image.yml b/.github/workflows/mirror-image.yml index abf168796b..0f8204f23d 100644 --- a/.github/workflows/mirror-image.yml +++ b/.github/workflows/mirror-image.yml @@ -30,7 +30,7 @@ jobs: TAG=${{ github.event.client_payload.image || inputs.image }} echo "image=${TAG##*/}" >> $GITHUB_OUTPUT - name: configure aws credentials - uses: aws-actions/configure-aws-credentials@v5.1.1 + uses: aws-actions/configure-aws-credentials@v6.0.0 with: role-to-assume: ${{ secrets.PROD_AWS_ROLE }} aws-region: us-east-1 From aa62c122d98bfa55ba69ebe3947ed18ac846c065 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Feb 2026 17:05:51 +0800 Subject: [PATCH 046/117] chore(deps): bump golang.org/x/oauth2 from 0.34.0 to 0.35.0 in the go-minor group across 1 directory (#4823) chore(deps): bump golang.org/x/oauth2 Bumps the go-minor group with 1 update in the / directory: [golang.org/x/oauth2](https://github.com/golang/oauth2). Updates `golang.org/x/oauth2` from 0.34.0 to 0.35.0 - [Commits](https://github.com/golang/oauth2/compare/v0.34.0...v0.35.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-version: 0.35.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-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 f8f44bdafa..16214fa778 100644 --- a/go.mod +++ b/go.mod @@ -56,7 +56,7 @@ require ( go.opentelemetry.io/otel v1.40.0 golang.org/x/mod v0.32.0 golang.org/x/net v0.49.0 - golang.org/x/oauth2 v0.34.0 + golang.org/x/oauth2 v0.35.0 golang.org/x/term v0.39.0 google.golang.org/grpc v1.78.0 gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index 51aa46c948..17787e927e 100644 --- a/go.sum +++ b/go.sum @@ -1284,8 +1284,8 @@ golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= -golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= -golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= +golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= 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 9b2f6f2845bc8cd94fac9d13fa7267729df70467 Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Mon, 9 Feb 2026 17:27:37 +0800 Subject: [PATCH 047/117] chore: unit tests for vanity subdomain (#4829) * chore: unit tests for vanity subdomain * chore: check flag error --- cmd/vanitySubdomains.go | 3 +- .../vanity_subdomains/activate/activate.go | 33 +++----- .../activate/activate_test.go | 76 +++++++++++++++++ internal/vanity_subdomains/check/check.go | 33 +++----- .../vanity_subdomains/check/check_test.go | 73 +++++++++++++++++ internal/vanity_subdomains/delete/delete.go | 21 ++--- .../vanity_subdomains/delete/delete_test.go | 54 ++++++++++++ internal/vanity_subdomains/get/get.go | 29 ++++--- internal/vanity_subdomains/get/get_test.go | 82 +++++++++++++++++++ 9 files changed, 334 insertions(+), 70 deletions(-) create mode 100644 internal/vanity_subdomains/activate/activate_test.go create mode 100644 internal/vanity_subdomains/check/check_test.go create mode 100644 internal/vanity_subdomains/delete/delete_test.go create mode 100644 internal/vanity_subdomains/get/get_test.go diff --git a/cmd/vanitySubdomains.go b/cmd/vanitySubdomains.go index dd3608c53e..44d87e8d7a 100644 --- a/cmd/vanitySubdomains.go +++ b/cmd/vanitySubdomains.go @@ -64,11 +64,12 @@ After the vanity subdomain is activated, your project's auth services will no lo func init() { vanityCmd.PersistentFlags().StringVar(&flags.ProjectRef, "project-ref", "", "Project ref of the Supabase project.") vanityActivateCmd.Flags().StringVar(&desiredSubdomain, "desired-subdomain", "", "The desired vanity subdomain to use for your Supabase project.") + cobra.CheckErr(vanityActivateCmd.MarkFlagRequired("desired-subdomain")) vanityCheckCmd.Flags().StringVar(&desiredSubdomain, "desired-subdomain", "", "The desired vanity subdomain to use for your Supabase project.") + cobra.CheckErr(vanityCheckCmd.MarkFlagRequired("desired-subdomain")) vanityCmd.AddCommand(vanityGetCmd) vanityCmd.AddCommand(vanityCheckCmd) vanityCmd.AddCommand(vanityActivateCmd) vanityCmd.AddCommand(vanityDeleteCmd) - rootCmd.AddCommand(vanityCmd) } diff --git a/internal/vanity_subdomains/activate/activate.go b/internal/vanity_subdomains/activate/activate.go index 133ec7edd3..87eb748ea9 100644 --- a/internal/vanity_subdomains/activate/activate.go +++ b/internal/vanity_subdomains/activate/activate.go @@ -3,7 +3,7 @@ package activate import ( "context" "fmt" - "strings" + "os" "github.com/go-errors/errors" "github.com/spf13/afero" @@ -12,26 +12,17 @@ import ( ) func Run(ctx context.Context, projectRef string, desiredSubdomain string, fsys afero.Fs) error { - // 1. Sanity checks. - subdomain := strings.TrimSpace(desiredSubdomain) - { - if len(subdomain) == 0 { - return errors.New("non-empty vanity subdomain expected") - } + resp, err := utils.GetSupabase().V1ActivateVanitySubdomainConfigWithResponse(ctx, projectRef, api.V1ActivateVanitySubdomainConfigJSONRequestBody{ + VanitySubdomain: desiredSubdomain, + }) + if err != nil { + return errors.Errorf("failed activate vanity subdomain: %w", err) + } else if resp.JSON201 == nil { + return errors.Errorf("unexpected activate vanity subdomain status %d: %s", resp.StatusCode(), string(resp.Body)) } - - // 2. create vanity subdomain - { - resp, err := utils.GetSupabase().V1ActivateVanitySubdomainConfigWithResponse(ctx, projectRef, api.V1ActivateVanitySubdomainConfigJSONRequestBody{ - VanitySubdomain: subdomain, - }) - if err != nil { - return errors.Errorf("failed activate vanity subdomain: %w", err) - } - if resp.JSON201 == nil { - return errors.New("failed to create vanity subdomain config: " + string(resp.Body)) - } - fmt.Printf("Activated vanity subdomain at %s\n", resp.JSON201.CustomDomain) - return nil + if utils.OutputFormat.Value != utils.OutputPretty { + return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, *resp.JSON201) } + fmt.Printf("Activated vanity subdomain at %s\n", resp.JSON201.CustomDomain) + return nil } diff --git a/internal/vanity_subdomains/activate/activate_test.go b/internal/vanity_subdomains/activate/activate_test.go new file mode 100644 index 0000000000..fb3ea7f84d --- /dev/null +++ b/internal/vanity_subdomains/activate/activate_test.go @@ -0,0 +1,76 @@ +package activate + +import ( + "context" + "net/http" + "testing" + + "github.com/go-errors/errors" + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/flags" + "github.com/supabase/cli/pkg/api" +) + +func TestActivateSubdomain(t *testing.T) { + t.Run("actives vanity subdomain", func(t *testing.T) { + t.Cleanup(fstest.MockStdout(t, "Activated vanity subdomain at example.com\n")) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("v1/projects/" + flags.ProjectRef + "/vanity-subdomain"). + Reply(http.StatusCreated). + JSON(api.ActivateVanitySubdomainResponse{ + CustomDomain: "example.com", + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, "example.com", nil) + assert.NoError(t, err) + }) + + t.Run("encodes toml output", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputToml + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(fstest.MockStdout(t, `CustomDomain = "example.com" +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("v1/projects/" + flags.ProjectRef + "/vanity-subdomain"). + Reply(http.StatusCreated). + JSON(api.ActivateVanitySubdomainResponse{ + CustomDomain: "example.com", + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, "example.com", nil) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("/v1/projects/" + flags.ProjectRef + "/vanity-subdomain"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, "example.com", nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("/v1/projects/" + flags.ProjectRef + "/vanity-subdomain"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef, "example.com", nil) + assert.ErrorContains(t, err, "unexpected activate vanity subdomain status 503:") + }) +} diff --git a/internal/vanity_subdomains/check/check.go b/internal/vanity_subdomains/check/check.go index 3901227071..a9ecb639cc 100644 --- a/internal/vanity_subdomains/check/check.go +++ b/internal/vanity_subdomains/check/check.go @@ -3,7 +3,7 @@ package check import ( "context" "fmt" - "strings" + "os" "github.com/go-errors/errors" "github.com/spf13/afero" @@ -12,26 +12,17 @@ import ( ) func Run(ctx context.Context, projectRef string, desiredSubdomain string, fsys afero.Fs) error { - // 1. Sanity checks. - subdomain := strings.TrimSpace(desiredSubdomain) - { - if len(subdomain) == 0 { - return errors.New("non-empty vanity subdomain expected") - } + resp, err := utils.GetSupabase().V1CheckVanitySubdomainAvailabilityWithResponse(ctx, projectRef, api.V1CheckVanitySubdomainAvailabilityJSONRequestBody{ + VanitySubdomain: desiredSubdomain, + }) + if err != nil { + return errors.Errorf("failed to check vanity subdomain: %w", err) + } else if resp.JSON201 == nil { + return errors.Errorf("unexpected check vanity subdomain status %d: %s", resp.StatusCode(), string(resp.Body)) } - - // 2. check if the subdomain is available - { - resp, err := utils.GetSupabase().V1CheckVanitySubdomainAvailabilityWithResponse(ctx, projectRef, api.V1CheckVanitySubdomainAvailabilityJSONRequestBody{ - VanitySubdomain: subdomain, - }) - if err != nil { - return errors.Errorf("failed to check vanity subdomain: %w", err) - } - if resp.JSON201 == nil { - return errors.New("failed to check subdomain availability: " + string(resp.Body)) - } - fmt.Printf("Subdomain %s available: %+v\n", subdomain, resp.JSON201.Available) - return nil + if utils.OutputFormat.Value != utils.OutputPretty { + return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, *resp.JSON201) } + fmt.Printf("Subdomain %s available: %+v\n", desiredSubdomain, resp.JSON201.Available) + return nil } diff --git a/internal/vanity_subdomains/check/check_test.go b/internal/vanity_subdomains/check/check_test.go new file mode 100644 index 0000000000..7702ab59c5 --- /dev/null +++ b/internal/vanity_subdomains/check/check_test.go @@ -0,0 +1,73 @@ +package check + +import ( + "context" + "net/http" + "testing" + + "github.com/go-errors/errors" + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/flags" + "github.com/supabase/cli/pkg/api" +) + +func TestCheckSubdomain(t *testing.T) { + t.Run("checks subdomain availability", func(t *testing.T) { + t.Cleanup(fstest.MockStdout(t, "Subdomain example.com available: true\n")) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("v1/projects/" + flags.ProjectRef + "/vanity-subdomain/check-availability"). + Reply(http.StatusCreated). + JSON(api.SubdomainAvailabilityResponse{ + Available: true, + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, "example.com", nil) + assert.NoError(t, err) + }) + + t.Run("encodes toml output", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputToml + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(fstest.MockStdout(t, "Available = false\n")) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("v1/projects/" + flags.ProjectRef + "/vanity-subdomain/check-availability"). + Reply(http.StatusCreated). + JSON(api.SubdomainAvailabilityResponse{}) + // Run test + err := Run(context.Background(), flags.ProjectRef, "example.com", nil) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("/v1/projects/" + flags.ProjectRef + "/vanity-subdomain/check-availability"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, "example.com", nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("/v1/projects/" + flags.ProjectRef + "/vanity-subdomain/check-availability"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef, "example.com", nil) + assert.ErrorContains(t, err, "unexpected check vanity subdomain status 503:") + }) +} diff --git a/internal/vanity_subdomains/delete/delete.go b/internal/vanity_subdomains/delete/delete.go index 3ee24d473d..969b63de7a 100644 --- a/internal/vanity_subdomains/delete/delete.go +++ b/internal/vanity_subdomains/delete/delete.go @@ -3,6 +3,8 @@ package delete import ( "context" "fmt" + "net/http" + "os" "github.com/go-errors/errors" "github.com/spf13/afero" @@ -10,17 +12,12 @@ import ( ) func Run(ctx context.Context, projectRef string, fsys afero.Fs) error { - // 1. Sanity checks. - // 2. delete config - { - resp, err := utils.GetSupabase().V1DeactivateVanitySubdomainConfigWithResponse(ctx, projectRef) - if err != nil { - return errors.Errorf("failed to delete vanity subdomain: %w", err) - } - if resp.StatusCode() != 200 { - return errors.New("failed to delete vanity subdomain config; received: " + string(resp.Body)) - } - fmt.Println("Deleted vanity subdomain successfully.") - return nil + resp, err := utils.GetSupabase().V1DeactivateVanitySubdomainConfigWithResponse(ctx, projectRef) + if err != nil { + return errors.Errorf("failed to delete vanity subdomain: %w", err) + } else if resp.StatusCode() != http.StatusOK { + return errors.Errorf("unexpected delete vanity subdomain status %d: %s", resp.StatusCode(), string(resp.Body)) } + fmt.Fprintln(os.Stderr, "Deleted vanity subdomain successfully.") + return nil } diff --git a/internal/vanity_subdomains/delete/delete_test.go b/internal/vanity_subdomains/delete/delete_test.go new file mode 100644 index 0000000000..1a09295f60 --- /dev/null +++ b/internal/vanity_subdomains/delete/delete_test.go @@ -0,0 +1,54 @@ +package delete + +import ( + "context" + "errors" + "net/http" + "testing" + + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/flags" +) + +func TestDeleteSubdomain(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("deletes vanity subdomain", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Delete("v1/projects/" + flags.ProjectRef + "/vanity-subdomain"). + Reply(http.StatusOK) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Delete("/v1/projects/" + flags.ProjectRef + "/vanity-subdomain"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Delete("/v1/projects/" + flags.ProjectRef + "/vanity-subdomain"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorContains(t, err, "unexpected delete vanity subdomain status 503:") + }) +} diff --git a/internal/vanity_subdomains/get/get.go b/internal/vanity_subdomains/get/get.go index b466f18958..303e9edec1 100644 --- a/internal/vanity_subdomains/get/get.go +++ b/internal/vanity_subdomains/get/get.go @@ -3,6 +3,7 @@ package get import ( "context" "fmt" + "os" "github.com/go-errors/errors" "github.com/spf13/afero" @@ -10,20 +11,18 @@ import ( ) func Run(ctx context.Context, projectRef string, fsys afero.Fs) error { - // 1. Sanity checks. - // 2. get vanity subdomain config - { - response, err := utils.GetSupabase().V1GetVanitySubdomainConfigWithResponse(ctx, projectRef) - if err != nil { - return errors.Errorf("failed to get vanity subdomain: %w", err) - } - if response.JSON200 == nil { - return errors.Errorf("failed to obtain vanity subdomain config: %+v", string(response.Body)) - } - fmt.Printf("Status: %s\n", response.JSON200.Status) - if response.JSON200.CustomDomain != nil { - fmt.Printf("Vanity subdomain: %s\n", *response.JSON200.CustomDomain) - } - return nil + resp, err := utils.GetSupabase().V1GetVanitySubdomainConfigWithResponse(ctx, projectRef) + if err != nil { + return errors.Errorf("failed to get vanity subdomain: %w", err) + } else if resp.JSON200 == nil { + return errors.Errorf("unexpected vanity subdomain status %d: %s", resp.StatusCode(), string(resp.Body)) } + if utils.OutputFormat.Value != utils.OutputPretty { + return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, *resp.JSON200) + } + fmt.Printf("Status: %s\n", resp.JSON200.Status) + if resp.JSON200.CustomDomain != nil { + fmt.Printf("Vanity subdomain: %s\n", *resp.JSON200.CustomDomain) + } + return nil } diff --git a/internal/vanity_subdomains/get/get_test.go b/internal/vanity_subdomains/get/get_test.go new file mode 100644 index 0000000000..8ec0428f3b --- /dev/null +++ b/internal/vanity_subdomains/get/get_test.go @@ -0,0 +1,82 @@ +package get + +import ( + "context" + "net/http" + "testing" + + "github.com/go-errors/errors" + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "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" +) + +func TestGetSubdomain(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("get vanity subdomains", func(t *testing.T) { + t.Cleanup(fstest.MockStdout(t, `Status: custom-domain-used +Vanity subdomain: example.com +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/projects/" + flags.ProjectRef + "/vanity-subdomain"). + Reply(http.StatusOK). + JSON(api.VanitySubdomainConfigResponse{ + CustomDomain: cast.Ptr("example.com"), + Status: api.CustomDomainUsed, + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("encodes toml output", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputToml + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(fstest.MockStdout(t, `Status = "not-used" +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/projects/" + flags.ProjectRef + "/vanity-subdomain"). + Reply(http.StatusOK). + JSON(api.VanitySubdomainConfigResponse{ + Status: api.NotUsed, + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/vanity-subdomain"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/vanity-subdomain"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorContains(t, err, "unexpected vanity subdomain status 503:") + }) +} From cee2c5b2d12fe4ea5c216342aa5d5e901469e15c Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Mon, 9 Feb 2026 18:23:13 +0800 Subject: [PATCH 048/117] chore: unit tests for pg config (#4830) --- internal/postgresConfig/delete/delete.go | 17 ++-- internal/postgresConfig/delete/delete_test.go | 94 ++++++++++++++++++ internal/postgresConfig/get/get.go | 27 ++---- internal/postgresConfig/get/get_test.go | 85 +++++++++++++++++ internal/postgresConfig/update/update.go | 13 +-- internal/postgresConfig/update/update_test.go | 95 +++++++++++++++++++ 6 files changed, 298 insertions(+), 33 deletions(-) create mode 100644 internal/postgresConfig/delete/delete_test.go create mode 100644 internal/postgresConfig/get/get_test.go create mode 100644 internal/postgresConfig/update/update_test.go diff --git a/internal/postgresConfig/delete/delete.go b/internal/postgresConfig/delete/delete.go index 20b7b978f5..86ecee6304 100644 --- a/internal/postgresConfig/delete/delete.go +++ b/internal/postgresConfig/delete/delete.go @@ -35,14 +35,15 @@ func Run(ctx context.Context, projectRef string, configKeys []string, noRestart resp, err := utils.GetSupabase().V1UpdatePostgresConfigWithBodyWithResponse(ctx, projectRef, "application/json", bytes.NewReader(bts)) if err != nil { - return errors.Errorf("failed to update config overrides: %w", err) - } - if resp.JSON200 == nil { - if resp.StatusCode() == 400 { - return errors.Errorf("failed to update config overrides: %s (%s). This usually indicates that an unsupported or invalid config override was attempted. Please refer to https://supabase.com/docs/guides/platform/custom-postgres-config", resp.Status(), string(resp.Body)) - } - return errors.Errorf("failed to update config overrides: %s (%s)", resp.Status(), string(resp.Body)) + return errors.Errorf("failed to delete config overrides: %w", err) + } else if resp.JSON200 == nil { + return errors.Errorf("unexpected delete config overrides status %d: %s", resp.StatusCode(), string(resp.Body)) } - return get.Run(ctx, projectRef, fsys) + var config map[string]any + err = json.Unmarshal(resp.Body, &config) + if err != nil { + return errors.Errorf("failed to unmarshal delete response: %w", err) + } + return get.PrintOutPostgresConfigOverrides(config) } diff --git a/internal/postgresConfig/delete/delete_test.go b/internal/postgresConfig/delete/delete_test.go new file mode 100644 index 0000000000..e1bfa880bb --- /dev/null +++ b/internal/postgresConfig/delete/delete_test.go @@ -0,0 +1,94 @@ +package delete + +import ( + "context" + "net/http" + "testing" + + "github.com/go-errors/errors" + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "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" +) + +func TestDeleteConfig(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("deletes postgres config", func(t *testing.T) { + t.Cleanup(fstest.MockStdout(t, ` + + Parameter | Value + -----------|------- + +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/projects/" + flags.ProjectRef + "/config/database/postgres"). + Reply(http.StatusOK). + JSON(api.PostgresConfigResponse{ + MaxConnections: cast.Ptr(100), + }) + gock.New(utils.DefaultApiHost). + Put("v1/projects/" + flags.ProjectRef + "/config/database/postgres"). + Reply(http.StatusOK). + JSON(api.PostgresConfigResponse{}) + // Run test + err := Run(context.Background(), flags.ProjectRef, []string{"max_connections"}, true, nil) + assert.NoError(t, err) + }) + + t.Run("throws error on missing project", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/config/database/postgres"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, []string{}, false, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/projects/" + flags.ProjectRef + "/config/database/postgres"). + Reply(http.StatusOK). + JSON(api.PostgresConfigResponse{ + MaxConnections: cast.Ptr(100), + }) + gock.New(utils.DefaultApiHost). + Put("/v1/projects/" + flags.ProjectRef + "/config/database/postgres"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, []string{}, false, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/projects/" + flags.ProjectRef + "/config/database/postgres"). + Reply(http.StatusOK). + JSON(api.PostgresConfigResponse{ + MaxConnections: cast.Ptr(100), + }) + gock.New(utils.DefaultApiHost). + Put("/v1/projects/" + flags.ProjectRef + "/config/database/postgres"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef, []string{}, false, nil) + assert.ErrorContains(t, err, "unexpected delete config overrides status 503:") + }) +} diff --git a/internal/postgresConfig/get/get.go b/internal/postgresConfig/get/get.go index 01a749ce45..e2142cf183 100644 --- a/internal/postgresConfig/get/get.go +++ b/internal/postgresConfig/get/get.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "io" "os" "strings" @@ -14,23 +13,18 @@ import ( ) func Run(ctx context.Context, projectRef string, fsys afero.Fs) error { - // 1. get current config config, err := GetCurrentPostgresConfig(ctx, projectRef) if err != nil { return err } - err = PrintOutPostgresConfigOverrides(config) - if err != nil { - return err - } - return nil + return PrintOutPostgresConfigOverrides(config) } func PrintOutPostgresConfigOverrides(config map[string]any) error { if utils.OutputFormat.Value != utils.OutputPretty { return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, config) } - fmt.Println("- Custom Postgres Config -") + fmt.Fprintln(os.Stderr, "- Custom Postgres Config -") markdownTable := []string{ "|Parameter|Value|\n|-|-|\n", } @@ -43,26 +37,21 @@ func PrintOutPostgresConfigOverrides(config map[string]any) error { if err := utils.RenderTable(strings.Join(markdownTable, "")); err != nil { return err } - fmt.Println("- End of Custom Postgres Config -") + fmt.Fprintln(os.Stderr, "- End of Custom Postgres Config -") return nil } func GetCurrentPostgresConfig(ctx context.Context, projectRef string) (map[string]any, error) { - resp, err := utils.GetSupabase().V1GetPostgresConfig(ctx, projectRef) + resp, err := utils.GetSupabase().V1GetPostgresConfigWithResponse(ctx, projectRef) if err != nil { return nil, errors.Errorf("failed to retrieve Postgres config overrides: %w", err) - } - if resp.StatusCode != 200 { - return nil, errors.Errorf("error in retrieving Postgres config overrides: %s", resp.Status) - } - contents, err := io.ReadAll(resp.Body) - if err != nil { - return nil, errors.Errorf("failed to read response body: %w", err) + } else if resp.JSON200 == nil { + return nil, errors.Errorf("unexpected config overrides status %d: %s", resp.StatusCode(), string(resp.Body)) } var config map[string]any - err = json.Unmarshal(contents, &config) + err = json.Unmarshal(resp.Body, &config) if err != nil { - return nil, errors.Errorf("failed to unmarshal response body: %w. Contents were %s", err, contents) + return nil, errors.Errorf("failed to unmarshal response body: %w", err) } return config, nil } diff --git a/internal/postgresConfig/get/get_test.go b/internal/postgresConfig/get/get_test.go new file mode 100644 index 0000000000..149c70758d --- /dev/null +++ b/internal/postgresConfig/get/get_test.go @@ -0,0 +1,85 @@ +package get + +import ( + "context" + "errors" + "net/http" + "testing" + + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "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" +) + +func TestPostgresConfig(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("get postgres config", func(t *testing.T) { + t.Cleanup(fstest.MockStdout(t, ` + + Parameter | Value + -----------------|------- + max_connections | 100 + +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/projects/" + flags.ProjectRef + "/config/database/postgres"). + Reply(http.StatusOK). + JSON(api.PostgresConfigResponse{ + MaxConnections: cast.Ptr(100), + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("encodes toml output", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputToml + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(fstest.MockStdout(t, `max_connections = 100.0 +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/projects/" + flags.ProjectRef + "/config/database/postgres"). + Reply(http.StatusOK). + JSON(api.PostgresConfigResponse{ + MaxConnections: cast.Ptr(100), + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/config/database/postgres"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + flags.ProjectRef + "/config/database/postgres"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorContains(t, err, "unexpected config overrides status 503:") + }) +} diff --git a/internal/postgresConfig/update/update.go b/internal/postgresConfig/update/update.go index 4d7e420870..ffb565ca06 100644 --- a/internal/postgresConfig/update/update.go +++ b/internal/postgresConfig/update/update.go @@ -67,13 +67,14 @@ func Run(ctx context.Context, projectRef string, values []string, replaceOverrid resp, err := utils.GetSupabase().V1UpdatePostgresConfigWithBodyWithResponse(ctx, projectRef, "application/json", bytes.NewReader(bts)) if err != nil { return errors.Errorf("failed to update config overrides: %w", err) + } else if resp.JSON200 == nil { + return errors.Errorf("unexpected update config overrides status %d: %s", resp.StatusCode(), string(resp.Body)) } - if resp.JSON200 == nil { - if resp.StatusCode() == 400 { - return errors.Errorf("failed to update config overrides: %s (%s). This usually indicates that an unsupported or invalid config override was attempted. Please refer to https://supabase.com/docs/guides/platform/custom-postgres-config", resp.Status(), string(resp.Body)) - } - return errors.Errorf("failed to update config overrides: %s (%s)", resp.Status(), string(resp.Body)) + var config map[string]any + err = json.Unmarshal(resp.Body, &config) + if err != nil { + return errors.Errorf("failed to unmarshal update response: %w", err) } + return get.PrintOutPostgresConfigOverrides(config) } - return get.Run(ctx, projectRef, fsys) } diff --git a/internal/postgresConfig/update/update_test.go b/internal/postgresConfig/update/update_test.go new file mode 100644 index 0000000000..f8b65de9c6 --- /dev/null +++ b/internal/postgresConfig/update/update_test.go @@ -0,0 +1,95 @@ +package update + +import ( + "context" + "errors" + "net/http" + "testing" + + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "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" +) + +func TestUpdatePostgresConfig(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("updates postgres config", func(t *testing.T) { + t.Cleanup(fstest.MockStdout(t, ` + + Parameter | Value + -----------------|------- + max_connections | 100 + +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Put("v1/projects/" + flags.ProjectRef + "/config/database/postgres"). + Reply(http.StatusOK). + JSON(api.PostgresConfigResponse{ + MaxConnections: cast.Ptr(100), + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, []string{ + "max_connections=100", + "track_commit_timestamp=true", + "statement_timeout=600", + "wal_keep_size=1GB", + }, true, true, nil) + assert.NoError(t, err) + }) + + t.Run("throws error on missing key", func(t *testing.T) { + err := Run(context.Background(), flags.ProjectRef, []string{"value"}, true, true, nil) + assert.ErrorContains(t, err, "expected config value in key:value format") + }) + + t.Run("throws error on missing project", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/projects/" + flags.ProjectRef + "/config/database/postgres"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, []string{}, false, false, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/projects/" + flags.ProjectRef + "/config/database/postgres"). + Reply(http.StatusOK). + JSON(api.PostgresConfigResponse{ + MaxConnections: cast.Ptr(100), + }) + gock.New(utils.DefaultApiHost). + Put("/v1/projects/" + flags.ProjectRef + "/config/database/postgres"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, []string{}, false, false, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Put("/v1/projects/" + flags.ProjectRef + "/config/database/postgres"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef, []string{}, true, true, nil) + assert.ErrorContains(t, err, "unexpected update config overrides status 503:") + }) +} From 8b2588c0d6dd66dbbf06c64e0243dfa39f0b9ff2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 00:41:19 +0000 Subject: [PATCH 049/117] chore(deps): bump github.com/go-git/go-git/v5 from 5.16.4 to 5.16.5 (#4831) Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) from 5.16.4 to 5.16.5. - [Release notes](https://github.com/go-git/go-git/releases) - [Commits](https://github.com/go-git/go-git/compare/v5.16.4...v5.16.5) --- updated-dependencies: - dependency-name: github.com/go-git/go-git/v5 dependency-version: 5.16.5 dependency-type: direct:production ... 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 16214fa778..92ef184264 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/fsnotify/fsnotify v1.9.0 github.com/getsentry/sentry-go v0.42.0 github.com/go-errors/errors v1.5.1 - github.com/go-git/go-git/v5 v5.16.4 + github.com/go-git/go-git/v5 v5.16.5 github.com/go-playground/validator/v10 v10.30.1 github.com/go-viper/mapstructure/v2 v2.5.0 github.com/go-xmlfmt/xmlfmt v1.1.3 diff --git a/go.sum b/go.sum index 17787e927e..309957b956 100644 --- a/go.sum +++ b/go.sum @@ -363,8 +363,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.16.4 h1:7ajIEZHZJULcyJebDLo99bGgS0jRrOxzZG4uCk2Yb2Y= -github.com/go-git/go-git/v5 v5.16.4/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8= +github.com/go-git/go-git/v5 v5.16.5 h1:mdkuqblwr57kVfXri5TTH+nMFLNUxIj9Z7F5ykFbw5s= +github.com/go-git/go-git/v5 v5.16.5/go.mod h1:QOMLpNf1qxuSY4StA/ArOdfFR2TrKEjJiye2kel2m+M= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= From aaa39e5ae97e70912aaaf73c7eae4e56a88a6750 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 02:13:46 +0000 Subject: [PATCH 050/117] fix(docker): bump the docker-minor group in /pkg/config/templates with 3 updates (#4832) fix(docker): bump the docker-minor group Bumps the docker-minor group in /pkg/config/templates with 3 updates: supabase/studio, supabase/edge-runtime and supabase/realtime. Updates `supabase/studio` from 2026.02.04-sha-fba1944 to 2026.02.09-sha-18cc6f8 Updates `supabase/edge-runtime` from v1.70.1 to v1.70.3 Updates `supabase/realtime` from v2.75.2 to v2.76.0 --- updated-dependencies: - dependency-name: supabase/studio dependency-version: 2026.02.09-sha-18cc6f8 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/edge-runtime dependency-version: v1.70.3 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/realtime dependency-version: v2.76.0 dependency-type: direct:production dependency-group: docker-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 4f9fe60c4c..d6527987dd 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -5,13 +5,13 @@ FROM library/kong:2.8.1 AS kong FROM axllent/mailpit:v1.22.3 AS mailpit FROM postgrest/postgrest:v14.4 AS postgrest FROM supabase/postgres-meta:v0.95.2 AS pgmeta -FROM supabase/studio:2026.02.04-sha-fba1944 AS studio +FROM supabase/studio:2026.02.09-sha-18cc6f8 AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy -FROM supabase/edge-runtime:v1.70.1 AS edgeruntime +FROM supabase/edge-runtime:v1.70.3 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.186.0 AS gotrue -FROM supabase/realtime:v2.75.2 AS realtime +FROM supabase/realtime:v2.76.0 AS realtime FROM supabase/storage-api:v1.37.7 AS storage FROM supabase/logflare:1.30.8 AS logflare # Append to JobImages when adding new dependencies below From 9fce3b775c152923f3385c3711f61a67bba3c926 Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Tue, 10 Feb 2026 17:17:35 +0800 Subject: [PATCH 051/117] chore: unit tests for custom domains (#4835) * chore: unit tests for custom domains * chore: refactor status message printing --- cmd/domains.go | 30 ++++- internal/hostnames/activate/activate.go | 39 ++---- internal/hostnames/activate/activate_test.go | 90 +++++++++++++ internal/hostnames/common.go | 132 ++++--------------- internal/hostnames/common_test.go | 54 ++++++++ internal/hostnames/create/create.go | 49 +++---- internal/hostnames/create/create_test.go | 127 ++++++++++++++++++ internal/hostnames/delete/delete.go | 21 ++- internal/hostnames/delete/delete_test.go | 56 ++++++++ internal/hostnames/get/get.go | 29 ++-- internal/hostnames/get/get_test.go | 90 +++++++++++++ internal/hostnames/reverify/reverify.go | 30 ++--- internal/hostnames/reverify/reverify_test.go | 90 +++++++++++++ 13 files changed, 623 insertions(+), 214 deletions(-) create mode 100644 internal/hostnames/activate/activate_test.go create mode 100644 internal/hostnames/create/create_test.go create mode 100644 internal/hostnames/delete/delete_test.go create mode 100644 internal/hostnames/get/get_test.go create mode 100644 internal/hostnames/reverify/reverify_test.go diff --git a/cmd/domains.go b/cmd/domains.go index 9ec4a097da..0d30637478 100644 --- a/cmd/domains.go +++ b/cmd/domains.go @@ -8,6 +8,7 @@ import ( "github.com/supabase/cli/internal/hostnames/delete" "github.com/supabase/cli/internal/hostnames/get" "github.com/supabase/cli/internal/hostnames/reverify" + "github.com/supabase/cli/internal/utils" "github.com/supabase/cli/internal/utils/flags" ) @@ -32,7 +33,10 @@ Use of custom domains and vanity subdomains is mutually exclusive. Expects your custom hostname to have a CNAME record to your Supabase project's subdomain.`, RunE: func(cmd *cobra.Command, args []string) error { - return create.Run(cmd.Context(), flags.ProjectRef, customHostname, rawOutput, afero.NewOsFs()) + if rawOutput && utils.OutputFormat.Value == utils.OutputPretty { + utils.OutputFormat.Value = utils.OutputJson + } + return create.Run(cmd.Context(), flags.ProjectRef, customHostname, afero.NewOsFs()) }, } @@ -41,7 +45,10 @@ Expects your custom hostname to have a CNAME record to your Supabase project's s Short: "Get the current custom hostname config", Long: "Retrieve the custom hostname config for your project, as stored in the Supabase platform.", RunE: func(cmd *cobra.Command, args []string) error { - return get.Run(cmd.Context(), flags.ProjectRef, rawOutput, afero.NewOsFs()) + if rawOutput && utils.OutputFormat.Value == utils.OutputPretty { + utils.OutputFormat.Value = utils.OutputJson + } + return get.Run(cmd.Context(), flags.ProjectRef, afero.NewOsFs()) }, } @@ -49,7 +56,10 @@ Expects your custom hostname to have a CNAME record to your Supabase project's s Use: "reverify", Short: "Re-verify the custom hostname config for your project", RunE: func(cmd *cobra.Command, args []string) error { - return reverify.Run(cmd.Context(), flags.ProjectRef, rawOutput, afero.NewOsFs()) + if rawOutput && utils.OutputFormat.Value == utils.OutputPretty { + utils.OutputFormat.Value = utils.OutputJson + } + return reverify.Run(cmd.Context(), flags.ProjectRef, afero.NewOsFs()) }, } @@ -61,7 +71,10 @@ Expects your custom hostname to have a CNAME record to your Supabase project's s This reconfigures your Supabase project to respond to requests on your custom hostname. After the custom hostname is activated, your project's auth services will no longer function on the Supabase-provisioned subdomain.`, RunE: func(cmd *cobra.Command, args []string) error { - return activate.Run(cmd.Context(), flags.ProjectRef, rawOutput, afero.NewOsFs()) + if rawOutput && utils.OutputFormat.Value == utils.OutputPretty { + utils.OutputFormat.Value = utils.OutputJson + } + return activate.Run(cmd.Context(), flags.ProjectRef, afero.NewOsFs()) }, } @@ -69,6 +82,9 @@ After the custom hostname is activated, your project's auth services will no lon Use: "delete", Short: "Deletes the custom hostname config for your project", RunE: func(cmd *cobra.Command, args []string) error { + if rawOutput && utils.OutputFormat.Value == utils.OutputPretty { + utils.OutputFormat.Value = utils.OutputJson + } return delete.Run(cmd.Context(), flags.ProjectRef, afero.NewOsFs()) }, } @@ -78,12 +94,14 @@ func init() { persistentFlags := customHostnamesCmd.PersistentFlags() persistentFlags.StringVar(&flags.ProjectRef, "project-ref", "", "Project ref of the Supabase project.") persistentFlags.BoolVar(&rawOutput, "include-raw-output", false, "Include raw output (useful for debugging).") - customHostnamesCreateCmd.Flags().StringVar(&customHostname, "custom-hostname", "", "The custom hostname to use for your Supabase project.") + cobra.CheckErr(persistentFlags.MarkDeprecated("include-raw-output", "use -o json instead")) + createFlags := customHostnamesCreateCmd.Flags() + createFlags.StringVar(&customHostname, "custom-hostname", "", "The custom hostname to use for your Supabase project.") + cobra.CheckErr(customHostnamesCreateCmd.MarkFlagRequired("custom-hostname")) customHostnamesCmd.AddCommand(customHostnamesGetCmd) customHostnamesCmd.AddCommand(customHostnamesCreateCmd) customHostnamesCmd.AddCommand(customHostnamesReverifyCmd) customHostnamesCmd.AddCommand(customHostnamesActivateCmd) customHostnamesCmd.AddCommand(customHostnamesDeleteCmd) - rootCmd.AddCommand(customHostnamesCmd) } diff --git a/internal/hostnames/activate/activate.go b/internal/hostnames/activate/activate.go index c2306a29ee..11a5e41248 100644 --- a/internal/hostnames/activate/activate.go +++ b/internal/hostnames/activate/activate.go @@ -2,7 +2,7 @@ package activate import ( "context" - "fmt" + "os" "github.com/go-errors/errors" "github.com/spf13/afero" @@ -10,33 +10,16 @@ import ( "github.com/supabase/cli/internal/utils" ) -func Run(ctx context.Context, projectRef string, includeRawOutput bool, fsys afero.Fs) error { - // 1. Sanity checks. - { - resp, err := hostnames.GetCustomHostnameConfig(ctx, projectRef) - if err != nil { - return err - } - err = hostnames.VerifyCNAME(ctx, projectRef, resp.JSON200.CustomHostname) - if err != nil { - return err - } +func Run(ctx context.Context, projectRef string, fsys afero.Fs) error { + resp, err := utils.GetSupabase().V1ActivateCustomHostnameWithResponse(ctx, projectRef) + if err != nil { + return errors.Errorf("failed to activate custom hostname: %w", err) + } else if resp.JSON201 == nil { + return errors.Errorf("unexpected activate hostname status %d: %s", resp.StatusCode(), string(resp.Body)) } - - // 2. activate custom hostname config - { - resp, err := utils.GetSupabase().V1ActivateCustomHostnameWithResponse(ctx, projectRef) - if err != nil { - return errors.Errorf("failed to activate custom hostname: %w", err) - } - if resp.JSON201 == nil { - return errors.New("failed to activate custom hostname config: " + string(resp.Body)) - } - status, err := hostnames.TranslateStatus(resp.JSON201, includeRawOutput) - if err != nil { - return err - } - fmt.Println(status) - return nil + hostnames.PrintStatus(resp.JSON201, os.Stderr) + if utils.OutputFormat.Value != utils.OutputPretty { + return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, *resp.JSON201) } + return nil } diff --git a/internal/hostnames/activate/activate_test.go b/internal/hostnames/activate/activate_test.go new file mode 100644 index 0000000000..104885421d --- /dev/null +++ b/internal/hostnames/activate/activate_test.go @@ -0,0 +1,90 @@ +package activate + +import ( + "context" + "net/http" + "testing" + + "github.com/go-errors/errors" + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/flags" + "github.com/supabase/cli/pkg/api" +) + +func TestActivateHostname(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("activate custom hostname", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("v1/projects/" + flags.ProjectRef + "/custom-hostname/activate"). + Reply(http.StatusCreated). + JSON(api.UpdateCustomHostnameResponse{}) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("encodes toml output", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputToml + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(fstest.MockStdout(t, `CustomHostname = "" +Status = "4_origin_setup_completed" + +[Data] + Success = false + [Data.Result] + CustomOriginServer = "" + Hostname = "" + Id = "" + Status = "" + [Data.Result.OwnershipVerification] + Name = "" + Type = "" + Value = "" + [Data.Result.Ssl] + Status = "" +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("v1/projects/" + flags.ProjectRef + "/custom-hostname/activate"). + Reply(http.StatusCreated). + JSON(api.UpdateCustomHostnameResponse{ + Status: api.N4OriginSetupCompleted, + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("v1/projects/" + flags.ProjectRef + "/custom-hostname/activate"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("v1/projects/" + flags.ProjectRef + "/custom-hostname/activate"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorContains(t, err, "unexpected activate hostname status 503:") + }) +} diff --git a/internal/hostnames/common.go b/internal/hostnames/common.go index c01e6a0da3..f991e7a652 100644 --- a/internal/hostnames/common.go +++ b/internal/hostnames/common.go @@ -2,8 +2,8 @@ package hostnames import ( "context" - "encoding/json" "fmt" + "io" "strings" "github.com/go-errors/errors" @@ -11,125 +11,49 @@ import ( "github.com/supabase/cli/pkg/api" ) -func GetCustomHostnameConfig(ctx context.Context, projectRef string) (*api.V1GetHostnameConfigResponse, error) { - resp, err := utils.GetSupabase().V1GetHostnameConfigWithResponse(ctx, projectRef) - if err != nil { - return nil, errors.Errorf("failed to get custom hostname: %w", err) - } - if resp.JSON200 == nil { - return nil, errors.New("failed to get custom hostname config; received: " + string(resp.Body)) - } - return resp, nil -} - func VerifyCNAME(ctx context.Context, projectRef string, customHostname string) error { expectedEndpoint := fmt.Sprintf("%s.", utils.GetSupabaseHost(projectRef)) - cname, err := utils.ResolveCNAME(ctx, customHostname) - if err != nil { + if cname, err := utils.ResolveCNAME(ctx, customHostname); err != nil { return errors.Errorf("expected custom hostname '%s' to have a CNAME record pointing to your project at '%s', but it failed to resolve: %w", customHostname, expectedEndpoint, err) - } - if cname != expectedEndpoint { + } else if cname != expectedEndpoint { return errors.Errorf("expected custom hostname '%s' to have a CNAME record pointing to your project at '%s', but it is currently set to '%s'", customHostname, expectedEndpoint, cname) } return nil } -type RawResponse struct { - Result struct { - CustomOriginServer string `json:"custom_origin_server"` - OwnershipVerification struct { - Name string - Type string - Value string - } `json:"ownership_verification"` - Ssl struct { - ValidationRecords []struct { - Status string `json:"status"` - TxtName string `json:"txt_name"` - TxtValue string `json:"txt_value"` - } `json:"validation_records"` - ValidationErrors []struct { - Message string `json:"message"` - } `json:"validation_errors"` - Status string `json:"status"` - } - } `json:"result"` -} - -func serializeRawOutput(response *api.UpdateCustomHostnameResponse) (string, error) { - output, err := json.MarshalIndent(response, "", " ") - if err != nil { - return "", errors.Errorf("failed to serialize json: %w", err) - } - return string(output), nil -} - -func appendRawOutputIfNeeded(status string, response *api.UpdateCustomHostnameResponse, includeRawOutput bool) string { - if !includeRawOutput { - return status - } - rawOutput, err := serializeRawOutput(response) - if err != nil { - return fmt.Sprintf("%s\nFailed to serialize raw output: %+v\n", status, err) - } - return fmt.Sprintf("%s\nRaw output follows:\n%s\n", status, rawOutput) -} - -func TranslateStatus(response *api.UpdateCustomHostnameResponse, includeRawOutput bool) (string, error) { - if response.Status == api.N5ServicesReconfigured { - return appendRawOutputIfNeeded(fmt.Sprintf("Custom hostname setup completed. Project is now accessible at %s.", response.CustomHostname), response, includeRawOutput), nil - } - if response.Status == api.N4OriginSetupCompleted { - var res RawResponse - rawBody, err := json.Marshal(response.Data) - if err != nil { - return "", errors.Errorf("failed to serialize body: %w", err) - } - err = json.Unmarshal(rawBody, &res) - if err != nil { - return "", errors.Errorf("failed to deserialize body: %w", err) - } - return appendRawOutputIfNeeded(fmt.Sprintf(`Custom hostname configuration complete, and ready for activation. +func PrintStatus(response *api.UpdateCustomHostnameResponse, w io.Writer) { + switch response.Status { + case api.N5ServicesReconfigured: + fmt.Fprintf(w, "Custom hostname setup completed. Project is now accessible at %s.", response.CustomHostname) + case api.N4OriginSetupCompleted: + fmt.Fprintf(w, `Custom hostname configuration complete, and ready for activation. Please ensure that your custom domain is set up as a CNAME record to your Supabase subdomain: - %s CNAME -> %s`, response.CustomHostname, res.Result.CustomOriginServer), response, includeRawOutput), nil - } - if response.Status == api.N2Initiated { - var res RawResponse - rawBody, err := json.Marshal(response.Data) - if err != nil { - return "", errors.Errorf("failed to serialize body: %w", err) - } - err = json.Unmarshal(rawBody, &res) - if err != nil { - return "", errors.Errorf("failed to deserialize body: %w", err) - } - ssl := res.Result.Ssl.ValidationRecords - if res.Result.Ssl.Status == "initializing" { - return appendRawOutputIfNeeded("Custom hostname setup is being initialized; please request re-verification in a few seconds.\n", response, includeRawOutput), nil - } - if len(res.Result.Ssl.ValidationErrors) > 0 { +%s CNAME -> %s`, response.CustomHostname, response.Data.Result.CustomOriginServer) + case api.N3ChallengeVerified, api.N2Initiated: + if ssl := response.Data.Result.Ssl; ssl.Status == "initializing" { + fmt.Fprintln(w, "Custom hostname setup is being initialized; please request re-verification in a few seconds.") + } else if errVal := response.Data.Result.Ssl.ValidationErrors; errVal != nil && len(*errVal) > 0 { var errorMessages []string - for _, valError := range res.Result.Ssl.ValidationErrors { + for _, valError := range *errVal { if strings.Contains(valError.Message, "caa_error") { - return appendRawOutputIfNeeded("CAA mismatch; please remove any existing CAA records on your domain, or add one for \"digicert.com\"\n", response, includeRawOutput), nil + fmt.Fprintln(w, `CAA mismatch; please remove any existing CAA records on your domain, or add one for "digicert.com"`) + return } errorMessages = append(errorMessages, valError.Message) } valErrors := strings.Join(errorMessages, "\n\t- ") - return appendRawOutputIfNeeded(fmt.Sprintf("SSL validation errors: \n\t- %s\n", valErrors), response, includeRawOutput), nil - } - if len(ssl) != 1 { - return "", errors.Errorf("expected a single SSL verification record, received: %+v", ssl) - } - records := "" - if ssl[0].TxtName != "" { - records = fmt.Sprintf("%s\n\t%s TXT -> %s", records, ssl[0].TxtName, ssl[0].TxtValue) + fmt.Fprintf(w, "SSL validation errors: \n\t- %s\n", valErrors) + } else if len(ssl.ValidationRecords) != 1 { + fmt.Fprintf(w, "expected a single SSL verification record, received: %+v", ssl) + } else { + fmt.Fprintln(w, `Custom hostname verification in-progress; please configure the appropriate DNS entries and request re-verification. +Required outstanding validation records:`) + if rec := ssl.ValidationRecords[0]; rec.TxtName != "" { + fmt.Fprintf(w, "\t%s TXT -> %s", rec.TxtName, rec.TxtValue) + } } - status := fmt.Sprintf("Custom hostname verification in-progress; please configure the appropriate DNS entries and request re-verification.\n"+ - "Required outstanding validation records: %s\n", - records) - return appendRawOutputIfNeeded(status, response, includeRawOutput), nil + case api.N1NotStarted: + fmt.Fprintln(w, "Custom hostname configuration not started.") } - return appendRawOutputIfNeeded("Custom hostname configuration not started.", response, includeRawOutput), nil } diff --git a/internal/hostnames/common_test.go b/internal/hostnames/common_test.go index 2c3755c7c0..4502ef2fe7 100644 --- a/internal/hostnames/common_test.go +++ b/internal/hostnames/common_test.go @@ -1,6 +1,7 @@ package hostnames import ( + "bytes" "context" "net/http" "testing" @@ -8,6 +9,7 @@ import ( "github.com/h2non/gock" "github.com/stretchr/testify/assert" "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/pkg/api" ) func TestVerifyCNAME(t *testing.T) { @@ -44,3 +46,55 @@ func TestVerifyCNAMEFailures(t *testing.T) { err := VerifyCNAME(context.Background(), "foobarbaz", "hello.custom-domain.com") assert.ErrorContains(t, err, "failed to locate appropriate CNAME record for hello.custom-domain.com") } + +func TestPrintStatus(t *testing.T) { + t.Run("initialising hostname message", func(t *testing.T) { + data := api.UpdateCustomHostnameResponse{Status: api.N2Initiated} + data.Data.Result.Ssl.Status = "initializing" + var buf bytes.Buffer + PrintStatus(&data, &buf) + assert.Equal(t, "Custom hostname setup is being initialized; please request re-verification in a few seconds.\n", buf.String()) + }) + + t.Run("validation records message", func(t *testing.T) { + data := api.UpdateCustomHostnameResponse{Status: api.N2Initiated} + data.Data.Result.Ssl.ValidationRecords = []struct { + TxtName string `json:"txt_name"` + TxtValue string `json:"txt_value"` + }{{ + TxtName: "_pki-validation", + TxtValue: "f3k9d8s7h2l1m4n6p0q5r", + }} + var buf bytes.Buffer + PrintStatus(&data, &buf) + assert.Equal(t, `Custom hostname verification in-progress; please configure the appropriate DNS entries and request re-verification. +Required outstanding validation records: + _pki-validation TXT -> f3k9d8s7h2l1m4n6p0q5r`, buf.String()) + }) + + t.Run("validation error message", func(t *testing.T) { + data := api.UpdateCustomHostnameResponse{Status: api.N2Initiated} + data.Data.Result.Ssl.ValidationErrors = &[]struct { + Message string `json:"message"` + }{{ + Message: "self signed cert", + }} + var buf bytes.Buffer + PrintStatus(&data, &buf) + assert.Equal(t, `SSL validation errors: + - self signed cert +`, buf.String()) + }) + + t.Run("validation caa error message", func(t *testing.T) { + data := api.UpdateCustomHostnameResponse{Status: api.N2Initiated} + data.Data.Result.Ssl.ValidationErrors = &[]struct { + Message string `json:"message"` + }{{ + Message: "caa_error", + }} + var buf bytes.Buffer + PrintStatus(&data, &buf) + assert.Equal(t, "CAA mismatch; please remove any existing CAA records on your domain, or add one for \"digicert.com\"\n", buf.String()) + }) +} diff --git a/internal/hostnames/create/create.go b/internal/hostnames/create/create.go index 563b524bc7..ef6f01e603 100644 --- a/internal/hostnames/create/create.go +++ b/internal/hostnames/create/create.go @@ -2,8 +2,7 @@ package create import ( "context" - "fmt" - "strings" + "os" "github.com/go-errors/errors" "github.com/spf13/afero" @@ -12,36 +11,24 @@ import ( "github.com/supabase/cli/pkg/api" ) -func Run(ctx context.Context, projectRef string, customHostname string, includeRawOutput bool, fsys afero.Fs) error { - // 1. Sanity checks. - hostname := strings.TrimSpace(customHostname) - { - if len(hostname) == 0 { - return errors.New("non-empty custom hostname expected") - } - // we verify that a CNAME is set as it simplifies the checks used for verifying ownership - err := hostnames.VerifyCNAME(ctx, projectRef, hostname) - if err != nil { - return err - } +func Run(ctx context.Context, projectRef string, customHostname string, fsys afero.Fs) error { + // 1. verify that a CNAME is set as it simplifies the checks used for verifying ownership + err := hostnames.VerifyCNAME(ctx, projectRef, customHostname) + if err != nil { + return err } - // 2. create custom hostname - { - resp, err := utils.GetSupabase().V1UpdateHostnameConfigWithResponse(ctx, projectRef, api.V1UpdateHostnameConfigJSONRequestBody{ - CustomHostname: hostname, - }) - if err != nil { - return errors.Errorf("failed to create custom hostname: %w", err) - } - if resp.JSON201 == nil { - return errors.New("failed to create custom hostname config: " + string(resp.Body)) - } - status, err := hostnames.TranslateStatus(resp.JSON201, includeRawOutput) - if err != nil { - return err - } - fmt.Println(status) - return nil + resp, err := utils.GetSupabase().V1UpdateHostnameConfigWithResponse(ctx, projectRef, api.V1UpdateHostnameConfigJSONRequestBody{ + CustomHostname: customHostname, + }) + if err != nil { + return errors.Errorf("failed to create custom hostname: %w", err) + } else if resp.JSON201 == nil { + return errors.Errorf("unexpected create hostname status %d: %s", resp.StatusCode(), string(resp.Body)) + } + hostnames.PrintStatus(resp.JSON201, os.Stderr) + if utils.OutputFormat.Value != utils.OutputPretty { + return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, *resp.JSON201) } + return nil } diff --git a/internal/hostnames/create/create_test.go b/internal/hostnames/create/create_test.go new file mode 100644 index 0000000000..64d3ffd0a0 --- /dev/null +++ b/internal/hostnames/create/create_test.go @@ -0,0 +1,127 @@ +package create + +import ( + "context" + "net/http" + "testing" + + "github.com/go-errors/errors" + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/cloudflare" + "github.com/supabase/cli/internal/utils/flags" + "github.com/supabase/cli/pkg/api" +) + +func TestCreateHostname(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("create custom hostname", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New("https://1.1.1.1"). + Get("/dns-query"). + Reply(http.StatusOK). + JSON(&cloudflare.DNSResponse{Answer: []cloudflare.DNSAnswer{ + {Type: cloudflare.TypeCNAME, Data: flags.ProjectRef + ".."}, + }}) + gock.New(utils.DefaultApiHost). + Post("v1/projects/" + flags.ProjectRef + "/custom-hostname"). + Reply(http.StatusCreated). + JSON(api.UpdateCustomHostnameResponse{}) + // Run test + err := Run(context.Background(), flags.ProjectRef, "example.com", nil) + assert.NoError(t, err) + }) + + t.Run("encodes toml output", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputToml + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(fstest.MockStdout(t, `CustomHostname = "" +Status = "1_not_started" + +[Data] + Success = false + [Data.Result] + CustomOriginServer = "" + Hostname = "" + Id = "" + Status = "" + [Data.Result.OwnershipVerification] + Name = "" + Type = "" + Value = "" + [Data.Result.Ssl] + Status = "" +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New("https://1.1.1.1"). + Get("/dns-query"). + Reply(http.StatusOK). + JSON(&cloudflare.DNSResponse{Answer: []cloudflare.DNSAnswer{ + {Type: cloudflare.TypeCNAME, Data: flags.ProjectRef + ".."}, + }}) + gock.New(utils.DefaultApiHost). + Post("v1/projects/" + flags.ProjectRef + "/custom-hostname"). + Reply(http.StatusCreated). + JSON(api.UpdateCustomHostnameResponse{ + Status: api.N1NotStarted, + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, "example.com", nil) + assert.NoError(t, err) + }) + + t.Run("throws error on invalid cname", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New("https://1.1.1.1"). + Get("/dns-query"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, "example.com", nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New("https://1.1.1.1"). + Get("/dns-query"). + Reply(http.StatusOK). + JSON(&cloudflare.DNSResponse{Answer: []cloudflare.DNSAnswer{ + {Type: cloudflare.TypeCNAME, Data: flags.ProjectRef + ".."}, + }}) + gock.New(utils.DefaultApiHost). + Post("v1/projects/" + flags.ProjectRef + "/custom-hostname"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, "example.com", nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New("https://1.1.1.1"). + Get("/dns-query"). + Reply(http.StatusOK). + JSON(&cloudflare.DNSResponse{Answer: []cloudflare.DNSAnswer{ + {Type: cloudflare.TypeCNAME, Data: flags.ProjectRef + ".."}, + }}) + gock.New(utils.DefaultApiHost). + Post("v1/projects/" + flags.ProjectRef + "/custom-hostname"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef, "example.com", nil) + assert.ErrorContains(t, err, "unexpected create hostname status 503:") + }) +} diff --git a/internal/hostnames/delete/delete.go b/internal/hostnames/delete/delete.go index 3b9f3653c1..fdc3a18032 100644 --- a/internal/hostnames/delete/delete.go +++ b/internal/hostnames/delete/delete.go @@ -3,6 +3,8 @@ package delete import ( "context" "fmt" + "net/http" + "os" "github.com/go-errors/errors" "github.com/spf13/afero" @@ -10,17 +12,12 @@ import ( ) func Run(ctx context.Context, projectRef string, fsys afero.Fs) error { - // 1. Sanity checks. - // 2. delete config - { - resp, err := utils.GetSupabase().V1DeleteHostnameConfigWithResponse(ctx, projectRef) - if err != nil { - return errors.Errorf("failed to delete custom hostname: %w", err) - } - if resp.StatusCode() != 200 { - return errors.New("failed to delete custom hostname config; received: " + resp.Status()) - } - fmt.Println("Deleted custom hostname config successfully.") - return nil + resp, err := utils.GetSupabase().V1DeleteHostnameConfigWithResponse(ctx, projectRef) + if err != nil { + return errors.Errorf("failed to delete custom hostname: %w", err) + } else if resp.StatusCode() != http.StatusOK { + return errors.Errorf("unexpected delete hostname status %d: %s", resp.StatusCode(), string(resp.Body)) } + fmt.Fprintln(os.Stderr, "Deleted custom hostname config successfully.") + return nil } diff --git a/internal/hostnames/delete/delete_test.go b/internal/hostnames/delete/delete_test.go new file mode 100644 index 0000000000..667d12a39a --- /dev/null +++ b/internal/hostnames/delete/delete_test.go @@ -0,0 +1,56 @@ +package delete + +import ( + "context" + "net/http" + "testing" + + "github.com/go-errors/errors" + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "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" +) + +func TestDeleteHostname(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("deletes custom hostname", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Delete("v1/projects/" + flags.ProjectRef + "/custom-hostname"). + Reply(http.StatusOK). + JSON(api.UpdateCustomHostnameResponse{}) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Delete("v1/projects/" + flags.ProjectRef + "/custom-hostname"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Delete("v1/projects/" + flags.ProjectRef + "/custom-hostname"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorContains(t, err, "unexpected delete hostname status 503:") + }) +} diff --git a/internal/hostnames/get/get.go b/internal/hostnames/get/get.go index 9e17c19f2d..ded7c8622f 100644 --- a/internal/hostnames/get/get.go +++ b/internal/hostnames/get/get.go @@ -2,25 +2,24 @@ package get import ( "context" - "fmt" + "os" + "github.com/go-errors/errors" "github.com/spf13/afero" "github.com/supabase/cli/internal/hostnames" + "github.com/supabase/cli/internal/utils" ) -func Run(ctx context.Context, projectRef string, includeRawOutput bool, fsys afero.Fs) error { - // 1. Sanity checks. - // 2. activate custom hostname config - { - resp, err := hostnames.GetCustomHostnameConfig(ctx, projectRef) - if err != nil { - return err - } - status, err := hostnames.TranslateStatus(resp.JSON200, includeRawOutput) - if err != nil { - return err - } - fmt.Println(status) - return nil +func Run(ctx context.Context, projectRef string, fsys afero.Fs) error { + resp, err := utils.GetSupabase().V1GetHostnameConfigWithResponse(ctx, projectRef) + if err != nil { + return errors.Errorf("failed to get custom hostname: %w", err) + } else if resp.JSON200 == nil { + return errors.Errorf("unexpected get hostname status %d: %s", resp.StatusCode(), string(resp.Body)) } + hostnames.PrintStatus(resp.JSON200, os.Stderr) + if utils.OutputFormat.Value != utils.OutputPretty { + return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, *resp.JSON200) + } + return nil } diff --git a/internal/hostnames/get/get_test.go b/internal/hostnames/get/get_test.go new file mode 100644 index 0000000000..9fe5a60e35 --- /dev/null +++ b/internal/hostnames/get/get_test.go @@ -0,0 +1,90 @@ +package get + +import ( + "context" + "errors" + "net/http" + "testing" + + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/flags" + "github.com/supabase/cli/pkg/api" +) + +func TestGetHostname(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("fetches custom hostname", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/projects/" + flags.ProjectRef + "/custom-hostname"). + Reply(http.StatusOK). + JSON(api.UpdateCustomHostnameResponse{}) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("encodes toml output", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputToml + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(fstest.MockStdout(t, `CustomHostname = "" +Status = "5_services_reconfigured" + +[Data] + Success = false + [Data.Result] + CustomOriginServer = "" + Hostname = "" + Id = "" + Status = "" + [Data.Result.OwnershipVerification] + Name = "" + Type = "" + Value = "" + [Data.Result.Ssl] + Status = "" +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/projects/" + flags.ProjectRef + "/custom-hostname"). + Reply(http.StatusOK). + JSON(api.UpdateCustomHostnameResponse{ + Status: api.N5ServicesReconfigured, + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/projects/" + flags.ProjectRef + "/custom-hostname"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/projects/" + flags.ProjectRef + "/custom-hostname"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorContains(t, err, "unexpected get hostname status 503:") + }) +} diff --git a/internal/hostnames/reverify/reverify.go b/internal/hostnames/reverify/reverify.go index 7f4329903e..f38f38fd49 100644 --- a/internal/hostnames/reverify/reverify.go +++ b/internal/hostnames/reverify/reverify.go @@ -2,7 +2,7 @@ package reverify import ( "context" - "fmt" + "os" "github.com/go-errors/errors" "github.com/spf13/afero" @@ -10,22 +10,16 @@ import ( "github.com/supabase/cli/internal/utils" ) -func Run(ctx context.Context, projectRef string, includeRawOutput bool, fsys afero.Fs) error { - // 1. Sanity checks. - // 2. attempt to re-verify custom hostname config - { - resp, err := utils.GetSupabase().V1VerifyDnsConfigWithResponse(ctx, projectRef) - if err != nil { - return errors.Errorf("failed to re-verify custom hostname: %w", err) - } - if resp.JSON201 == nil { - return errors.New("failed to re-verify custom hostname config: " + string(resp.Body)) - } - status, err := hostnames.TranslateStatus(resp.JSON201, includeRawOutput) - if err != nil { - return err - } - fmt.Println(status) - return nil +func Run(ctx context.Context, projectRef string, fsys afero.Fs) error { + resp, err := utils.GetSupabase().V1VerifyDnsConfigWithResponse(ctx, projectRef) + if err != nil { + return errors.Errorf("failed to re-verify custom hostname: %w", err) + } else if resp.JSON201 == nil { + return errors.Errorf("unexpected re-verify hostname status %d: %s", resp.StatusCode(), string(resp.Body)) } + hostnames.PrintStatus(resp.JSON201, os.Stderr) + if utils.OutputFormat.Value != utils.OutputPretty { + return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, *resp.JSON201) + } + return nil } diff --git a/internal/hostnames/reverify/reverify_test.go b/internal/hostnames/reverify/reverify_test.go new file mode 100644 index 0000000000..f0b6f4fd16 --- /dev/null +++ b/internal/hostnames/reverify/reverify_test.go @@ -0,0 +1,90 @@ +package reverify + +import ( + "context" + "net/http" + "testing" + + "github.com/go-errors/errors" + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/flags" + "github.com/supabase/cli/pkg/api" +) + +func TestReverifyHostname(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("reverify custom hostname", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("v1/projects/" + flags.ProjectRef + "/custom-hostname/reverify"). + Reply(http.StatusCreated). + JSON(api.UpdateCustomHostnameResponse{}) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("encodes toml output", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputToml + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(fstest.MockStdout(t, `CustomHostname = "" +Status = "2_initiated" + +[Data] + Success = false + [Data.Result] + CustomOriginServer = "" + Hostname = "" + Id = "" + Status = "" + [Data.Result.OwnershipVerification] + Name = "" + Type = "" + Value = "" + [Data.Result.Ssl] + Status = "" +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("v1/projects/" + flags.ProjectRef + "/custom-hostname/reverify"). + Reply(http.StatusCreated). + JSON(api.UpdateCustomHostnameResponse{ + Status: api.N2Initiated, + }) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.NoError(t, err) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("v1/projects/" + flags.ProjectRef + "/custom-hostname/reverify"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Post("v1/projects/" + flags.ProjectRef + "/custom-hostname/reverify"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), flags.ProjectRef, nil) + assert.ErrorContains(t, err, "unexpected re-verify hostname status 503:") + }) +} From cc889c66329966d489e7ba0a1c1537efd3c7cc0c Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Tue, 10 Feb 2026 17:34:59 +0800 Subject: [PATCH 052/117] chore: unit tests for snippets command (#4836) * chore: unit tests for snippets command * chore: download snippet test --- internal/snippets/download/download.go | 7 +- internal/snippets/download/download_test.go | 73 +++++++++++ internal/snippets/list/list.go | 10 +- internal/snippets/list/list_test.go | 130 ++++++++++++++++++++ 4 files changed, 210 insertions(+), 10 deletions(-) create mode 100644 internal/snippets/download/download_test.go create mode 100644 internal/snippets/list/list_test.go diff --git a/internal/snippets/download/download.go b/internal/snippets/download/download.go index 22b45dd689..36b8deb18d 100644 --- a/internal/snippets/download/download.go +++ b/internal/snippets/download/download.go @@ -19,12 +19,9 @@ func Run(ctx context.Context, snippetId string, fsys afero.Fs) error { resp, err := utils.GetSupabase().V1GetASnippetWithResponse(ctx, id) if err != nil { return errors.Errorf("failed to download snippet: %w", err) + } else if resp.JSON200 == nil { + return errors.Errorf("unexpected download snippet status %d: %s", resp.StatusCode(), string(resp.Body)) } - - if resp.JSON200 == nil { - return errors.New("Unexpected error downloading SQL snippet: " + string(resp.Body)) - } - fmt.Println(resp.JSON200.Content.Sql) return nil } diff --git a/internal/snippets/download/download_test.go b/internal/snippets/download/download_test.go new file mode 100644 index 0000000000..9a290ef4ad --- /dev/null +++ b/internal/snippets/download/download_test.go @@ -0,0 +1,73 @@ +package download + +import ( + "context" + "net/http" + "testing" + + "github.com/go-errors/errors" + "github.com/google/uuid" + "github.com/h2non/gock" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/flags" + "github.com/supabase/cli/pkg/api" +) + +func TestSnippetDownload(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + snippetId, err := uuid.NewUUID() + require.NoError(t, err) + + t.Run("downloads sql snippet", func(t *testing.T) { + t.Cleanup(fstest.MockStdout(t, "select 1\n")) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/snippets/" + snippetId.String()). + Reply(http.StatusOK). + JSON(api.SnippetResponse{Content: struct { + Favorite *bool `json:"favorite,omitempty"` + SchemaVersion string `json:"schema_version"` + Sql string `json:"sql"` + }{ + Sql: "select 1", + }}) + // Run test + err = Run(context.Background(), snippetId.String(), nil) + assert.NoError(t, err) + }) + + t.Run("throws error on invalid id", func(t *testing.T) { + err := Run(context.Background(), "", nil) + assert.ErrorContains(t, err, "invalid snippet ID:") + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/snippets/" + snippetId.String()). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), snippetId.String(), nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/snippets/" + snippetId.String()). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), snippetId.String(), nil) + assert.ErrorContains(t, err, "unexpected download snippet status 503:") + }) +} diff --git a/internal/snippets/list/list.go b/internal/snippets/list/list.go index ca5529cee0..1c5c1ee8df 100644 --- a/internal/snippets/list/list.go +++ b/internal/snippets/list/list.go @@ -24,12 +24,12 @@ func Run(ctx context.Context, fsys afero.Fs) error { switch utils.OutputFormat.Value { case utils.OutputPretty: - table := `|ID|NAME|VISIBILITY|OWNER|CREATED AT (UTC)|UPDATED AT (UTC)| + var table strings.Builder + table.WriteString(`|ID|NAME|VISIBILITY|OWNER|CREATED AT (UTC)|UPDATED AT (UTC)| |-|-|-|-|-|-| -` +`) for _, snippet := range resp.JSON200.Data { - table += fmt.Sprintf( - "|`%s`|`%s`|`%s`|`%s`|`%s`|`%s`|\n", + fmt.Fprintf(&table, "|`%s`|`%s`|`%s`|`%s`|`%s`|`%s`|\n", snippet.Id, strings.ReplaceAll(snippet.Name, "|", "\\|"), strings.ReplaceAll(string(snippet.Visibility), "|", "\\|"), @@ -38,7 +38,7 @@ func Run(ctx context.Context, fsys afero.Fs) error { utils.FormatTimestamp(snippet.UpdatedAt), ) } - return utils.RenderTable(table) + return utils.RenderTable(table.String()) case utils.OutputEnv: return errors.New(utils.ErrEnvNotSupported) } diff --git a/internal/snippets/list/list_test.go b/internal/snippets/list/list_test.go new file mode 100644 index 0000000000..37848da493 --- /dev/null +++ b/internal/snippets/list/list_test.go @@ -0,0 +1,130 @@ +package list + +import ( + "context" + "net/http" + "testing" + + "github.com/go-errors/errors" + "github.com/h2non/gock" + "github.com/oapi-codegen/nullable" + "github.com/stretchr/testify/assert" + "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" + "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/internal/utils/flags" + "github.com/supabase/cli/pkg/api" +) + +func TestListSnippets(t *testing.T) { + flags.ProjectRef = apitest.RandomProjectRef() + + t.Run("lists sql snippets", func(t *testing.T) { + t.Cleanup(fstest.MockStdout(t, ` + + ID | NAME | VISIBILITY | OWNER | CREATED AT (UTC) | UPDATED AT (UTC) + --------------|--------------|------------|----------|---------------------|--------------------- + test-snippet | Create table | user | supaseed | 2023-10-13 17:48:58 | 2023-10-13 17:48:58 + +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/snippets"). + Reply(http.StatusOK). + JSON(api.SnippetList{Data: []struct { + Description nullable.Nullable[string] `json:"description"` + Favorite bool `json:"favorite"` + Id string `json:"id"` + InsertedAt string `json:"inserted_at"` + Name string `json:"name"` + Owner struct { + Id float32 `json:"id"` + Username string `json:"username"` + } `json:"owner"` + Project struct { + Id float32 `json:"id"` + Name string `json:"name"` + } `json:"project"` + Type api.SnippetListDataType `json:"type"` + UpdatedAt string `json:"updated_at"` + UpdatedBy struct { + Id float32 `json:"id"` + Username string `json:"username"` + } `json:"updated_by"` + Visibility api.SnippetListDataVisibility `json:"visibility"` + }{{ + Id: "test-snippet", + Name: "Create table", + Visibility: api.SnippetListDataVisibilityUser, + Owner: struct { + Id float32 `json:"id"` + Username string `json:"username"` + }{ + Username: "supaseed", + }, + InsertedAt: "2023-10-13T17:48:58.491Z", + UpdatedAt: "2023-10-13T17:48:58.491Z", + }}}) + // Run test + err := Run(context.Background(), nil) + assert.NoError(t, err) + }) + + t.Run("encodes json output", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputJson + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(fstest.MockStdout(t, `{ + "data": null +} +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/snippets"). + Reply(http.StatusOK). + JSON(api.SnippetList{}) + // Run test + err := Run(context.Background(), nil) + assert.NoError(t, err) + }) + + t.Run("throws error on env format", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/snippets"). + Reply(http.StatusOK). + JSON(api.SnippetList{}) + // Run test + err := Run(context.Background(), nil) + assert.ErrorIs(t, err, utils.ErrEnvNotSupported) + }) + + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/snippets"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), nil) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("v1/snippets"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), nil) + assert.ErrorContains(t, err, "unexpected list snippets status 503:") + }) +} From 49de83ddbf76e82de7f471e41ef512b113072c7e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Feb 2026 00:13:51 +0000 Subject: [PATCH 053/117] fix(docker): bump supabase/realtime from v2.76.0 to v2.76.1 in /pkg/config/templates in the docker-minor group (#4844) fix(docker): bump supabase/realtime Bumps the docker-minor group in /pkg/config/templates with 1 update: supabase/realtime. Updates `supabase/realtime` from v2.76.0 to v2.76.1 --- updated-dependencies: - dependency-name: supabase/realtime dependency-version: v2.76.1 dependency-type: direct:production dependency-group: docker-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 d6527987dd..7da7f456cc 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -11,7 +11,7 @@ FROM supabase/edge-runtime:v1.70.3 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.186.0 AS gotrue -FROM supabase/realtime:v2.76.0 AS realtime +FROM supabase/realtime:v2.76.1 AS realtime FROM supabase/storage-api:v1.37.7 AS storage FROM supabase/logflare:1.30.8 AS logflare # Append to JobImages when adding new dependencies below From 63ff718b1cdbf8e3e147ecb808762c5fa3a6e4c4 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Wed, 11 Feb 2026 19:57:18 +0800 Subject: [PATCH 054/117] chore: unit tests for config push --- internal/config/push/push_test.go | 83 ++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 17 deletions(-) diff --git a/internal/config/push/push_test.go b/internal/config/push/push_test.go index 5af8fb273f..687ea5d052 100644 --- a/internal/config/push/push_test.go +++ b/internal/config/push/push_test.go @@ -11,14 +11,53 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" "github.com/supabase/cli/internal/utils" + "github.com/supabase/cli/pkg/api" ) func TestPushConfig(t *testing.T) { project := apitest.RandomProjectRef() - // Setup valid access token - token := apitest.RandomAccessToken(t) - t.Setenv("SUPABASE_ACCESS_TOKEN", string(token)) + + t.Run("pushes local config", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(fstest.MockStdin(t, "y")) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup in-memory fs + fsys := afero.NewMemMapFs() + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/"+project+"/billing/addons"). + Reply(http.StatusOK). + SetHeader("Content-Type", "application/json"). + BodyString(`{ + "available_addons":[{ + "name": "GraphQL", + "type": "api", + "variants": [{ + "id": "api_graphql", + "name": "GraphQL", + "price": { + "amount": 0.1027, + "description": "$75/month, then $10/month", + "interval": "hourly", + "type": "usage" + } + }] + }] + }`) + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + project + "/postgrest"). + Reply(http.StatusOK). + JSON(api.V1PostgrestConfigResponse{}) + gock.New(utils.DefaultApiHost). + Patch("/v1/projects/" + project + "/postgrest"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), project, fsys) + // Check error + assert.ErrorIs(t, err, errNetwork) + }) t.Run("throws error on malformed config", func(t *testing.T) { // Setup in-memory fs @@ -31,10 +70,10 @@ func TestPushConfig(t *testing.T) { }) t.Run("throws error on service unavailable", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) // Setup in-memory fs fsys := afero.NewMemMapFs() // Setup mock api - defer gock.OffAll() gock.New(utils.DefaultApiHost). Get("/v1/projects/" + project + "/billing/addons"). Reply(http.StatusServiceUnavailable) @@ -47,13 +86,10 @@ func TestPushConfig(t *testing.T) { func TestCostMatrix(t *testing.T) { project := apitest.RandomProjectRef() - // Setup valid access token - token := apitest.RandomAccessToken(t) - t.Setenv("SUPABASE_ACCESS_TOKEN", string(token)) t.Run("fetches cost matrix", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) // Setup mock api - defer gock.OffAll() gock.New(utils.DefaultApiHost). Get("/v1/projects/"+project+"/billing/addons"). Reply(http.StatusOK). @@ -66,10 +102,10 @@ func TestCostMatrix(t *testing.T) { "id": "auth_mfa_phone_default", "name": "Advanced MFA - Phone", "price": { - "amount": 0.1027, - "description": "$75/month, then $10/month", - "interval": "hourly", - "type": "usage" + "amount": 0.1027, + "description": "$75/month, then $10/month", + "interval": "hourly", + "type": "usage" } }] }, { @@ -79,10 +115,10 @@ func TestCostMatrix(t *testing.T) { "id": "auth_mfa_web_authn_default", "name": "Advanced MFA - WebAuthn", "price": { - "amount": 0.1027, - "description": "$75/month, then $10/month", - "interval": "hourly", - "type": "usage" + "amount": 0.1027, + "description": "$75/month, then $10/month", + "interval": "hourly", + "type": "usage" } }] }] @@ -100,8 +136,8 @@ func TestCostMatrix(t *testing.T) { t.Run("throws error on network error", func(t *testing.T) { errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) // Setup mock api - defer gock.OffAll() gock.New(utils.DefaultApiHost). Get("/v1/projects/" + project + "/billing/addons"). ReplyError(errNetwork) @@ -111,4 +147,17 @@ func TestCostMatrix(t *testing.T) { assert.ErrorIs(t, err, errNetwork) assert.Nil(t, cost) }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + project + "/billing/addons"). + Reply(http.StatusServiceUnavailable) + // Run test + cost, err := getCostMatrix(context.Background(), project) + // Check error + assert.ErrorContains(t, err, "unexpected list addons status 503:") + assert.Nil(t, cost) + }) } From 67e813fefa9442851f9b9b2b565a8fb39ce8577d Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Wed, 11 Feb 2026 21:13:30 +0800 Subject: [PATCH 055/117] chore: unit tests for encryption command --- cmd/encryption.go | 4 +- internal/encryption/get/get.go | 7 +-- internal/encryption/get/get_test.go | 43 ++++++++--------- internal/encryption/update/update.go | 13 ++---- internal/encryption/update/update_test.go | 57 +++++++++++------------ 5 files changed, 56 insertions(+), 68 deletions(-) diff --git a/cmd/encryption.go b/cmd/encryption.go index d3b654afcb..77b114ec50 100644 --- a/cmd/encryption.go +++ b/cmd/encryption.go @@ -1,8 +1,6 @@ package cmd import ( - "os" - "github.com/spf13/cobra" "github.com/supabase/cli/internal/encryption/get" "github.com/supabase/cli/internal/encryption/update" @@ -28,7 +26,7 @@ var ( Use: "update-root-key", Short: "Update root encryption key of a Supabase project", RunE: func(cmd *cobra.Command, args []string) error { - return update.Run(cmd.Context(), flags.ProjectRef, os.Stdin) + return update.Run(cmd.Context(), flags.ProjectRef) }, } ) diff --git a/internal/encryption/get/get.go b/internal/encryption/get/get.go index 93c6986352..a48e21c8bc 100644 --- a/internal/encryption/get/get.go +++ b/internal/encryption/get/get.go @@ -12,12 +12,9 @@ func Run(ctx context.Context, projectRef string) error { resp, err := utils.GetSupabase().V1GetPgsodiumConfigWithResponse(ctx, projectRef) if err != nil { return errors.Errorf("failed to retrieve pgsodium config: %w", err) + } else if resp.JSON200 == nil { + return errors.Errorf("unexpected get pgsodium config status %d: %s", resp.StatusCode(), string(resp.Body)) } - - if resp.JSON200 == nil { - return errors.New("Unexpected error retrieving project root key: " + string(resp.Body)) - } - fmt.Println(resp.JSON200.RootKey) return nil } diff --git a/internal/encryption/get/get_test.go b/internal/encryption/get/get_test.go index 8f280189be..42c16f0cef 100644 --- a/internal/encryption/get/get_test.go +++ b/internal/encryption/get/get_test.go @@ -5,6 +5,7 @@ import ( "net/http" "testing" + "github.com/go-errors/errors" "github.com/h2non/gock" "github.com/stretchr/testify/assert" "github.com/supabase/cli/internal/testing/apitest" @@ -13,40 +14,40 @@ import ( ) func TestGetRootKey(t *testing.T) { + project := apitest.RandomProjectRef() + t.Run("fetches project encryption key", func(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)) - // Flush pending mocks after test execution - defer gock.OffAll() + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api gock.New(utils.DefaultApiHost). Get("/v1/projects/" + project + "/pgsodium"). Reply(http.StatusOK). JSON(api.PgsodiumConfigResponse{RootKey: "test-key"}) // Run test err := Run(context.Background(), project) - // Check error assert.NoError(t, err) - assert.Empty(t, apitest.ListUnmatchedRequests()) }) - t.Run("throws on invalid credentials", func(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)) - // Flush pending mocks after test execution - defer gock.OffAll() + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + project + "/pgsodium"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), project) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api gock.New(utils.DefaultApiHost). Get("/v1/projects/" + project + "/pgsodium"). - Reply(http.StatusForbidden) + Reply(http.StatusServiceUnavailable) // Run test err := Run(context.Background(), project) - // Check error - assert.ErrorContains(t, err, "Unexpected error retrieving project root key:") - assert.Empty(t, apitest.ListUnmatchedRequests()) + assert.ErrorContains(t, err, "unexpected get pgsodium config status 503:") }) } diff --git a/internal/encryption/update/update.go b/internal/encryption/update/update.go index ed576823ff..ca4b483f33 100644 --- a/internal/encryption/update/update.go +++ b/internal/encryption/update/update.go @@ -12,20 +12,17 @@ import ( "github.com/supabase/cli/pkg/api" ) -func Run(ctx context.Context, projectRef string, stdin *os.File) error { +func Run(ctx context.Context, projectRef string) error { fmt.Fprintf(os.Stderr, "Enter a new root key: ") - input := credentials.PromptMasked(stdin) + input := credentials.PromptMasked(os.Stdin) resp, err := utils.GetSupabase().V1UpdatePgsodiumConfigWithResponse(ctx, projectRef, api.UpdatePgsodiumConfigBody{ RootKey: strings.TrimSpace(input), }) if err != nil { return errors.Errorf("failed to update pgsodium config: %w", err) + } else if resp.JSON200 == nil { + return errors.Errorf("unexpected update pgsodium config status %d: %s", resp.StatusCode(), string(resp.Body)) } - - if resp.JSON200 == nil { - return errors.New("Unexpected error updating project root key: " + string(resp.Body)) - } - - fmt.Println("Finished " + utils.Aqua("supabase root-key update") + ".") + fmt.Fprintln(os.Stderr, "Finished "+utils.Aqua("supabase root-key update")+".") return nil } diff --git a/internal/encryption/update/update_test.go b/internal/encryption/update/update_test.go index 8a6f609300..f15a107092 100644 --- a/internal/encryption/update/update_test.go +++ b/internal/encryption/update/update_test.go @@ -2,60 +2,55 @@ package update import ( "context" + "errors" "net/http" - "os" "testing" "github.com/h2non/gock" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" "github.com/supabase/cli/internal/utils" "github.com/supabase/cli/pkg/api" ) func TestUpdateRootKey(t *testing.T) { + project := apitest.RandomProjectRef() + t.Run("updates project encryption key", func(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)) - // Setup root key - r, w, err := os.Pipe() - require.NoError(t, err) - _, err = w.WriteString("test-key") - require.NoError(t, err) - require.NoError(t, w.Close()) - // Flush pending mocks after test execution - defer gock.OffAll() + t.Cleanup(fstest.MockStdin(t, "test-key")) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api gock.New(utils.DefaultApiHost). Put("/v1/projects/" + project + "/pgsodium"). JSON(api.UpdatePgsodiumConfigBody{RootKey: "test-key"}). Reply(http.StatusOK). JSON(api.PgsodiumConfigResponse{RootKey: "test-key"}) // Run test - err = Run(context.Background(), project, r) - // Check error + err := Run(context.Background(), project) assert.NoError(t, err) - assert.Empty(t, apitest.ListUnmatchedRequests()) }) - t.Run("throws on invalid credentials", func(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)) - // Flush pending mocks after test execution - defer gock.OffAll() + t.Run("throws error on network error", func(t *testing.T) { + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Put("/v1/projects/" + project + "/pgsodium"). + ReplyError(errNetwork) + // Run test + err := Run(context.Background(), project) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api gock.New(utils.DefaultApiHost). Put("/v1/projects/" + project + "/pgsodium"). - Reply(http.StatusForbidden) + Reply(http.StatusServiceUnavailable) // Run test - err := Run(context.Background(), project, nil) - // Check error - assert.ErrorContains(t, err, "Unexpected error updating project root key:") - assert.Empty(t, apitest.ListUnmatchedRequests()) + err := Run(context.Background(), project) + assert.ErrorContains(t, err, "unexpected update pgsodium config status 503:") }) } From 0ad412c91b8bea85767c4c52daafc1e752db9ed3 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Wed, 11 Feb 2026 22:00:27 +0800 Subject: [PATCH 056/117] chore: update signing keys test --- internal/gen/signingkeys/signingkeys.go | 62 +++++++--------- internal/gen/signingkeys/signingkeys_test.go | 74 ++++++++++++++++++++ 2 files changed, 98 insertions(+), 38 deletions(-) diff --git a/internal/gen/signingkeys/signingkeys.go b/internal/gen/signingkeys/signingkeys.go index 5651ac2651..b1fdb9e73c 100644 --- a/internal/gen/signingkeys/signingkeys.go +++ b/internal/gen/signingkeys/signingkeys.go @@ -9,7 +9,6 @@ import ( "encoding/base64" "encoding/json" "fmt" - "io" "math/big" "os" "path/filepath" @@ -102,7 +101,6 @@ func Run(ctx context.Context, algorithm string, appendMode bool, fsys afero.Fs) if err != nil { return err } - outputPath := utils.Config.Auth.SigningKeysPath // Generate key pair privateJWK, err := GeneratePrivateKey(config.Algorithm(algorithm)) @@ -111,7 +109,7 @@ func Run(ctx context.Context, algorithm string, appendMode bool, fsys afero.Fs) } // Only serialise a single key to stdout - if len(outputPath) == 0 { + if len(utils.Config.Auth.SigningKeysPath) == 0 { enc := json.NewEncoder(os.Stdout) if err := enc.Encode(privateJWK); err != nil { return errors.Errorf("failed to encode signing key: %w", err) @@ -127,51 +125,25 @@ signing_keys_path = "./signing_key.json" return nil } - var jwkArray []config.JWK - if err := utils.MkdirIfNotExistFS(fsys, filepath.Dir(outputPath)); err != nil { - return err - } - f, err := fsys.OpenFile(outputPath, os.O_RDWR|os.O_CREATE, 0600) - if err != nil { - return errors.Errorf("failed to open signing key: %w", err) - } - defer f.Close() if appendMode { - // Load existing key and reset file - dec := json.NewDecoder(f) - // Since a new file is empty, we must ignore EOF error - if err := dec.Decode(&jwkArray); err != nil && !errors.Is(err, io.EOF) { - return errors.Errorf("failed to decode signing key: %w", err) - } - if _, err = f.Seek(0, io.SeekStart); err != nil { - return errors.Errorf("failed to seek signing key: %w", err) - } - } else if fi, err := f.Stat(); fi.Size() > 0 { - if err != nil { - fmt.Fprintln(utils.GetDebugLogger(), err) - } - label := fmt.Sprintf("Do you want to overwrite the existing %s file?", utils.Bold(outputPath)) + utils.Config.Auth.SigningKeys = append(utils.Config.Auth.SigningKeys, *privateJWK) + } else { + label := fmt.Sprintf("Do you want to overwrite the existing %s file?", utils.Bold(utils.Config.Auth.SigningKeysPath)) if shouldOverwrite, err := utils.NewConsole().PromptYesNo(ctx, label, true); err != nil { return err } else if !shouldOverwrite { return errors.New(context.Canceled) } - if err := f.Truncate(0); err != nil { - return errors.Errorf("failed to truncate signing key: %w", err) - } + utils.Config.Auth.SigningKeys = []config.JWK{*privateJWK} } - jwkArray = append(jwkArray, *privateJWK) - // Write to file - enc := json.NewEncoder(f) - enc.SetIndent("", " ") - if err := enc.Encode(jwkArray); err != nil { - return errors.Errorf("failed to encode signing key: %w", err) + if err := saveSigningKeys(fsys); err != nil { + return err } - fmt.Fprintf(os.Stderr, "JWT signing key appended to: %s (now contains %d keys)\n", utils.Bold(outputPath), len(jwkArray)) - if len(jwkArray) == 1 { - if ignored, err := utils.IsGitIgnored(outputPath); err != nil { + fmt.Fprintf(os.Stderr, "JWT signing key appended to: %s (now contains %d keys)\n", utils.Bold(utils.Config.Auth.SigningKeysPath), len(utils.Config.Auth.SigningKeys)) + if len(utils.Config.Auth.SigningKeys) == 1 { + if ignored, err := utils.IsGitIgnored(utils.Config.Auth.SigningKeysPath); err != nil { fmt.Fprintln(utils.GetDebugLogger(), err) } else if !ignored { // Since the output path is user defined, we can't update the managed .gitignore file. @@ -181,6 +153,20 @@ signing_keys_path = "./signing_key.json" return nil } +func saveSigningKeys(fsys afero.Fs) error { + f, err := fsys.OpenFile(utils.Config.Auth.SigningKeysPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + return errors.Errorf("failed to open signing key: %w", err) + } + defer f.Close() + enc := json.NewEncoder(f) + enc.SetIndent("", " ") + if err := enc.Encode(utils.Config.Auth.SigningKeys); err != nil { + return errors.Errorf("failed to encode signing key: %w", err) + } + return nil +} + // GetSupportedAlgorithms returns a list of supported algorithms func GetSupportedAlgorithms() []string { return []string{string(config.AlgRS256), string(config.AlgES256)} diff --git a/internal/gen/signingkeys/signingkeys_test.go b/internal/gen/signingkeys/signingkeys_test.go index 6c3a7c63d5..b03d8277f2 100644 --- a/internal/gen/signingkeys/signingkeys_test.go +++ b/internal/gen/signingkeys/signingkeys_test.go @@ -1,8 +1,16 @@ package signingkeys import ( + "context" + "os" + "path/filepath" "testing" + "github.com/spf13/afero" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/supabase/cli/internal/testing/fstest" + "github.com/supabase/cli/internal/utils" "github.com/supabase/cli/pkg/config" ) @@ -110,3 +118,69 @@ func TestGetSupportedAlgorithms(t *testing.T) { } } } + +func TestSigningKey(t *testing.T) { + t.Run("generates signing key", func(t *testing.T) { + fsys := afero.NewMemMapFs() + err := Run(context.Background(), "ES256", false, fsys) + assert.NoError(t, err) + }) + + t.Run("throws error on permission denied", func(t *testing.T) { + fsys := &fstest.OpenErrorFs{DenyPath: utils.ConfigPath} + err := Run(context.Background(), "ES256", false, fsys) + assert.ErrorIs(t, err, os.ErrPermission) + }) + + t.Run("throws error on encode failure", func(t *testing.T) { + oldStdout := os.Stdout + t.Cleanup(func() { os.Stdout = oldStdout }) + os.Stdout = nil + // Run test + fsys := afero.NewMemMapFs() + err := Run(context.Background(), "ES256", false, fsys) + assert.ErrorIs(t, err, os.ErrInvalid) + }) +} + +func TestAppendKey(t *testing.T) { + // Setup in-memory fs + fsys := afero.NewMemMapFs() + keyPath := filepath.Join(utils.SupabaseDirPath, "signing_keys.json") + require.NoError(t, utils.WriteFile(keyPath, []byte(`[]`), fsys)) + require.NoError(t, utils.WriteFile(utils.ConfigPath, []byte(` +[auth] +signing_keys_path = "./signing_keys.json" +`), fsys)) + + t.Run("overwrites signing key", func(t *testing.T) { + t.Cleanup(fstest.MockStdin(t, "y")) + err := Run(context.Background(), "ES256", false, fsys) + assert.NoError(t, err) + }) + + t.Run("throws error on context cancelled", func(t *testing.T) { + t.Cleanup(fstest.MockStdin(t, "y")) + ctx, cancel := context.WithCancel(context.Background()) + cancel() + // Run test + err := Run(ctx, "ES256", false, afero.NewReadOnlyFs(fsys)) + assert.ErrorIs(t, err, context.Canceled) + }) + + t.Run("throws error on no answer", func(t *testing.T) { + t.Cleanup(fstest.MockStdin(t, "n")) + err := Run(context.Background(), "ES256", false, afero.NewReadOnlyFs(fsys)) + assert.ErrorIs(t, err, context.Canceled) + }) + + t.Run("appends signing key", func(t *testing.T) { + err := Run(context.Background(), "ES256", true, fsys) + assert.NoError(t, err) + }) + + t.Run("throws error on write failure", func(t *testing.T) { + err := Run(context.Background(), "ES256", true, afero.NewReadOnlyFs(fsys)) + assert.ErrorIs(t, err, os.ErrPermission) + }) +} From e3b0630a3d66dce112480d39b36875ebd2a5ad77 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Wed, 11 Feb 2026 22:08:41 +0800 Subject: [PATCH 057/117] chore: remove to legacy package --- cmd/branches.go | 3 +-- cmd/db.go | 11 ++++---- cmd/gen.go | 2 +- internal/branches/create/create.go | 3 +-- internal/db/diff/diff.go | 22 +++++++++++++-- internal/db/reset/reset.go | 3 +-- internal/utils/git.go | 26 ++++++++++++++++++ .../db => legacy}/branch/create/create.go | 0 .../branch/create/create_test.go | 0 .../branch/create/templates/clone.sh | 0 .../db => legacy}/branch/delete/delete.go | 0 .../branch/delete/delete_test.go | 0 {internal/db => legacy}/branch/list/list.go | 0 .../db => legacy}/branch/list/list_test.go | 0 .../db => legacy}/branch/switch_/switch_.go | 0 .../branch/switch_/switch__test.go | 0 {internal/db => legacy}/diff/pgadmin.go | 27 +++---------------- {internal/gen => legacy}/keys/keys.go | 21 +-------------- 18 files changed, 61 insertions(+), 57 deletions(-) create mode 100644 internal/utils/git.go rename {internal/db => legacy}/branch/create/create.go (100%) rename {internal/db => legacy}/branch/create/create_test.go (100%) rename {internal/db => legacy}/branch/create/templates/clone.sh (100%) rename {internal/db => legacy}/branch/delete/delete.go (100%) rename {internal/db => legacy}/branch/delete/delete_test.go (100%) rename {internal/db => legacy}/branch/list/list.go (100%) rename {internal/db => legacy}/branch/list/list_test.go (100%) rename {internal/db => legacy}/branch/switch_/switch_.go (100%) rename {internal/db => legacy}/branch/switch_/switch__test.go (100%) rename {internal/db => legacy}/diff/pgadmin.go (71%) rename {internal/gen => legacy}/keys/keys.go (83%) diff --git a/cmd/branches.go b/cmd/branches.go index 1f12f8727b..f0888b3429 100644 --- a/cmd/branches.go +++ b/cmd/branches.go @@ -16,7 +16,6 @@ import ( "github.com/supabase/cli/internal/branches/pause" "github.com/supabase/cli/internal/branches/unpause" "github.com/supabase/cli/internal/branches/update" - "github.com/supabase/cli/internal/gen/keys" "github.com/supabase/cli/internal/utils" "github.com/supabase/cli/internal/utils/flags" "github.com/supabase/cli/pkg/api" @@ -229,7 +228,7 @@ func promptBranchId(ctx context.Context, fsys afero.Fs) error { 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 { + if branchId = utils.GetGitBranch(fsys); len(branchId) > 0 { title += fmt.Sprintf(" (or leave blank to use %s)", utils.Aqua(branchId)) } title += ": " diff --git a/cmd/db.go b/cmd/db.go index 94af929082..409ef42380 100644 --- a/cmd/db.go +++ b/cmd/db.go @@ -8,10 +8,6 @@ import ( "github.com/spf13/afero" "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/supabase/cli/internal/db/branch/create" - "github.com/supabase/cli/internal/db/branch/delete" - "github.com/supabase/cli/internal/db/branch/list" - "github.com/supabase/cli/internal/db/branch/switch_" "github.com/supabase/cli/internal/db/diff" "github.com/supabase/cli/internal/db/dump" "github.com/supabase/cli/internal/db/lint" @@ -22,6 +18,11 @@ import ( "github.com/supabase/cli/internal/db/test" "github.com/supabase/cli/internal/utils" "github.com/supabase/cli/internal/utils/flags" + "github.com/supabase/cli/legacy/branch/create" + "github.com/supabase/cli/legacy/branch/delete" + "github.com/supabase/cli/legacy/branch/list" + "github.com/supabase/cli/legacy/branch/switch_" + legacy "github.com/supabase/cli/legacy/diff" "github.com/supabase/cli/pkg/migration" ) @@ -90,7 +91,7 @@ var ( Short: "Diffs the local database for schema changes", RunE: func(cmd *cobra.Command, args []string) error { if usePgAdmin { - return diff.RunPgAdmin(cmd.Context(), schema, file, flags.DbConfig, afero.NewOsFs()) + return legacy.RunPgAdmin(cmd.Context(), schema, file, flags.DbConfig, afero.NewOsFs()) } differ := diff.DiffSchemaMigra if usePgSchema { diff --git a/cmd/gen.go b/cmd/gen.go index d15908a7b2..05f34cbea2 100644 --- a/cmd/gen.go +++ b/cmd/gen.go @@ -13,11 +13,11 @@ import ( "github.com/spf13/afero" "github.com/spf13/cobra" "github.com/supabase/cli/internal/gen/bearerjwt" - "github.com/supabase/cli/internal/gen/keys" "github.com/supabase/cli/internal/gen/signingkeys" "github.com/supabase/cli/internal/gen/types" "github.com/supabase/cli/internal/utils" "github.com/supabase/cli/internal/utils/flags" + "github.com/supabase/cli/legacy/keys" "github.com/supabase/cli/pkg/config" ) diff --git a/internal/branches/create/create.go b/internal/branches/create/create.go index 6d5b9c7a15..5ee14aacd9 100644 --- a/internal/branches/create/create.go +++ b/internal/branches/create/create.go @@ -8,14 +8,13 @@ import ( "github.com/go-errors/errors" "github.com/spf13/afero" "github.com/supabase/cli/internal/branches/list" - "github.com/supabase/cli/internal/gen/keys" "github.com/supabase/cli/internal/utils" "github.com/supabase/cli/internal/utils/flags" "github.com/supabase/cli/pkg/api" ) func Run(ctx context.Context, body api.CreateBranchBody, fsys afero.Fs) error { - gitBranch := keys.GetGitBranchOrDefault("", fsys) + gitBranch := utils.GetGitBranchOrDefault("", fsys) if len(body.BranchName) == 0 && len(gitBranch) > 0 { title := fmt.Sprintf("Do you want to create a branch named %s?", utils.Aqua(gitBranch)) if shouldCreate, err := utils.NewConsole().PromptYesNo(ctx, title, true); err != nil { diff --git a/internal/db/diff/diff.go b/internal/db/diff/diff.go index 18d3420949..3f7854fc7a 100644 --- a/internal/db/diff/diff.go +++ b/internal/db/diff/diff.go @@ -22,7 +22,7 @@ import ( "github.com/jackc/pgx/v4" "github.com/spf13/afero" "github.com/supabase/cli/internal/db/start" - "github.com/supabase/cli/internal/gen/keys" + "github.com/supabase/cli/internal/migration/new" "github.com/supabase/cli/internal/utils" "github.com/supabase/cli/pkg/migration" "github.com/supabase/cli/pkg/parser" @@ -35,7 +35,7 @@ func Run(ctx context.Context, schema []string, file string, config pgconn.Config if err != nil { return err } - branch := keys.GetGitBranch(fsys) + branch := utils.GetGitBranch(fsys) fmt.Fprintln(os.Stderr, "Finished "+utils.Aqua("supabase db diff")+" on branch "+utils.Aqua(branch)+".\n") if err := SaveDiff(out, file, fsys); err != nil { return err @@ -48,6 +48,24 @@ func Run(ctx context.Context, schema []string, file string, config pgconn.Config return nil } +var warnDiff = `WARNING: The diff tool is not foolproof, so you may need to manually rearrange and modify the generated migration. +Run ` + utils.Aqua("supabase db reset") + ` to verify that the new migration does not generate errors.` + +func SaveDiff(out, file string, fsys afero.Fs) error { + if len(out) < 2 { + fmt.Fprintln(os.Stderr, "No schema changes found") + } else if len(file) > 0 { + path := new.GetMigrationPath(utils.GetCurrentTimestamp(), file) + if err := utils.WriteFile(path, []byte(out), fsys); err != nil { + return err + } + fmt.Fprintln(os.Stderr, warnDiff) + } else { + fmt.Println(out) + } + return nil +} + func loadDeclaredSchemas(fsys afero.Fs) ([]string, error) { if schemas := utils.Config.Db.Migrations.SchemaPaths; len(schemas) > 0 { return schemas.Files(afero.NewIOFS(fsys)) diff --git a/internal/db/reset/reset.go b/internal/db/reset/reset.go index 21df9f648f..d86f344975 100644 --- a/internal/db/reset/reset.go +++ b/internal/db/reset/reset.go @@ -21,7 +21,6 @@ import ( "github.com/jackc/pgx/v4" "github.com/spf13/afero" "github.com/supabase/cli/internal/db/start" - "github.com/supabase/cli/internal/gen/keys" "github.com/supabase/cli/internal/migration/apply" "github.com/supabase/cli/internal/migration/down" "github.com/supabase/cli/internal/migration/list" @@ -73,7 +72,7 @@ func Run(ctx context.Context, version string, last uint, config pgconn.Config, f return err } } - branch := keys.GetGitBranch(fsys) + branch := utils.GetGitBranch(fsys) fmt.Fprintln(os.Stderr, "Finished "+utils.Aqua("supabase db reset")+" on branch "+utils.Aqua(branch)+".") return nil } diff --git a/internal/utils/git.go b/internal/utils/git.go new file mode 100644 index 0000000000..2c2ad70337 --- /dev/null +++ b/internal/utils/git.go @@ -0,0 +1,26 @@ +package utils + +import ( + "os" + + "github.com/go-git/go-git/v5" + "github.com/spf13/afero" +) + +func GetGitBranch(fsys afero.Fs) string { + return GetGitBranchOrDefault("main", fsys) +} + +func GetGitBranchOrDefault(def string, fsys afero.Fs) string { + head := os.Getenv("GITHUB_HEAD_REF") + if len(head) > 0 { + return head + } + opts := &git.PlainOpenOptions{DetectDotGit: true} + if repo, err := git.PlainOpenWithOptions(".", opts); err == nil { + if ref, err := repo.Head(); err == nil { + return ref.Name().Short() + } + } + return def +} diff --git a/internal/db/branch/create/create.go b/legacy/branch/create/create.go similarity index 100% rename from internal/db/branch/create/create.go rename to legacy/branch/create/create.go diff --git a/internal/db/branch/create/create_test.go b/legacy/branch/create/create_test.go similarity index 100% rename from internal/db/branch/create/create_test.go rename to legacy/branch/create/create_test.go diff --git a/internal/db/branch/create/templates/clone.sh b/legacy/branch/create/templates/clone.sh similarity index 100% rename from internal/db/branch/create/templates/clone.sh rename to legacy/branch/create/templates/clone.sh diff --git a/internal/db/branch/delete/delete.go b/legacy/branch/delete/delete.go similarity index 100% rename from internal/db/branch/delete/delete.go rename to legacy/branch/delete/delete.go diff --git a/internal/db/branch/delete/delete_test.go b/legacy/branch/delete/delete_test.go similarity index 100% rename from internal/db/branch/delete/delete_test.go rename to legacy/branch/delete/delete_test.go diff --git a/internal/db/branch/list/list.go b/legacy/branch/list/list.go similarity index 100% rename from internal/db/branch/list/list.go rename to legacy/branch/list/list.go diff --git a/internal/db/branch/list/list_test.go b/legacy/branch/list/list_test.go similarity index 100% rename from internal/db/branch/list/list_test.go rename to legacy/branch/list/list_test.go diff --git a/internal/db/branch/switch_/switch_.go b/legacy/branch/switch_/switch_.go similarity index 100% rename from internal/db/branch/switch_/switch_.go rename to legacy/branch/switch_/switch_.go diff --git a/internal/db/branch/switch_/switch__test.go b/legacy/branch/switch_/switch__test.go similarity index 100% rename from internal/db/branch/switch_/switch__test.go rename to legacy/branch/switch_/switch__test.go diff --git a/internal/db/diff/pgadmin.go b/legacy/diff/pgadmin.go similarity index 71% rename from internal/db/diff/pgadmin.go rename to legacy/diff/pgadmin.go index d53cd4660e..e6db262072 100644 --- a/internal/db/diff/pgadmin.go +++ b/legacy/diff/pgadmin.go @@ -4,34 +4,15 @@ import ( "context" _ "embed" "fmt" - "os" "github.com/jackc/pgconn" "github.com/spf13/afero" + "github.com/supabase/cli/internal/db/diff" "github.com/supabase/cli/internal/db/start" - "github.com/supabase/cli/internal/migration/new" "github.com/supabase/cli/internal/utils" "github.com/supabase/cli/pkg/config" ) -var warnDiff = `WARNING: The diff tool is not foolproof, so you may need to manually rearrange and modify the generated migration. -Run ` + utils.Aqua("supabase db reset") + ` to verify that the new migration does not generate errors.` - -func SaveDiff(out, file string, fsys afero.Fs) error { - if len(out) < 2 { - fmt.Fprintln(os.Stderr, "No schema changes found") - } else if len(file) > 0 { - path := new.GetMigrationPath(utils.GetCurrentTimestamp(), file) - if err := utils.WriteFile(path, []byte(out), fsys); err != nil { - return err - } - fmt.Fprintln(os.Stderr, warnDiff) - } else { - fmt.Println(out) - } - return nil -} - func RunPgAdmin(ctx context.Context, schema []string, file string, config pgconn.Config, fsys afero.Fs) error { // Sanity checks. if err := utils.AssertSupabaseDbIsRunning(); err != nil { @@ -44,7 +25,7 @@ func RunPgAdmin(ctx context.Context, schema []string, file string, config pgconn return err } - return SaveDiff(output, file, fsys) + return diff.SaveDiff(output, file, fsys) } var output string @@ -53,7 +34,7 @@ func run(p utils.Program, ctx context.Context, schema []string, config pgconn.Co p.Send(utils.StatusMsg("Creating shadow database...")) // 1. Create shadow db and run migrations - shadow, err := CreateShadowDatabase(ctx, utils.Config.Db.ShadowPort) + shadow, err := diff.CreateShadowDatabase(ctx, utils.Config.Db.ShadowPort) if err != nil { return err } @@ -61,7 +42,7 @@ func run(p utils.Program, ctx context.Context, schema []string, config pgconn.Co if err := start.WaitForHealthyService(ctx, utils.Config.Db.HealthTimeout, shadow); err != nil { return err } - if err := MigrateShadowDatabase(ctx, shadow, fsys); err != nil { + if err := diff.MigrateShadowDatabase(ctx, shadow, fsys); err != nil { return err } diff --git a/internal/gen/keys/keys.go b/legacy/keys/keys.go similarity index 83% rename from internal/gen/keys/keys.go rename to legacy/keys/keys.go index 6c81f4bd32..560a4ce917 100644 --- a/internal/gen/keys/keys.go +++ b/legacy/keys/keys.go @@ -9,7 +9,6 @@ import ( "strings" "github.com/go-errors/errors" - "github.com/go-git/go-git/v5" "github.com/spf13/afero" "github.com/supabase/cli/internal/utils" "github.com/supabase/cli/pkg/config" @@ -24,7 +23,7 @@ type CustomName struct { } func Run(ctx context.Context, projectRef, format string, names CustomName, fsys afero.Fs) error { - branch := GetGitBranch(fsys) + branch := utils.GetGitBranch(fsys) if err := GenerateSecrets(ctx, projectRef, branch, fsys); err != nil { return err } @@ -74,21 +73,3 @@ func GenerateSecrets(ctx context.Context, projectRef, branch string, fsys afero. } return nil } - -func GetGitBranch(fsys afero.Fs) string { - return GetGitBranchOrDefault("main", fsys) -} - -func GetGitBranchOrDefault(def string, fsys afero.Fs) string { - head := os.Getenv("GITHUB_HEAD_REF") - if len(head) > 0 { - return head - } - opts := &git.PlainOpenOptions{DetectDotGit: true} - if repo, err := git.PlainOpenWithOptions(".", opts); err == nil { - if ref, err := repo.Head(); err == nil { - return ref.Name().Short() - } - } - return def -} From ad9a424b423f8e3131f562f6b483233efe32808e Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Wed, 11 Feb 2026 22:26:22 +0800 Subject: [PATCH 058/117] chore: unit tests for functions list --- internal/functions/list/list.go | 11 +-- internal/functions/list/list_test.go | 104 ++++++++++++++++++--------- 2 files changed, 76 insertions(+), 39 deletions(-) diff --git a/internal/functions/list/list.go b/internal/functions/list/list.go index c376a22a9a..ce4a59e216 100644 --- a/internal/functions/list/list.go +++ b/internal/functions/list/list.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "os" + "strings" "time" "github.com/go-errors/errors" @@ -22,13 +23,13 @@ func Run(ctx context.Context, projectRef string, fsys afero.Fs) error { switch utils.OutputFormat.Value { case utils.OutputPretty: - table := `|ID|NAME|SLUG|STATUS|VERSION|UPDATED_AT (UTC)| + var table strings.Builder + table.WriteString(`|ID|NAME|SLUG|STATUS|VERSION|UPDATED_AT (UTC)| |-|-|-|-|-|-| -` +`) for _, function := range *resp.JSON200 { t := time.UnixMilli(function.UpdatedAt) - table += fmt.Sprintf( - "|`%s`|`%s`|`%s`|`%s`|`%d`|`%s`|\n", + fmt.Fprintf(&table, "|`%s`|`%s`|`%s`|`%s`|`%d`|`%s`|\n", function.Id, function.Name, function.Slug, @@ -37,7 +38,7 @@ func Run(ctx context.Context, projectRef string, fsys afero.Fs) error { t.UTC().Format("2006-01-02 15:04:05"), ) } - return utils.RenderTable(table) + return utils.RenderTable(table.String()) case utils.OutputToml: return utils.EncodeOutput(utils.OutputFormat.Value, os.Stdout, struct { Functions []api.FunctionResponse `toml:"functions"` diff --git a/internal/functions/list/list_test.go b/internal/functions/list/list_test.go index 7b6197ff51..0d4a6ce246 100644 --- a/internal/functions/list/list_test.go +++ b/internal/functions/list/list_test.go @@ -10,31 +10,23 @@ import ( "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/supabase/cli/internal/testing/apitest" + "github.com/supabase/cli/internal/testing/fstest" "github.com/supabase/cli/internal/utils" "github.com/supabase/cli/pkg/api" + "github.com/supabase/cli/pkg/cast" ) func TestFunctionsListCommand(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 functions", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) // Setup in-memory fs fsys := afero.NewMemMapFs() - // Flush pending mocks after test execution - defer gock.OffAll() - - testEntrypointPath := "test-entrypoint-path" - testImportMapPath := "test-import-map-path" - testImportMap := false - testVerifyJwt := true - + // Setup mock api gock.New(utils.DefaultApiHost). Get("/v1/projects/" + project + "/functions"). - Reply(200). + Reply(http.StatusOK). JSON([]api.FunctionResponse{{ Id: "test-id", Name: "Test Function", @@ -43,44 +35,88 @@ func TestFunctionsListCommand(t *testing.T) { UpdatedAt: 1687423025152.000000, CreatedAt: 1687423025152.000000, Version: 1.000000, - VerifyJwt: &testVerifyJwt, - EntrypointPath: &testEntrypointPath, - ImportMap: &testImportMap, - ImportMapPath: &testImportMapPath, + VerifyJwt: cast.Ptr(true), + EntrypointPath: cast.Ptr("test-entrypoint-path"), + ImportMap: cast.Ptr(false), + ImportMapPath: cast.Ptr("test-import-map-path"), }}) // Run test err := Run(context.Background(), project, fsys) // Check error assert.NoError(t, err) - assert.Empty(t, apitest.ListUnmatchedRequests()) }) - t.Run("throws error on service unavailable", func(t *testing.T) { - // Setup in-memory fs - fsys := afero.NewMemMapFs() - // Flush pending mocks after test execution - defer gock.OffAll() + t.Run("encodes toml format", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputToml + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(fstest.MockStdout(t, `functions = [] +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api gock.New(utils.DefaultApiHost). Get("/v1/projects/" + project + "/functions"). - Reply(http.StatusServiceUnavailable) + Reply(http.StatusOK). + JSON([]api.FunctionResponse{}) // Run test - err := Run(context.Background(), project, fsys) + err := Run(context.Background(), project, nil) // Check error - assert.ErrorContains(t, err, "unexpected list functions status 503:") + assert.NoError(t, err) + }) + + t.Run("encodes json format", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputJson + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(fstest.MockStdout(t, `[] +`)) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + project + "/functions"). + Reply(http.StatusOK). + JSON([]api.FunctionResponse{}) + // Run test + err := Run(context.Background(), project, nil) + // Check error + assert.NoError(t, err) + }) + + t.Run("throws error on env format", func(t *testing.T) { + utils.OutputFormat.Value = utils.OutputEnv + t.Cleanup(func() { utils.OutputFormat.Value = utils.OutputPretty }) + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + project + "/functions"). + Reply(http.StatusOK). + JSON([]api.FunctionResponse{}) + // Run test + err := Run(context.Background(), project, nil) + // Check error + assert.ErrorIs(t, err, utils.ErrEnvNotSupported) }) 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() + errNetwork := errors.New("network error") + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api gock.New(utils.DefaultApiHost). Get("/v1/projects/" + project + "/functions"). - ReplyError(errors.New("network error")) + ReplyError(errNetwork) // Run test - err := Run(context.Background(), project, fsys) + err := Run(context.Background(), project, nil) // Check error - assert.ErrorContains(t, err, "network error") - assert.Empty(t, apitest.ListUnmatchedRequests()) + assert.ErrorIs(t, err, errNetwork) + }) + + t.Run("throws error on service unavailable", func(t *testing.T) { + t.Cleanup(apitest.MockPlatformAPI(t)) + // Setup mock api + gock.New(utils.DefaultApiHost). + Get("/v1/projects/" + project + "/functions"). + Reply(http.StatusServiceUnavailable) + // Run test + err := Run(context.Background(), project, nil) + // Check error + assert.ErrorContains(t, err, "unexpected list functions status 503:") }) } From 5434608a83632bc1d1f6efca822088bee22a872d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Feb 2026 00:13:49 +0000 Subject: [PATCH 059/117] fix(docker): bump supabase/postgres from 17.6.1.081 to 17.6.1.082 in /pkg/config/templates (#4849) fix(docker): bump supabase/postgres in /pkg/config/templates Bumps supabase/postgres from 17.6.1.081 to 17.6.1.082. --- updated-dependencies: - dependency-name: supabase/postgres dependency-version: 17.6.1.082 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 7da7f456cc..cd6efbd791 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:17.6.1.081 AS pg +FROM supabase/postgres:17.6.1.082 AS pg # 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 b2218895ee04ac5193e2ee923095e28f976a3a0e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Feb 2026 00:19:42 +0000 Subject: [PATCH 060/117] fix(docker): bump the docker-minor group in /pkg/config/templates with 2 updates (#4848) fix(docker): bump the docker-minor group Bumps the docker-minor group in /pkg/config/templates with 2 updates: supabase/realtime and supabase/logflare. Updates `supabase/realtime` from v2.76.1 to v2.76.4 Updates `supabase/logflare` from 1.30.8 to 1.31.0 --- updated-dependencies: - dependency-name: supabase/realtime dependency-version: v2.76.4 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/logflare dependency-version: 1.31.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: docker-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index cd6efbd791..75f95bbd1c 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -11,9 +11,9 @@ FROM supabase/edge-runtime:v1.70.3 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.186.0 AS gotrue -FROM supabase/realtime:v2.76.1 AS realtime +FROM supabase/realtime:v2.76.4 AS realtime FROM supabase/storage-api:v1.37.7 AS storage -FROM supabase/logflare:1.30.8 AS logflare +FROM supabase/logflare:1.31.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 5978fb4a1e3d09584e81384b904c0206a7a5eb04 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Feb 2026 00:13:45 +0000 Subject: [PATCH 061/117] fix(docker): bump supabase/postgres from 17.6.1.082 to 17.6.1.084 in /pkg/config/templates (#4853) fix(docker): bump supabase/postgres in /pkg/config/templates Bumps supabase/postgres from 17.6.1.082 to 17.6.1.084. --- updated-dependencies: - dependency-name: supabase/postgres dependency-version: 17.6.1.084 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 75f95bbd1c..13c21aa6a8 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:17.6.1.082 AS pg +FROM supabase/postgres:17.6.1.084 AS pg # 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 3453b5dcc4f279c69b73f1ae711f0f4f56a0c3c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Feb 2026 00:19:25 +0000 Subject: [PATCH 062/117] fix(docker): bump the docker-minor group in /pkg/config/templates with 2 updates (#4852) fix(docker): bump the docker-minor group Bumps the docker-minor group in /pkg/config/templates with 2 updates: supabase/realtime and supabase/logflare. Updates `supabase/realtime` from v2.76.4 to v2.76.5 Updates `supabase/logflare` from 1.31.0 to 1.31.2 --- updated-dependencies: - dependency-name: supabase/realtime dependency-version: v2.76.5 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/logflare dependency-version: 1.31.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: docker-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 13c21aa6a8..a70827e50b 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -11,9 +11,9 @@ FROM supabase/edge-runtime:v1.70.3 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.186.0 AS gotrue -FROM supabase/realtime:v2.76.4 AS realtime +FROM supabase/realtime:v2.76.5 AS realtime FROM supabase/storage-api:v1.37.7 AS storage -FROM supabase/logflare:1.31.0 AS logflare +FROM supabase/logflare:1.31.2 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 0aee2149e16242c3c798acf907804f41de071728 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:09:14 +0000 Subject: [PATCH 063/117] chore(deps): bump the go-minor group across 2 directories with 4 updates (#4854) Bumps the go-minor group with 3 updates in the / directory: [golang.org/x/mod](https://github.com/golang/mod), [golang.org/x/net](https://github.com/golang/net) and [google.golang.org/grpc](https://github.com/grpc/grpc-go). Bumps the go-minor group with 2 updates in the /pkg directory: [golang.org/x/mod](https://github.com/golang/mod) and [google.golang.org/grpc](https://github.com/grpc/grpc-go). Updates `golang.org/x/mod` from 0.32.0 to 0.33.0 - [Commits](https://github.com/golang/mod/compare/v0.32.0...v0.33.0) Updates `golang.org/x/net` from 0.49.0 to 0.50.0 - [Commits](https://github.com/golang/net/compare/v0.49.0...v0.50.0) Updates `golang.org/x/term` from 0.39.0 to 0.40.0 - [Commits](https://github.com/golang/term/compare/v0.39.0...v0.40.0) Updates `google.golang.org/grpc` from 1.78.0 to 1.79.0 - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.78.0...v1.79.0) Updates `golang.org/x/mod` from 0.32.0 to 0.33.0 - [Commits](https://github.com/golang/mod/compare/v0.32.0...v0.33.0) Updates `google.golang.org/grpc` from 1.78.0 to 1.79.0 - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.78.0...v1.79.0) Updates `golang.org/x/mod` from 0.32.0 to 0.33.0 - [Commits](https://github.com/golang/mod/compare/v0.32.0...v0.33.0) Updates `google.golang.org/grpc` from 1.78.0 to 1.79.0 - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.78.0...v1.79.0) Updates `golang.org/x/mod` from 0.32.0 to 0.33.0 - [Commits](https://github.com/golang/mod/compare/v0.32.0...v0.33.0) Updates `google.golang.org/grpc` from 1.78.0 to 1.79.0 - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.78.0...v1.79.0) --- updated-dependencies: - dependency-name: golang.org/x/mod dependency-version: 0.33.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor - dependency-name: golang.org/x/net dependency-version: 0.50.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor - dependency-name: golang.org/x/term dependency-version: 0.40.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor - dependency-name: google.golang.org/grpc dependency-version: 1.79.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor - dependency-name: golang.org/x/mod dependency-version: 0.33.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor - dependency-name: google.golang.org/grpc dependency-version: 1.79.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor - dependency-name: golang.org/x/mod dependency-version: 0.33.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor - dependency-name: google.golang.org/grpc dependency-version: 1.79.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor - dependency-name: golang.org/x/mod dependency-version: 0.33.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor - dependency-name: google.golang.org/grpc dependency-version: 1.79.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 16 ++++++++-------- go.sum | 32 ++++++++++++++++---------------- pkg/go.mod | 10 +++++----- pkg/go.sum | 20 ++++++++++---------- 4 files changed, 39 insertions(+), 39 deletions(-) diff --git a/go.mod b/go.mod index 92ef184264..7ea4ed212e 100644 --- a/go.mod +++ b/go.mod @@ -54,11 +54,11 @@ require ( github.com/withfig/autocomplete-tools/packages/cobra v1.2.0 github.com/zalando/go-keyring v0.2.6 go.opentelemetry.io/otel v1.40.0 - golang.org/x/mod v0.32.0 - golang.org/x/net v0.49.0 + golang.org/x/mod v0.33.0 + golang.org/x/net v0.50.0 golang.org/x/oauth2 v0.35.0 - golang.org/x/term v0.39.0 - google.golang.org/grpc v1.78.0 + golang.org/x/term v0.40.0 + google.golang.org/grpc v1.79.1 gopkg.in/yaml.v3 v3.0.1 ) @@ -427,13 +427,13 @@ require ( go.uber.org/zap v1.27.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.47.0 // indirect + golang.org/x/crypto v0.48.0 // indirect golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac // indirect golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.33.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.40.0 // indirect + golang.org/x/tools v0.41.0 // indirect golang.org/x/tools/go/expect v0.1.1-deprecated // indirect golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b // indirect diff --git a/go.sum b/go.sum index 309957b956..4c759e1f47 100644 --- a/go.sum +++ b/go.sum @@ -1233,8 +1233,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= 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.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= -golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= @@ -1255,8 +1255,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= -golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1282,8 +1282,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= -golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1344,8 +1344,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= 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= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1356,8 +1356,8 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= 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.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= -golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= +golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= +golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -1370,8 +1370,8 @@ golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= -golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1402,8 +1402,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= -golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= -golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= +golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= +golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM= golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= @@ -1421,8 +1421,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= -google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= 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= diff --git a/pkg/go.mod b/pkg/go.mod index 1c2c3adab0..0f639818fa 100644 --- a/pkg/go.mod +++ b/pkg/go.mod @@ -25,8 +25,8 @@ require ( github.com/spf13/viper v1.21.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/jsonc v0.3.2 - golang.org/x/mod v0.32.0 - google.golang.org/grpc v1.78.0 + golang.org/x/mod v0.33.0 + google.golang.org/grpc v1.79.1 ) require ( @@ -52,8 +52,8 @@ require ( github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/crypto v0.46.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/text v0.32.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/go.sum b/pkg/go.sum index 3a2065560a..3c10460052 100644 --- a/pkg/go.sum +++ b/pkg/go.sum @@ -217,15 +217,15 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 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.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= -golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -255,8 +255,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= 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= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -272,8 +272,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -290,8 +290,8 @@ golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= -google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= From f1ebd29d152ed9c46758fe4f8b1d1eeedc5348d3 Mon Sep 17 00:00:00 2001 From: Andrew Valleteau Date: Mon, 16 Feb 2026 14:20:36 +0100 Subject: [PATCH 064/117] fix(ci): api-sync code generate discriminated union (#4863) --- api/overlay.yaml | 3 + pkg/api/client.gen.go | 750 ++++++++++++++++++++++++++++++++++++++++-- pkg/api/types.gen.go | 206 +++++++++++- 3 files changed, 933 insertions(+), 26 deletions(-) diff --git a/api/overlay.yaml b/api/overlay.yaml index 9418cccd2f..7843f3d86b 100644 --- a/api/overlay.yaml +++ b/api/overlay.yaml @@ -38,6 +38,9 @@ actions: - target: $.components.schemas.*.properties.private_jwk.discriminator description: Replaces discriminated union with concrete type remove: true +- target: $.components.schemas.DiskRequestBody.properties.attributes.discriminator + description: Replaces discriminated union with concrete type + remove: true - target: $.paths.*.*.parameters[?(@.name=='branch_id_or_ref')] update: schema: diff --git a/pkg/api/client.gen.go b/pkg/api/client.gen.go index f6411a0c19..65f2febd28 100644 --- a/pkg/api/client.gen.go +++ b/pkg/api/client.gen.go @@ -372,6 +372,17 @@ type ClientInterface interface { V1UpdatePostgresConfig(ctx context.Context, ref string, body V1UpdatePostgresConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // V1ModifyDatabaseDiskWithBody request with any body + V1ModifyDatabaseDiskWithBody(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + V1ModifyDatabaseDisk(ctx context.Context, ref string, body V1ModifyDatabaseDiskJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + + // V1GetProjectDiskAutoscaleConfig request + V1GetProjectDiskAutoscaleConfig(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // V1GetDiskUtilization request + V1GetDiskUtilization(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) + // V1GetRealtimeConfig request V1GetRealtimeConfig(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -380,6 +391,9 @@ type ClientInterface interface { V1UpdateRealtimeConfig(ctx context.Context, ref string, body V1UpdateRealtimeConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // V1ShutdownRealtime request + V1ShutdownRealtime(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) + // V1GetStorageConfig request V1GetStorageConfig(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -523,6 +537,14 @@ type ClientInterface interface { // V1GetServicesHealth request V1GetServicesHealth(ctx context.Context, ref string, params *V1GetServicesHealthParams, reqEditors ...RequestEditorFn) (*http.Response, error) + // V1GetJitAccessConfig request + V1GetJitAccessConfig(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // V1UpdateJitAccessConfigWithBody request with any body + V1UpdateJitAccessConfigWithBody(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + V1UpdateJitAccessConfig(ctx context.Context, ref string, body V1UpdateJitAccessConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // V1DeleteNetworkBansWithBody request with any body V1DeleteNetworkBansWithBody(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -1866,6 +1888,54 @@ func (c *Client) V1UpdatePostgresConfig(ctx context.Context, ref string, body V1 return c.Client.Do(req) } +func (c *Client) V1ModifyDatabaseDiskWithBody(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewV1ModifyDatabaseDiskRequestWithBody(c.Server, ref, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) V1ModifyDatabaseDisk(ctx context.Context, ref string, body V1ModifyDatabaseDiskJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewV1ModifyDatabaseDiskRequest(c.Server, ref, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) V1GetProjectDiskAutoscaleConfig(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewV1GetProjectDiskAutoscaleConfigRequest(c.Server, ref) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) V1GetDiskUtilization(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewV1GetDiskUtilizationRequest(c.Server, ref) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + func (c *Client) V1GetRealtimeConfig(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewV1GetRealtimeConfigRequest(c.Server, ref) if err != nil { @@ -1902,6 +1972,18 @@ func (c *Client) V1UpdateRealtimeConfig(ctx context.Context, ref string, body V1 return c.Client.Do(req) } +func (c *Client) V1ShutdownRealtime(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewV1ShutdownRealtimeRequest(c.Server, ref) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + func (c *Client) V1GetStorageConfig(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewV1GetStorageConfigRequest(c.Server, ref) if err != nil { @@ -2538,6 +2620,42 @@ func (c *Client) V1GetServicesHealth(ctx context.Context, ref string, params *V1 return c.Client.Do(req) } +func (c *Client) V1GetJitAccessConfig(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewV1GetJitAccessConfigRequest(c.Server, ref) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) V1UpdateJitAccessConfigWithBody(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewV1UpdateJitAccessConfigRequestWithBody(c.Server, ref, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) V1UpdateJitAccessConfig(ctx context.Context, ref string, body V1UpdateJitAccessConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewV1UpdateJitAccessConfigRequest(c.Server, ref, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + func (c *Client) V1DeleteNetworkBansWithBody(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewV1DeleteNetworkBansRequestWithBody(c.Server, ref, contentType, body) if err != nil { @@ -6896,6 +7014,121 @@ func NewV1UpdatePostgresConfigRequestWithBody(server string, ref string, content return req, nil } +// NewV1ModifyDatabaseDiskRequest calls the generic V1ModifyDatabaseDisk builder with application/json body +func NewV1ModifyDatabaseDiskRequest(server string, ref string, body V1ModifyDatabaseDiskJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewV1ModifyDatabaseDiskRequestWithBody(server, ref, "application/json", bodyReader) +} + +// NewV1ModifyDatabaseDiskRequestWithBody generates requests for V1ModifyDatabaseDisk with any type of body +func NewV1ModifyDatabaseDiskRequestWithBody(server string, ref string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "ref", runtime.ParamLocationPath, ref) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/v1/projects/%s/config/disk", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewV1GetProjectDiskAutoscaleConfigRequest generates requests for V1GetProjectDiskAutoscaleConfig +func NewV1GetProjectDiskAutoscaleConfigRequest(server string, ref string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "ref", runtime.ParamLocationPath, ref) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/v1/projects/%s/config/disk/autoscale", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewV1GetDiskUtilizationRequest generates requests for V1GetDiskUtilization +func NewV1GetDiskUtilizationRequest(server string, ref string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "ref", runtime.ParamLocationPath, ref) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/v1/projects/%s/config/disk/util", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + // NewV1GetRealtimeConfigRequest generates requests for V1GetRealtimeConfig func NewV1GetRealtimeConfigRequest(server string, ref string) (*http.Request, error) { var err error @@ -6977,6 +7210,40 @@ func NewV1UpdateRealtimeConfigRequestWithBody(server string, ref string, content return req, nil } +// NewV1ShutdownRealtimeRequest generates requests for V1ShutdownRealtime +func NewV1ShutdownRealtimeRequest(server string, ref string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "ref", runtime.ParamLocationPath, ref) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/v1/projects/%s/config/realtime/shutdown", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + // NewV1GetStorageConfigRequest generates requests for V1GetStorageConfig func NewV1GetStorageConfigRequest(server string, ref string) (*http.Request, error) { var err error @@ -8872,19 +9139,8 @@ func NewV1GetServicesHealthRequest(server string, ref string, params *V1GetServi return req, nil } -// NewV1DeleteNetworkBansRequest calls the generic V1DeleteNetworkBans builder with application/json body -func NewV1DeleteNetworkBansRequest(server string, ref string, body V1DeleteNetworkBansJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) - if err != nil { - return nil, err - } - bodyReader = bytes.NewReader(buf) - return NewV1DeleteNetworkBansRequestWithBody(server, ref, "application/json", bodyReader) -} - -// NewV1DeleteNetworkBansRequestWithBody generates requests for V1DeleteNetworkBans with any type of body -func NewV1DeleteNetworkBansRequestWithBody(server string, ref string, contentType string, body io.Reader) (*http.Request, error) { +// NewV1GetJitAccessConfigRequest generates requests for V1GetJitAccessConfig +func NewV1GetJitAccessConfigRequest(server string, ref string) (*http.Request, error) { var err error var pathParam0 string @@ -8899,7 +9155,7 @@ func NewV1DeleteNetworkBansRequestWithBody(server string, ref string, contentTyp return nil, err } - operationPath := fmt.Sprintf("/v1/projects/%s/network-bans", pathParam0) + operationPath := fmt.Sprintf("/v1/projects/%s/jit-access", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -8909,18 +9165,27 @@ func NewV1DeleteNetworkBansRequestWithBody(server string, ref string, contentTyp return nil, err } - req, err := http.NewRequest("DELETE", queryURL.String(), body) + req, err := http.NewRequest("GET", queryURL.String(), nil) if err != nil { return nil, err } - req.Header.Add("Content-Type", contentType) - return req, nil } -// NewV1ListAllNetworkBansRequest generates requests for V1ListAllNetworkBans -func NewV1ListAllNetworkBansRequest(server string, ref string) (*http.Request, error) { +// NewV1UpdateJitAccessConfigRequest calls the generic V1UpdateJitAccessConfig builder with application/json body +func NewV1UpdateJitAccessConfigRequest(server string, ref string, body V1UpdateJitAccessConfigJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewV1UpdateJitAccessConfigRequestWithBody(server, ref, "application/json", bodyReader) +} + +// NewV1UpdateJitAccessConfigRequestWithBody generates requests for V1UpdateJitAccessConfig with any type of body +func NewV1UpdateJitAccessConfigRequestWithBody(server string, ref string, contentType string, body io.Reader) (*http.Request, error) { var err error var pathParam0 string @@ -8935,7 +9200,7 @@ func NewV1ListAllNetworkBansRequest(server string, ref string) (*http.Request, e return nil, err } - operationPath := fmt.Sprintf("/v1/projects/%s/network-bans/retrieve", pathParam0) + operationPath := fmt.Sprintf("/v1/projects/%s/jit-access", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -8945,15 +9210,98 @@ func NewV1ListAllNetworkBansRequest(server string, ref string) (*http.Request, e return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), nil) + req, err := http.NewRequest("PUT", queryURL.String(), body) if err != nil { return nil, err } + req.Header.Add("Content-Type", contentType) + return req, nil } -// NewV1ListAllNetworkBansEnrichedRequest generates requests for V1ListAllNetworkBansEnriched +// NewV1DeleteNetworkBansRequest calls the generic V1DeleteNetworkBans builder with application/json body +func NewV1DeleteNetworkBansRequest(server string, ref string, body V1DeleteNetworkBansJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewV1DeleteNetworkBansRequestWithBody(server, ref, "application/json", bodyReader) +} + +// NewV1DeleteNetworkBansRequestWithBody generates requests for V1DeleteNetworkBans with any type of body +func NewV1DeleteNetworkBansRequestWithBody(server string, ref string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "ref", runtime.ParamLocationPath, ref) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/v1/projects/%s/network-bans", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("DELETE", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// NewV1ListAllNetworkBansRequest generates requests for V1ListAllNetworkBans +func NewV1ListAllNetworkBansRequest(server string, ref string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "ref", runtime.ParamLocationPath, ref) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/v1/projects/%s/network-bans/retrieve", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + +// NewV1ListAllNetworkBansEnrichedRequest generates requests for V1ListAllNetworkBansEnriched func NewV1ListAllNetworkBansEnrichedRequest(server string, ref string) (*http.Request, error) { var err error @@ -10645,6 +10993,17 @@ type ClientWithResponsesInterface interface { V1UpdatePostgresConfigWithResponse(ctx context.Context, ref string, body V1UpdatePostgresConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*V1UpdatePostgresConfigResponse, error) + // V1ModifyDatabaseDiskWithBodyWithResponse request with any body + V1ModifyDatabaseDiskWithBodyWithResponse(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*V1ModifyDatabaseDiskResponse, error) + + V1ModifyDatabaseDiskWithResponse(ctx context.Context, ref string, body V1ModifyDatabaseDiskJSONRequestBody, reqEditors ...RequestEditorFn) (*V1ModifyDatabaseDiskResponse, error) + + // V1GetProjectDiskAutoscaleConfigWithResponse request + V1GetProjectDiskAutoscaleConfigWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetProjectDiskAutoscaleConfigResponse, error) + + // V1GetDiskUtilizationWithResponse request + V1GetDiskUtilizationWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetDiskUtilizationResponse, error) + // V1GetRealtimeConfigWithResponse request V1GetRealtimeConfigWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetRealtimeConfigResponse, error) @@ -10653,6 +11012,9 @@ type ClientWithResponsesInterface interface { V1UpdateRealtimeConfigWithResponse(ctx context.Context, ref string, body V1UpdateRealtimeConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*V1UpdateRealtimeConfigResponse, error) + // V1ShutdownRealtimeWithResponse request + V1ShutdownRealtimeWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1ShutdownRealtimeResponse, error) + // V1GetStorageConfigWithResponse request V1GetStorageConfigWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetStorageConfigResponse, error) @@ -10796,6 +11158,14 @@ type ClientWithResponsesInterface interface { // V1GetServicesHealthWithResponse request V1GetServicesHealthWithResponse(ctx context.Context, ref string, params *V1GetServicesHealthParams, reqEditors ...RequestEditorFn) (*V1GetServicesHealthResponse, error) + // V1GetJitAccessConfigWithResponse request + V1GetJitAccessConfigWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetJitAccessConfigResponse, error) + + // V1UpdateJitAccessConfigWithBodyWithResponse request with any body + V1UpdateJitAccessConfigWithBodyWithResponse(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*V1UpdateJitAccessConfigResponse, error) + + V1UpdateJitAccessConfigWithResponse(ctx context.Context, ref string, body V1UpdateJitAccessConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*V1UpdateJitAccessConfigResponse, error) + // V1DeleteNetworkBansWithBodyWithResponse request with any body V1DeleteNetworkBansWithBodyWithResponse(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*V1DeleteNetworkBansResponse, error) @@ -12630,6 +13000,71 @@ func (r V1UpdatePostgresConfigResponse) StatusCode() int { return 0 } +type V1ModifyDatabaseDiskResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r V1ModifyDatabaseDiskResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r V1ModifyDatabaseDiskResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type V1GetProjectDiskAutoscaleConfigResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *DiskAutoscaleConfig +} + +// Status returns HTTPResponse.Status +func (r V1GetProjectDiskAutoscaleConfigResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r V1GetProjectDiskAutoscaleConfigResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type V1GetDiskUtilizationResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *DiskUtilMetricsResponse +} + +// Status returns HTTPResponse.Status +func (r V1GetDiskUtilizationResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r V1GetDiskUtilizationResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type V1GetRealtimeConfigResponse struct { Body []byte HTTPResponse *http.Response @@ -12673,6 +13108,27 @@ func (r V1UpdateRealtimeConfigResponse) StatusCode() int { return 0 } +type V1ShutdownRealtimeResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r V1ShutdownRealtimeResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r V1ShutdownRealtimeResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type V1GetStorageConfigResponse struct { Body []byte HTTPResponse *http.Response @@ -13474,6 +13930,50 @@ func (r V1GetServicesHealthResponse) StatusCode() int { return 0 } +type V1GetJitAccessConfigResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *JitAccessResponse +} + +// Status returns HTTPResponse.Status +func (r V1GetJitAccessConfigResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r V1GetJitAccessConfigResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type V1UpdateJitAccessConfigResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *JitAccessResponse +} + +// Status returns HTTPResponse.Status +func (r V1UpdateJitAccessConfigResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r V1UpdateJitAccessConfigResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type V1DeleteNetworkBansResponse struct { Body []byte HTTPResponse *http.Response @@ -15100,6 +15600,41 @@ func (c *ClientWithResponses) V1UpdatePostgresConfigWithResponse(ctx context.Con return ParseV1UpdatePostgresConfigResponse(rsp) } +// V1ModifyDatabaseDiskWithBodyWithResponse request with arbitrary body returning *V1ModifyDatabaseDiskResponse +func (c *ClientWithResponses) V1ModifyDatabaseDiskWithBodyWithResponse(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*V1ModifyDatabaseDiskResponse, error) { + rsp, err := c.V1ModifyDatabaseDiskWithBody(ctx, ref, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseV1ModifyDatabaseDiskResponse(rsp) +} + +func (c *ClientWithResponses) V1ModifyDatabaseDiskWithResponse(ctx context.Context, ref string, body V1ModifyDatabaseDiskJSONRequestBody, reqEditors ...RequestEditorFn) (*V1ModifyDatabaseDiskResponse, error) { + rsp, err := c.V1ModifyDatabaseDisk(ctx, ref, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseV1ModifyDatabaseDiskResponse(rsp) +} + +// V1GetProjectDiskAutoscaleConfigWithResponse request returning *V1GetProjectDiskAutoscaleConfigResponse +func (c *ClientWithResponses) V1GetProjectDiskAutoscaleConfigWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetProjectDiskAutoscaleConfigResponse, error) { + rsp, err := c.V1GetProjectDiskAutoscaleConfig(ctx, ref, reqEditors...) + if err != nil { + return nil, err + } + return ParseV1GetProjectDiskAutoscaleConfigResponse(rsp) +} + +// V1GetDiskUtilizationWithResponse request returning *V1GetDiskUtilizationResponse +func (c *ClientWithResponses) V1GetDiskUtilizationWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetDiskUtilizationResponse, error) { + rsp, err := c.V1GetDiskUtilization(ctx, ref, reqEditors...) + if err != nil { + return nil, err + } + return ParseV1GetDiskUtilizationResponse(rsp) +} + // V1GetRealtimeConfigWithResponse request returning *V1GetRealtimeConfigResponse func (c *ClientWithResponses) V1GetRealtimeConfigWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetRealtimeConfigResponse, error) { rsp, err := c.V1GetRealtimeConfig(ctx, ref, reqEditors...) @@ -15126,6 +15661,15 @@ func (c *ClientWithResponses) V1UpdateRealtimeConfigWithResponse(ctx context.Con return ParseV1UpdateRealtimeConfigResponse(rsp) } +// V1ShutdownRealtimeWithResponse request returning *V1ShutdownRealtimeResponse +func (c *ClientWithResponses) V1ShutdownRealtimeWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1ShutdownRealtimeResponse, error) { + rsp, err := c.V1ShutdownRealtime(ctx, ref, reqEditors...) + if err != nil { + return nil, err + } + return ParseV1ShutdownRealtimeResponse(rsp) +} + // V1GetStorageConfigWithResponse request returning *V1GetStorageConfigResponse func (c *ClientWithResponses) V1GetStorageConfigWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetStorageConfigResponse, error) { rsp, err := c.V1GetStorageConfig(ctx, ref, reqEditors...) @@ -15587,6 +16131,32 @@ func (c *ClientWithResponses) V1GetServicesHealthWithResponse(ctx context.Contex return ParseV1GetServicesHealthResponse(rsp) } +// V1GetJitAccessConfigWithResponse request returning *V1GetJitAccessConfigResponse +func (c *ClientWithResponses) V1GetJitAccessConfigWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetJitAccessConfigResponse, error) { + rsp, err := c.V1GetJitAccessConfig(ctx, ref, reqEditors...) + if err != nil { + return nil, err + } + return ParseV1GetJitAccessConfigResponse(rsp) +} + +// V1UpdateJitAccessConfigWithBodyWithResponse request with arbitrary body returning *V1UpdateJitAccessConfigResponse +func (c *ClientWithResponses) V1UpdateJitAccessConfigWithBodyWithResponse(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*V1UpdateJitAccessConfigResponse, error) { + rsp, err := c.V1UpdateJitAccessConfigWithBody(ctx, ref, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseV1UpdateJitAccessConfigResponse(rsp) +} + +func (c *ClientWithResponses) V1UpdateJitAccessConfigWithResponse(ctx context.Context, ref string, body V1UpdateJitAccessConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*V1UpdateJitAccessConfigResponse, error) { + rsp, err := c.V1UpdateJitAccessConfig(ctx, ref, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseV1UpdateJitAccessConfigResponse(rsp) +} + // V1DeleteNetworkBansWithBodyWithResponse request with arbitrary body returning *V1DeleteNetworkBansResponse func (c *ClientWithResponses) V1DeleteNetworkBansWithBodyWithResponse(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*V1DeleteNetworkBansResponse, error) { rsp, err := c.V1DeleteNetworkBansWithBody(ctx, ref, contentType, body, reqEditors...) @@ -17915,6 +18485,74 @@ func ParseV1UpdatePostgresConfigResponse(rsp *http.Response) (*V1UpdatePostgresC return response, nil } +// ParseV1ModifyDatabaseDiskResponse parses an HTTP response from a V1ModifyDatabaseDiskWithResponse call +func ParseV1ModifyDatabaseDiskResponse(rsp *http.Response) (*V1ModifyDatabaseDiskResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &V1ModifyDatabaseDiskResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + +// ParseV1GetProjectDiskAutoscaleConfigResponse parses an HTTP response from a V1GetProjectDiskAutoscaleConfigWithResponse call +func ParseV1GetProjectDiskAutoscaleConfigResponse(rsp *http.Response) (*V1GetProjectDiskAutoscaleConfigResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &V1GetProjectDiskAutoscaleConfigResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest DiskAutoscaleConfig + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseV1GetDiskUtilizationResponse parses an HTTP response from a V1GetDiskUtilizationWithResponse call +func ParseV1GetDiskUtilizationResponse(rsp *http.Response) (*V1GetDiskUtilizationResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &V1GetDiskUtilizationResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest DiskUtilMetricsResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + // ParseV1GetRealtimeConfigResponse parses an HTTP response from a V1GetRealtimeConfigWithResponse call func ParseV1GetRealtimeConfigResponse(rsp *http.Response) (*V1GetRealtimeConfigResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) @@ -17957,6 +18595,22 @@ func ParseV1UpdateRealtimeConfigResponse(rsp *http.Response) (*V1UpdateRealtimeC return response, nil } +// ParseV1ShutdownRealtimeResponse parses an HTTP response from a V1ShutdownRealtimeWithResponse call +func ParseV1ShutdownRealtimeResponse(rsp *http.Response) (*V1ShutdownRealtimeResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &V1ShutdownRealtimeResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + return response, nil +} + // ParseV1GetStorageConfigResponse parses an HTTP response from a V1GetStorageConfigWithResponse call func ParseV1GetStorageConfigResponse(rsp *http.Response) (*V1GetStorageConfigResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) @@ -18789,6 +19443,58 @@ func ParseV1GetServicesHealthResponse(rsp *http.Response) (*V1GetServicesHealthR return response, nil } +// ParseV1GetJitAccessConfigResponse parses an HTTP response from a V1GetJitAccessConfigWithResponse call +func ParseV1GetJitAccessConfigResponse(rsp *http.Response) (*V1GetJitAccessConfigResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &V1GetJitAccessConfigResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest JitAccessResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseV1UpdateJitAccessConfigResponse parses an HTTP response from a V1UpdateJitAccessConfigWithResponse call +func ParseV1UpdateJitAccessConfigResponse(rsp *http.Response) (*V1UpdateJitAccessConfigResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &V1UpdateJitAccessConfigResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest JitAccessResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + // ParseV1DeleteNetworkBansResponse parses an HTTP response from a V1DeleteNetworkBansWithResponse call func ParseV1DeleteNetworkBansResponse(rsp *http.Response) (*V1DeleteNetworkBansResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) diff --git a/pkg/api/types.gen.go b/pkg/api/types.gen.go index 65079455c9..859b509727 100644 --- a/pkg/api/types.gen.go +++ b/pkg/api/types.gen.go @@ -437,6 +437,16 @@ const ( DeployFunctionResponseStatusTHROTTLED DeployFunctionResponseStatus = "THROTTLED" ) +// Defines values for DiskRequestBodyAttributes0Type. +const ( + DiskRequestBodyAttributes0TypeGp3 DiskRequestBodyAttributes0Type = "gp3" +) + +// Defines values for DiskRequestBodyAttributes1Type. +const ( + Io2 DiskRequestBodyAttributes1Type = "io2" +) + // Defines values for FunctionResponseStatus. const ( FunctionResponseStatusACTIVE FunctionResponseStatus = "ACTIVE" @@ -470,6 +480,13 @@ const ( GetProjectAvailableRestoreVersionsResponseAvailableVersionsReleaseChannelWithdrawn GetProjectAvailableRestoreVersionsResponseAvailableVersionsReleaseChannel = "withdrawn" ) +// Defines values for JitAccessRequestRequestState. +const ( + Disabled JitAccessRequestRequestState = "disabled" + Enabled JitAccessRequestRequestState = "enabled" + Unavailable JitAccessRequestRequestState = "unavailable" +) + // Defines values for ListActionRunResponseRunStepsName. const ( ListActionRunResponseRunStepsNameClone ListActionRunResponseRunStepsName = "clone" @@ -713,8 +730,8 @@ const ( // Defines values for OrganizationProjectsResponseProjectsDatabasesDiskType. const ( - Gp3 OrganizationProjectsResponseProjectsDatabasesDiskType = "gp3" - Io2 OrganizationProjectsResponseProjectsDatabasesDiskType = "io2" + OrganizationProjectsResponseProjectsDatabasesDiskTypeGp3 OrganizationProjectsResponseProjectsDatabasesDiskType = "gp3" + OrganizationProjectsResponseProjectsDatabasesDiskTypeIo2 OrganizationProjectsResponseProjectsDatabasesDiskType = "io2" ) // Defines values for OrganizationProjectsResponseProjectsDatabasesInfraComputeSize. @@ -876,6 +893,28 @@ const ( RegionsInfoAllSmartGroupTypeSmartGroup RegionsInfoAllSmartGroupType = "smartGroup" ) +// Defines values for RegionsInfoAllSpecificCode. +const ( + RegionsInfoAllSpecificCodeApEast1 RegionsInfoAllSpecificCode = "ap-east-1" + RegionsInfoAllSpecificCodeApNortheast1 RegionsInfoAllSpecificCode = "ap-northeast-1" + RegionsInfoAllSpecificCodeApNortheast2 RegionsInfoAllSpecificCode = "ap-northeast-2" + RegionsInfoAllSpecificCodeApSouth1 RegionsInfoAllSpecificCode = "ap-south-1" + RegionsInfoAllSpecificCodeApSoutheast1 RegionsInfoAllSpecificCode = "ap-southeast-1" + RegionsInfoAllSpecificCodeApSoutheast2 RegionsInfoAllSpecificCode = "ap-southeast-2" + RegionsInfoAllSpecificCodeCaCentral1 RegionsInfoAllSpecificCode = "ca-central-1" + RegionsInfoAllSpecificCodeEuCentral1 RegionsInfoAllSpecificCode = "eu-central-1" + RegionsInfoAllSpecificCodeEuCentral2 RegionsInfoAllSpecificCode = "eu-central-2" + RegionsInfoAllSpecificCodeEuNorth1 RegionsInfoAllSpecificCode = "eu-north-1" + RegionsInfoAllSpecificCodeEuWest1 RegionsInfoAllSpecificCode = "eu-west-1" + RegionsInfoAllSpecificCodeEuWest2 RegionsInfoAllSpecificCode = "eu-west-2" + RegionsInfoAllSpecificCodeEuWest3 RegionsInfoAllSpecificCode = "eu-west-3" + RegionsInfoAllSpecificCodeSaEast1 RegionsInfoAllSpecificCode = "sa-east-1" + RegionsInfoAllSpecificCodeUsEast1 RegionsInfoAllSpecificCode = "us-east-1" + RegionsInfoAllSpecificCodeUsEast2 RegionsInfoAllSpecificCode = "us-east-2" + RegionsInfoAllSpecificCodeUsWest1 RegionsInfoAllSpecificCode = "us-west-1" + RegionsInfoAllSpecificCodeUsWest2 RegionsInfoAllSpecificCode = "us-west-2" +) + // Defines values for RegionsInfoAllSpecificProvider. const ( RegionsInfoAllSpecificProviderAWS RegionsInfoAllSpecificProvider = "AWS" @@ -907,6 +946,28 @@ const ( RegionsInfoRecommendationsSmartGroupTypeSmartGroup RegionsInfoRecommendationsSmartGroupType = "smartGroup" ) +// Defines values for RegionsInfoRecommendationsSpecificCode. +const ( + RegionsInfoRecommendationsSpecificCodeApEast1 RegionsInfoRecommendationsSpecificCode = "ap-east-1" + RegionsInfoRecommendationsSpecificCodeApNortheast1 RegionsInfoRecommendationsSpecificCode = "ap-northeast-1" + RegionsInfoRecommendationsSpecificCodeApNortheast2 RegionsInfoRecommendationsSpecificCode = "ap-northeast-2" + RegionsInfoRecommendationsSpecificCodeApSouth1 RegionsInfoRecommendationsSpecificCode = "ap-south-1" + RegionsInfoRecommendationsSpecificCodeApSoutheast1 RegionsInfoRecommendationsSpecificCode = "ap-southeast-1" + RegionsInfoRecommendationsSpecificCodeApSoutheast2 RegionsInfoRecommendationsSpecificCode = "ap-southeast-2" + RegionsInfoRecommendationsSpecificCodeCaCentral1 RegionsInfoRecommendationsSpecificCode = "ca-central-1" + RegionsInfoRecommendationsSpecificCodeEuCentral1 RegionsInfoRecommendationsSpecificCode = "eu-central-1" + RegionsInfoRecommendationsSpecificCodeEuCentral2 RegionsInfoRecommendationsSpecificCode = "eu-central-2" + RegionsInfoRecommendationsSpecificCodeEuNorth1 RegionsInfoRecommendationsSpecificCode = "eu-north-1" + RegionsInfoRecommendationsSpecificCodeEuWest1 RegionsInfoRecommendationsSpecificCode = "eu-west-1" + RegionsInfoRecommendationsSpecificCodeEuWest2 RegionsInfoRecommendationsSpecificCode = "eu-west-2" + RegionsInfoRecommendationsSpecificCodeEuWest3 RegionsInfoRecommendationsSpecificCode = "eu-west-3" + RegionsInfoRecommendationsSpecificCodeSaEast1 RegionsInfoRecommendationsSpecificCode = "sa-east-1" + RegionsInfoRecommendationsSpecificCodeUsEast1 RegionsInfoRecommendationsSpecificCode = "us-east-1" + RegionsInfoRecommendationsSpecificCodeUsEast2 RegionsInfoRecommendationsSpecificCode = "us-east-2" + RegionsInfoRecommendationsSpecificCodeUsWest1 RegionsInfoRecommendationsSpecificCode = "us-west-1" + RegionsInfoRecommendationsSpecificCodeUsWest2 RegionsInfoRecommendationsSpecificCode = "us-west-2" +) + // Defines values for RegionsInfoRecommendationsSpecificProvider. const ( RegionsInfoRecommendationsSpecificProviderAWS RegionsInfoRecommendationsSpecificProvider = "AWS" @@ -1941,6 +2002,7 @@ type AuthConfigResponse struct { SecurityCaptchaSecret nullable.Nullable[string] `json:"security_captcha_secret"` SecurityManualLinkingEnabled nullable.Nullable[bool] `json:"security_manual_linking_enabled"` SecurityRefreshTokenReuseInterval nullable.Nullable[int] `json:"security_refresh_token_reuse_interval"` + SecuritySbForwardedForEnabled nullable.Nullable[bool] `json:"security_sb_forwarded_for_enabled"` SecurityUpdatePasswordRequireReauthentication nullable.Nullable[bool] `json:"security_update_password_require_reauthentication"` SessionsInactivityTimeout nullable.Nullable[int] `json:"sessions_inactivity_timeout"` SessionsSinglePerUser nullable.Nullable[bool] `json:"sessions_single_per_user"` @@ -2466,6 +2528,59 @@ type DeployFunctionResponse struct { // DeployFunctionResponseStatus defines model for DeployFunctionResponse.Status. type DeployFunctionResponseStatus string +// DiskAutoscaleConfig defines model for DiskAutoscaleConfig. +type DiskAutoscaleConfig struct { + // GrowthPercent Growth percentage for disk autoscaling + GrowthPercent nullable.Nullable[int] `json:"growth_percent"` + + // MaxSizeGb Maximum limit the disk size will grow to in GB + MaxSizeGb nullable.Nullable[int] `json:"max_size_gb"` + + // MinIncrementGb Minimum increment size for disk autoscaling in GB + MinIncrementGb nullable.Nullable[int] `json:"min_increment_gb"` +} + +// DiskRequestBody defines model for DiskRequestBody. +type DiskRequestBody struct { + Attributes DiskRequestBody_Attributes `json:"attributes"` +} + +// DiskRequestBodyAttributes0 defines model for . +type DiskRequestBodyAttributes0 struct { + Iops int `json:"iops"` + SizeGb int `json:"size_gb"` + ThroughputMibps *int `json:"throughput_mibps,omitempty"` + Type DiskRequestBodyAttributes0Type `json:"type"` +} + +// DiskRequestBodyAttributes0Type defines model for DiskRequestBody.Attributes.0.Type. +type DiskRequestBodyAttributes0Type string + +// DiskRequestBodyAttributes1 defines model for . +type DiskRequestBodyAttributes1 struct { + Iops int `json:"iops"` + SizeGb int `json:"size_gb"` + Type DiskRequestBodyAttributes1Type `json:"type"` +} + +// DiskRequestBodyAttributes1Type defines model for DiskRequestBody.Attributes.1.Type. +type DiskRequestBodyAttributes1Type string + +// DiskRequestBody_Attributes defines model for DiskRequestBody.Attributes. +type DiskRequestBody_Attributes struct { + union json.RawMessage +} + +// DiskUtilMetricsResponse defines model for DiskUtilMetricsResponse. +type DiskUtilMetricsResponse struct { + Metrics struct { + FsAvailBytes float32 `json:"fs_avail_bytes"` + FsSizeBytes float32 `json:"fs_size_bytes"` + FsUsedBytes float32 `json:"fs_used_bytes"` + } `json:"metrics"` + Timestamp string `json:"timestamp"` +} + // FunctionDeployBody defines model for FunctionDeployBody. type FunctionDeployBody struct { File *[]openapi_types.File `json:"file,omitempty"` @@ -2577,6 +2692,14 @@ type GetProviderResponse struct { UpdatedAt *string `json:"updated_at,omitempty"` } +// JitAccessRequestRequest defines model for JitAccessRequestRequest. +type JitAccessRequestRequest struct { + State JitAccessRequestRequestState `json:"state"` +} + +// JitAccessRequestRequestState defines model for JitAccessRequestRequest.State. +type JitAccessRequestRequestState string + // JitAccessResponse defines model for JitAccessResponse. type JitAccessResponse struct { UserId openapi_types.UUID `json:"user_id"` @@ -3265,7 +3388,7 @@ type RegionsInfo struct { Type RegionsInfoAllSmartGroupType `json:"type"` } `json:"smartGroup"` Specific []struct { - Code string `json:"code"` + Code RegionsInfoAllSpecificCode `json:"code"` Name string `json:"name"` Provider RegionsInfoAllSpecificProvider `json:"provider"` Status *RegionsInfoAllSpecificStatus `json:"status,omitempty"` @@ -3279,7 +3402,7 @@ type RegionsInfo struct { Type RegionsInfoRecommendationsSmartGroupType `json:"type"` } `json:"smartGroup"` Specific []struct { - Code string `json:"code"` + Code RegionsInfoRecommendationsSpecificCode `json:"code"` Name string `json:"name"` Provider RegionsInfoRecommendationsSpecificProvider `json:"provider"` Status *RegionsInfoRecommendationsSpecificStatus `json:"status,omitempty"` @@ -3294,6 +3417,9 @@ type RegionsInfoAllSmartGroupCode string // RegionsInfoAllSmartGroupType defines model for RegionsInfo.All.SmartGroup.Type. type RegionsInfoAllSmartGroupType string +// RegionsInfoAllSpecificCode defines model for RegionsInfo.All.Specific.Code. +type RegionsInfoAllSpecificCode string + // RegionsInfoAllSpecificProvider defines model for RegionsInfo.All.Specific.Provider. type RegionsInfoAllSpecificProvider string @@ -3309,6 +3435,9 @@ type RegionsInfoRecommendationsSmartGroupCode string // RegionsInfoRecommendationsSmartGroupType defines model for RegionsInfo.Recommendations.SmartGroup.Type. type RegionsInfoRecommendationsSmartGroupType string +// RegionsInfoRecommendationsSpecificCode defines model for RegionsInfo.Recommendations.Specific.Code. +type RegionsInfoRecommendationsSpecificCode string + // RegionsInfoRecommendationsSpecificProvider defines model for RegionsInfo.Recommendations.Specific.Provider. type RegionsInfoRecommendationsSpecificProvider string @@ -3753,6 +3882,7 @@ type UpdateAuthConfigBody struct { SecurityCaptchaSecret nullable.Nullable[string] `json:"security_captcha_secret,omitempty"` SecurityManualLinkingEnabled nullable.Nullable[bool] `json:"security_manual_linking_enabled,omitempty"` SecurityRefreshTokenReuseInterval nullable.Nullable[int] `json:"security_refresh_token_reuse_interval,omitempty"` + SecuritySbForwardedForEnabled nullable.Nullable[bool] `json:"security_sb_forwarded_for_enabled,omitempty"` SecurityUpdatePasswordRequireReauthentication nullable.Nullable[bool] `json:"security_update_password_require_reauthentication,omitempty"` SessionsInactivityTimeout nullable.Nullable[int] `json:"sessions_inactivity_timeout,omitempty"` SessionsSinglePerUser nullable.Nullable[bool] `json:"sessions_single_per_user,omitempty"` @@ -4984,6 +5114,9 @@ type V1UpdatePoolerConfigJSONRequestBody = UpdateSupavisorConfigBody // V1UpdatePostgresConfigJSONRequestBody defines body for V1UpdatePostgresConfig for application/json ContentType. type V1UpdatePostgresConfigJSONRequestBody = UpdatePostgresConfigBody +// V1ModifyDatabaseDiskJSONRequestBody defines body for V1ModifyDatabaseDisk for application/json ContentType. +type V1ModifyDatabaseDiskJSONRequestBody = DiskRequestBody + // V1UpdateRealtimeConfigJSONRequestBody defines body for V1UpdateRealtimeConfig for application/json ContentType. type V1UpdateRealtimeConfigJSONRequestBody = UpdateRealtimeConfigBody @@ -5038,6 +5171,9 @@ type V1DeployAFunctionMultipartRequestBody = FunctionDeployBody // V1UpdateAFunctionJSONRequestBody defines body for V1UpdateAFunction for application/json ContentType. type V1UpdateAFunctionJSONRequestBody = V1UpdateFunctionBody +// V1UpdateJitAccessConfigJSONRequestBody defines body for V1UpdateJitAccessConfig for application/json ContentType. +type V1UpdateJitAccessConfigJSONRequestBody = JitAccessRequestRequest + // V1DeleteNetworkBansJSONRequestBody defines body for V1DeleteNetworkBans for application/json ContentType. type V1DeleteNetworkBansJSONRequestBody = RemoveNetworkBanRequest @@ -5512,6 +5648,68 @@ func (t *CreateSigningKeyBody_PrivateJwk) UnmarshalJSON(b []byte) error { return err } +// AsDiskRequestBodyAttributes0 returns the union data inside the DiskRequestBody_Attributes as a DiskRequestBodyAttributes0 +func (t DiskRequestBody_Attributes) AsDiskRequestBodyAttributes0() (DiskRequestBodyAttributes0, error) { + var body DiskRequestBodyAttributes0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromDiskRequestBodyAttributes0 overwrites any union data inside the DiskRequestBody_Attributes as the provided DiskRequestBodyAttributes0 +func (t *DiskRequestBody_Attributes) FromDiskRequestBodyAttributes0(v DiskRequestBodyAttributes0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeDiskRequestBodyAttributes0 performs a merge with any union data inside the DiskRequestBody_Attributes, using the provided DiskRequestBodyAttributes0 +func (t *DiskRequestBody_Attributes) MergeDiskRequestBodyAttributes0(v DiskRequestBodyAttributes0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsDiskRequestBodyAttributes1 returns the union data inside the DiskRequestBody_Attributes as a DiskRequestBodyAttributes1 +func (t DiskRequestBody_Attributes) AsDiskRequestBodyAttributes1() (DiskRequestBodyAttributes1, error) { + var body DiskRequestBodyAttributes1 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromDiskRequestBodyAttributes1 overwrites any union data inside the DiskRequestBody_Attributes as the provided DiskRequestBodyAttributes1 +func (t *DiskRequestBody_Attributes) FromDiskRequestBodyAttributes1(v DiskRequestBodyAttributes1) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeDiskRequestBodyAttributes1 performs a merge with any union data inside the DiskRequestBody_Attributes, using the provided DiskRequestBodyAttributes1 +func (t *DiskRequestBody_Attributes) MergeDiskRequestBodyAttributes1(v DiskRequestBodyAttributes1) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t DiskRequestBody_Attributes) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *DiskRequestBody_Attributes) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + // AsListProjectAddonsResponseAvailableAddonsVariantsId0 returns the union data inside the ListProjectAddonsResponse_AvailableAddons_Variants_Id as a ListProjectAddonsResponseAvailableAddonsVariantsId0 func (t ListProjectAddonsResponse_AvailableAddons_Variants_Id) AsListProjectAddonsResponseAvailableAddonsVariantsId0() (ListProjectAddonsResponseAvailableAddonsVariantsId0, error) { var body ListProjectAddonsResponseAvailableAddonsVariantsId0 From 50781a406303eb5b5b4ed99857ba1febb9ced437 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Feb 2026 00:09:43 +0000 Subject: [PATCH 065/117] chore(deps): bump tar from 7.5.7 to 7.5.9 in the npm-major group (#4864) Bumps the npm-major group with 1 update: [tar](https://github.com/isaacs/node-tar). Updates `tar` from 7.5.7 to 7.5.9 - [Release notes](https://github.com/isaacs/node-tar/releases) - [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md) - [Commits](https://github.com/isaacs/node-tar/compare/v7.5.7...v7.5.9) --- updated-dependencies: - dependency-name: tar dependency-version: 7.5.9 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: npm-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b89b2bfd98..0a51561953 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "bin-links": "^6.0.0", "https-proxy-agent": "^7.0.2", "node-fetch": "^3.3.2", - "tar": "7.5.7" + "tar": "7.5.9" }, "release": { "branches": [ From c7dc5cdc64f037cf1b72d19df5c00a0810eb4038 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Feb 2026 11:48:57 +0000 Subject: [PATCH 066/117] fix(docker): bump the docker-minor group across 1 directory with 3 updates (#4865) Bumps the docker-minor group with 3 updates in the /pkg/config/templates directory: postgrest/postgrest, supabase/studio and supabase/storage-api. Updates `postgrest/postgrest` from v14.4 to v14.5 Updates `supabase/studio` from 2026.02.09-sha-18cc6f8 to 2026.02.16-sha-26c615c Updates `supabase/storage-api` from v1.37.7 to v1.37.8 --- updated-dependencies: - dependency-name: postgrest/postgrest dependency-version: v14.5 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/studio dependency-version: 2026.02.16-sha-26c615c dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/storage-api dependency-version: v1.37.8 dependency-type: direct:production dependency-group: docker-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andrew Valleteau --- pkg/config/templates/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index a70827e50b..ffadb77236 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -3,16 +3,16 @@ FROM supabase/postgres:17.6.1.084 AS pg # 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 postgrest/postgrest:v14.4 AS postgrest +FROM postgrest/postgrest:v14.5 AS postgrest FROM supabase/postgres-meta:v0.95.2 AS pgmeta -FROM supabase/studio:2026.02.09-sha-18cc6f8 AS studio +FROM supabase/studio:2026.02.16-sha-26c615c AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy FROM supabase/edge-runtime:v1.70.3 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.186.0 AS gotrue FROM supabase/realtime:v2.76.5 AS realtime -FROM supabase/storage-api:v1.37.7 AS storage +FROM supabase/storage-api:v1.37.8 AS storage FROM supabase/logflare:1.31.2 AS logflare # Append to JobImages when adding new dependencies below FROM supabase/pgadmin-schema-diff:cli-0.0.5 AS differ From 54c41b8477f286c0d83d3d6bec4700547b2436f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 14:51:10 +0100 Subject: [PATCH 067/117] chore(deps): bump github.com/charmbracelet/bubbles from 0.21.1 to 1.0.0 (#4856) * chore(deps): bump github.com/charmbracelet/bubbles from 0.21.1 to 1.0.0 Bumps [github.com/charmbracelet/bubbles](https://github.com/charmbracelet/bubbles) from 0.21.1 to 1.0.0. - [Release notes](https://github.com/charmbracelet/bubbles/releases) - [Commits](https://github.com/charmbracelet/bubbles/compare/v0.21.1...v1.0.0) --- updated-dependencies: - dependency-name: github.com/charmbracelet/bubbles dependency-version: 1.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * chore: fix gosec on non-touched code (#4868) * fix(ci): only fail lint on issues in changed code Add only-new-issues: true to golangci-lint action so pre-existing gosec warnings in untouched files don't fail PR checks. New code is still fully checked by all rules including G101, G115, G117, G704, and G705. --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andrew Valleteau --- .github/workflows/ci.yml | 1 + go.mod | 4 ++-- go.sum | 8 ++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a8fa08a7de..3f8d28368e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,6 +63,7 @@ jobs: with: args: --timeout 3m --verbose version: latest + only-new-issues: true start: name: Start diff --git a/go.mod b/go.mod index 7ea4ed212e..01fc5c7eaf 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/Netflix/go-env v0.1.2 github.com/andybalholm/brotli v1.2.0 github.com/cenkalti/backoff/v4 v4.3.0 - github.com/charmbracelet/bubbles v0.21.1 + github.com/charmbracelet/bubbles v1.0.0 github.com/charmbracelet/bubbletea v1.3.10 github.com/charmbracelet/glamour v0.10.0 github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 @@ -124,7 +124,7 @@ require ( github.com/charithe/durationcheck v0.0.10 // indirect github.com/charmbracelet/colorprofile v0.4.1 // indirect github.com/charmbracelet/harmonica v0.2.0 // indirect - github.com/charmbracelet/x/ansi v0.11.5 // indirect + github.com/charmbracelet/x/ansi v0.11.6 // indirect github.com/charmbracelet/x/cellbuf v0.0.15 // indirect github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf // indirect github.com/charmbracelet/x/term v0.2.2 // indirect diff --git a/go.sum b/go.sum index 4c759e1f47..8344412943 100644 --- a/go.sum +++ b/go.sum @@ -161,8 +161,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charithe/durationcheck v0.0.10 h1:wgw73BiocdBDQPik+zcEoBG/ob8uyBHf2iyoHGPf5w4= github.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ= -github.com/charmbracelet/bubbles v0.21.1 h1:nj0decPiixaZeL9diI4uzzQTkkz1kYY8+jgzCZXSmW0= -github.com/charmbracelet/bubbles v0.21.1/go.mod h1:HHvIYRCpbkCJw2yo0vNX1O5loCwSr9/mWS8GYSg50Sk= +github.com/charmbracelet/bubbles v1.0.0 h1:12J8/ak/uCZEMQ6KU7pcfwceyjLlWsDLAxB5fXonfvc= +github.com/charmbracelet/bubbles v1.0.0/go.mod h1:9d/Zd5GdnauMI5ivUIVisuEm3ave1XwXtD1ckyV6r3E= github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk= @@ -173,8 +173,8 @@ github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 h1:ZR7e0ro+SZZiIZD7msJyA+NjkCNNavuiPBLgerbOziE= github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834/go.mod h1:aKC/t2arECF6rNOnaKaVU6y4t4ZeHQzqfxedE/VkVhA= -github.com/charmbracelet/x/ansi v0.11.5 h1:NBWeBpj/lJPE3Q5l+Lusa4+mH6v7487OP8K0r1IhRg4= -github.com/charmbracelet/x/ansi v0.11.5/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ= +github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8= +github.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ= github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI= github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q= github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ= From e71302cbdf836032e0fa4dae1bfbbd106f13972b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cemal=20K=C4=B1l=C4=B1=C3=A7?= Date: Thu, 19 Feb 2026 20:37:14 +0800 Subject: [PATCH 068/117] fix(auth): pass GOTRUE_JWT_VALID_METHODS env var for GoTrue compat (#4874) fix(auth): pass GOTRUE_JWT_VALID_METHODS env var for GoTrue compatibility --- internal/start/start.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/start/start.go b/internal/start/start.go index dd9ca740fe..5a5cec56c6 100644 --- a/internal/start/start.go +++ b/internal/start/start.go @@ -627,7 +627,9 @@ EOF if keys, err := json.Marshal(utils.Config.Auth.SigningKeys); err == nil { env = append(env, "GOTRUE_JWT_KEYS="+string(keys)) // TODO: deprecate HS256 when it's no longer supported + // TODO: remove VALIDMETHODS after a while to avoid breaking changes env = append(env, "GOTRUE_JWT_VALIDMETHODS=HS256,RS256,ES256") + env = append(env, "GOTRUE_JWT_VALID_METHODS=HS256,RS256,ES256") } if utils.Config.Auth.Email.Smtp != nil && utils.Config.Auth.Email.Smtp.Enabled { From 8ff0c28c4dcc47a4ad66f9f971329087461c38b1 Mon Sep 17 00:00:00 2001 From: "supabase-cli-releaser[bot]" <246109035+supabase-cli-releaser[bot]@users.noreply.github.com> Date: Thu, 19 Feb 2026 18:05:47 +0100 Subject: [PATCH 069/117] chore: sync API types from infrastructure (#4875) Co-authored-by: supabase-cli-releaser[bot] <246109035+supabase-cli-releaser[bot]@users.noreply.github.com> --- pkg/api/types.gen.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/api/types.gen.go b/pkg/api/types.gen.go index 859b509727..330fc5de86 100644 --- a/pkg/api/types.gen.go +++ b/pkg/api/types.gen.go @@ -4678,7 +4678,8 @@ type V1ServiceHealthResponseInfo1 struct { // Healthy Deprecated. Use `status` instead. // Deprecated: - Healthy bool `json:"healthy"` + Healthy bool `json:"healthy"` + ReplicationConnected bool `json:"replication_connected"` } // V1ServiceHealthResponseInfo2 defines model for . From b3402fd8f5a350bb1091f59ea82457f082f004f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 00:14:51 +0000 Subject: [PATCH 070/117] fix(docker): bump the docker-minor group across 1 directory with 3 updates (#4870) Bumps the docker-minor group with 3 updates in the /pkg/config/templates directory: supabase/realtime, supabase/storage-api and supabase/logflare. Updates `supabase/realtime` from v2.76.5 to v2.76.6 Updates `supabase/storage-api` from v1.37.8 to v1.37.9 Updates `supabase/logflare` from 1.31.2 to 1.32.2 --- updated-dependencies: - dependency-name: supabase/realtime dependency-version: v2.76.6 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/storage-api dependency-version: v1.37.9 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/logflare dependency-version: 1.32.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: docker-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index ffadb77236..48c944bd47 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -11,9 +11,9 @@ FROM supabase/edge-runtime:v1.70.3 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.186.0 AS gotrue -FROM supabase/realtime:v2.76.5 AS realtime -FROM supabase/storage-api:v1.37.8 AS storage -FROM supabase/logflare:1.31.2 AS logflare +FROM supabase/realtime:v2.76.7 AS realtime +FROM supabase/storage-api:v1.37.11 AS storage +FROM supabase/logflare:1.32.3 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 4e71cef3dda19c1774daccff5af38bd196532592 Mon Sep 17 00:00:00 2001 From: "supabase-cli-releaser[bot]" <246109035+supabase-cli-releaser[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 16:23:09 +0100 Subject: [PATCH 071/117] chore: sync API types from infrastructure (#4878) Co-authored-by: supabase-cli-releaser[bot] <246109035+supabase-cli-releaser[bot]@users.noreply.github.com> --- pkg/api/client.gen.go | 109 +++++++++++++++++++++++++++++++++++++++++ pkg/api/types.gen.go | 110 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 216 insertions(+), 3 deletions(-) diff --git a/pkg/api/client.gen.go b/pkg/api/client.gen.go index 65f2febd28..ff2504973f 100644 --- a/pkg/api/client.gen.go +++ b/pkg/api/client.gen.go @@ -372,6 +372,9 @@ type ClientInterface interface { V1UpdatePostgresConfig(ctx context.Context, ref string, body V1UpdatePostgresConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // V1GetDatabaseDisk request + V1GetDatabaseDisk(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) + // V1ModifyDatabaseDiskWithBody request with any body V1ModifyDatabaseDiskWithBody(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -1888,6 +1891,18 @@ func (c *Client) V1UpdatePostgresConfig(ctx context.Context, ref string, body V1 return c.Client.Do(req) } +func (c *Client) V1GetDatabaseDisk(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewV1GetDatabaseDiskRequest(c.Server, ref) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + func (c *Client) V1ModifyDatabaseDiskWithBody(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewV1ModifyDatabaseDiskRequestWithBody(c.Server, ref, contentType, body) if err != nil { @@ -7014,6 +7029,40 @@ func NewV1UpdatePostgresConfigRequestWithBody(server string, ref string, content return req, nil } +// NewV1GetDatabaseDiskRequest generates requests for V1GetDatabaseDisk +func NewV1GetDatabaseDiskRequest(server string, ref string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "ref", runtime.ParamLocationPath, ref) + if err != nil { + return nil, err + } + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/v1/projects/%s/config/disk", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", queryURL.String(), nil) + if err != nil { + return nil, err + } + + return req, nil +} + // NewV1ModifyDatabaseDiskRequest calls the generic V1ModifyDatabaseDisk builder with application/json body func NewV1ModifyDatabaseDiskRequest(server string, ref string, body V1ModifyDatabaseDiskJSONRequestBody) (*http.Request, error) { var bodyReader io.Reader @@ -10993,6 +11042,9 @@ type ClientWithResponsesInterface interface { V1UpdatePostgresConfigWithResponse(ctx context.Context, ref string, body V1UpdatePostgresConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*V1UpdatePostgresConfigResponse, error) + // V1GetDatabaseDiskWithResponse request + V1GetDatabaseDiskWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetDatabaseDiskResponse, error) + // V1ModifyDatabaseDiskWithBodyWithResponse request with any body V1ModifyDatabaseDiskWithBodyWithResponse(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*V1ModifyDatabaseDiskResponse, error) @@ -13000,6 +13052,28 @@ func (r V1UpdatePostgresConfigResponse) StatusCode() int { return 0 } +type V1GetDatabaseDiskResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *DiskResponse +} + +// Status returns HTTPResponse.Status +func (r V1GetDatabaseDiskResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r V1GetDatabaseDiskResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type V1ModifyDatabaseDiskResponse struct { Body []byte HTTPResponse *http.Response @@ -15600,6 +15674,15 @@ func (c *ClientWithResponses) V1UpdatePostgresConfigWithResponse(ctx context.Con return ParseV1UpdatePostgresConfigResponse(rsp) } +// V1GetDatabaseDiskWithResponse request returning *V1GetDatabaseDiskResponse +func (c *ClientWithResponses) V1GetDatabaseDiskWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetDatabaseDiskResponse, error) { + rsp, err := c.V1GetDatabaseDisk(ctx, ref, reqEditors...) + if err != nil { + return nil, err + } + return ParseV1GetDatabaseDiskResponse(rsp) +} + // V1ModifyDatabaseDiskWithBodyWithResponse request with arbitrary body returning *V1ModifyDatabaseDiskResponse func (c *ClientWithResponses) V1ModifyDatabaseDiskWithBodyWithResponse(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*V1ModifyDatabaseDiskResponse, error) { rsp, err := c.V1ModifyDatabaseDiskWithBody(ctx, ref, contentType, body, reqEditors...) @@ -18485,6 +18568,32 @@ func ParseV1UpdatePostgresConfigResponse(rsp *http.Response) (*V1UpdatePostgresC return response, nil } +// ParseV1GetDatabaseDiskResponse parses an HTTP response from a V1GetDatabaseDiskWithResponse call +func ParseV1GetDatabaseDiskResponse(rsp *http.Response) (*V1GetDatabaseDiskResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &V1GetDatabaseDiskResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest DiskResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + // ParseV1ModifyDatabaseDiskResponse parses an HTTP response from a V1ModifyDatabaseDiskWithResponse call func ParseV1ModifyDatabaseDiskResponse(rsp *http.Response) (*V1ModifyDatabaseDiskResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) diff --git a/pkg/api/types.gen.go b/pkg/api/types.gen.go index 330fc5de86..aeaa350b76 100644 --- a/pkg/api/types.gen.go +++ b/pkg/api/types.gen.go @@ -444,7 +444,17 @@ const ( // Defines values for DiskRequestBodyAttributes1Type. const ( - Io2 DiskRequestBodyAttributes1Type = "io2" + DiskRequestBodyAttributes1TypeIo2 DiskRequestBodyAttributes1Type = "io2" +) + +// Defines values for DiskResponseAttributes0Type. +const ( + DiskResponseAttributes0TypeGp3 DiskResponseAttributes0Type = "gp3" +) + +// Defines values for DiskResponseAttributes1Type. +const ( + DiskResponseAttributes1TypeIo2 DiskResponseAttributes1Type = "io2" ) // Defines values for FunctionResponseStatus. @@ -730,8 +740,8 @@ const ( // Defines values for OrganizationProjectsResponseProjectsDatabasesDiskType. const ( - OrganizationProjectsResponseProjectsDatabasesDiskTypeGp3 OrganizationProjectsResponseProjectsDatabasesDiskType = "gp3" - OrganizationProjectsResponseProjectsDatabasesDiskTypeIo2 OrganizationProjectsResponseProjectsDatabasesDiskType = "io2" + Gp3 OrganizationProjectsResponseProjectsDatabasesDiskType = "gp3" + Io2 OrganizationProjectsResponseProjectsDatabasesDiskType = "io2" ) // Defines values for OrganizationProjectsResponseProjectsDatabasesInfraComputeSize. @@ -2571,6 +2581,38 @@ type DiskRequestBody_Attributes struct { union json.RawMessage } +// DiskResponse defines model for DiskResponse. +type DiskResponse struct { + Attributes DiskResponse_Attributes `json:"attributes"` + LastModifiedAt *string `json:"last_modified_at,omitempty"` +} + +// DiskResponseAttributes0 defines model for . +type DiskResponseAttributes0 struct { + Iops int `json:"iops"` + SizeGb int `json:"size_gb"` + ThroughputMibps *int `json:"throughput_mibps,omitempty"` + Type DiskResponseAttributes0Type `json:"type"` +} + +// DiskResponseAttributes0Type defines model for DiskResponse.Attributes.0.Type. +type DiskResponseAttributes0Type string + +// DiskResponseAttributes1 defines model for . +type DiskResponseAttributes1 struct { + Iops int `json:"iops"` + SizeGb int `json:"size_gb"` + Type DiskResponseAttributes1Type `json:"type"` +} + +// DiskResponseAttributes1Type defines model for DiskResponse.Attributes.1.Type. +type DiskResponseAttributes1Type string + +// DiskResponse_Attributes defines model for DiskResponse.Attributes. +type DiskResponse_Attributes struct { + union json.RawMessage +} + // DiskUtilMetricsResponse defines model for DiskUtilMetricsResponse. type DiskUtilMetricsResponse struct { Metrics struct { @@ -5711,6 +5753,68 @@ func (t *DiskRequestBody_Attributes) UnmarshalJSON(b []byte) error { return err } +// AsDiskResponseAttributes0 returns the union data inside the DiskResponse_Attributes as a DiskResponseAttributes0 +func (t DiskResponse_Attributes) AsDiskResponseAttributes0() (DiskResponseAttributes0, error) { + var body DiskResponseAttributes0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromDiskResponseAttributes0 overwrites any union data inside the DiskResponse_Attributes as the provided DiskResponseAttributes0 +func (t *DiskResponse_Attributes) FromDiskResponseAttributes0(v DiskResponseAttributes0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeDiskResponseAttributes0 performs a merge with any union data inside the DiskResponse_Attributes, using the provided DiskResponseAttributes0 +func (t *DiskResponse_Attributes) MergeDiskResponseAttributes0(v DiskResponseAttributes0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsDiskResponseAttributes1 returns the union data inside the DiskResponse_Attributes as a DiskResponseAttributes1 +func (t DiskResponse_Attributes) AsDiskResponseAttributes1() (DiskResponseAttributes1, error) { + var body DiskResponseAttributes1 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromDiskResponseAttributes1 overwrites any union data inside the DiskResponse_Attributes as the provided DiskResponseAttributes1 +func (t *DiskResponse_Attributes) FromDiskResponseAttributes1(v DiskResponseAttributes1) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeDiskResponseAttributes1 performs a merge with any union data inside the DiskResponse_Attributes, using the provided DiskResponseAttributes1 +func (t *DiskResponse_Attributes) MergeDiskResponseAttributes1(v DiskResponseAttributes1) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t DiskResponse_Attributes) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *DiskResponse_Attributes) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + // AsListProjectAddonsResponseAvailableAddonsVariantsId0 returns the union data inside the ListProjectAddonsResponse_AvailableAddons_Variants_Id as a ListProjectAddonsResponseAvailableAddonsVariantsId0 func (t ListProjectAddonsResponse_AvailableAddons_Variants_Id) AsListProjectAddonsResponseAvailableAddonsVariantsId0() (ListProjectAddonsResponseAvailableAddonsVariantsId0, error) { var body ListProjectAddonsResponseAvailableAddonsVariantsId0 From f770c79656da8556f5c159da4b81a2ad4e5533e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 21 Feb 2026 00:07:24 +0000 Subject: [PATCH 072/117] fix(docker): bump supabase/postgres from 17.6.1.084 to 17.6.1.087 in /pkg/config/templates (#4881) fix(docker): bump supabase/postgres in /pkg/config/templates Bumps supabase/postgres from 17.6.1.084 to 17.6.1.087. --- updated-dependencies: - dependency-name: supabase/postgres dependency-version: 17.6.1.087 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 48c944bd47..d2c4c3b70e 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:17.6.1.084 AS pg +FROM supabase/postgres:17.6.1.087 AS pg # 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 562fced0f720933372d8c9073a5990be21e94823 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 21 Feb 2026 00:12:59 +0000 Subject: [PATCH 073/117] fix(docker): bump the docker-minor group in /pkg/config/templates with 2 updates (#4880) fix(docker): bump the docker-minor group Bumps the docker-minor group in /pkg/config/templates with 2 updates: supabase/realtime and supabase/storage-api. Updates `supabase/realtime` from v2.76.7 to v2.77.0 Updates `supabase/storage-api` from v1.37.11 to v1.38.0 --- updated-dependencies: - dependency-name: supabase/realtime dependency-version: v2.77.0 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/storage-api dependency-version: v1.38.0 dependency-type: direct:production dependency-group: docker-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index d2c4c3b70e..9343f8b400 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -11,8 +11,8 @@ FROM supabase/edge-runtime:v1.70.3 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.186.0 AS gotrue -FROM supabase/realtime:v2.76.7 AS realtime -FROM supabase/storage-api:v1.37.11 AS storage +FROM supabase/realtime:v2.77.0 AS realtime +FROM supabase/storage-api:v1.38.0 AS storage FROM supabase/logflare:1.32.3 AS logflare # Append to JobImages when adding new dependencies below FROM supabase/pgadmin-schema-diff:cli-0.0.5 AS differ From 841c9f1e94419360fce91e4fcf259e4c2ba99933 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 22 Feb 2026 00:07:37 +0000 Subject: [PATCH 074/117] fix(docker): bump supabase/logflare from 1.32.3 to 1.32.5 in /pkg/config/templates in the docker-minor group (#4882) fix(docker): bump supabase/logflare Bumps the docker-minor group in /pkg/config/templates with 1 update: supabase/logflare. Updates `supabase/logflare` from 1.32.3 to 1.32.5 --- updated-dependencies: - dependency-name: supabase/logflare dependency-version: 1.32.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: docker-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 9343f8b400..445ff4b25a 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -13,7 +13,7 @@ FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.186.0 AS gotrue FROM supabase/realtime:v2.77.0 AS realtime FROM supabase/storage-api:v1.38.0 AS storage -FROM supabase/logflare:1.32.3 AS logflare +FROM supabase/logflare:1.32.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 7853c0ce4ee00f58f815c9dbee191b0c9d173e70 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 00:19:25 +0000 Subject: [PATCH 075/117] chore(deps): bump github.com/ethereum/go-ethereum from 1.16.8 to 1.17.0 (#4876) Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.16.8 to 1.17.0. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.16.8...v1.17.0) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-version: 1.17.0 dependency-type: indirect ... 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 01fc5c7eaf..17d7f581c3 100644 --- a/go.mod +++ b/go.mod @@ -167,7 +167,7 @@ require ( github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect - github.com/ethereum/go-ethereum v1.16.8 // indirect + github.com/ethereum/go-ethereum v1.17.0 // indirect github.com/ettle/strcase v0.2.0 // indirect github.com/fatih/color v1.18.0 // indirect github.com/fatih/structtag v1.2.0 // indirect diff --git a/go.sum b/go.sum index 8344412943..561bce1123 100644 --- a/go.sum +++ b/go.sum @@ -319,8 +319,8 @@ github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FM github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= -github.com/ethereum/go-ethereum v1.16.8 h1:LLLfkZWijhR5m6yrAXbdlTeXoqontH+Ga2f9igY7law= -github.com/ethereum/go-ethereum v1.16.8/go.mod h1:Fs6QebQbavneQTYcA39PEKv2+zIjX7rPUZ14DER46wk= +github.com/ethereum/go-ethereum v1.17.0 h1:2D+1Fe23CwZ5tQoAS5DfwKFNI1HGcTwi65/kRlAVxes= +github.com/ethereum/go-ethereum v1.17.0/go.mod h1:2W3msvdosS/MCWytpqTcqgFiRYbTH59FxDJzqah120o= github.com/ettle/strcase v0.2.0 h1:fGNiVF21fHXpX1niBgk0aROov1LagYsOwV/xqKDKR/Q= github.com/ettle/strcase v0.2.0/go.mod h1:DajmHElDSaX76ITe3/VHVyMin4LWSJN5Z909Wp+ED1A= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= From de0bc59acdf3416b71db358dab1e77b31b050bdf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 00:25:41 +0000 Subject: [PATCH 076/117] chore(deps): bump github.com/ethereum/go-ethereum from 1.16.8 to 1.17.0 in /pkg (#4877) chore(deps): bump github.com/ethereum/go-ethereum in /pkg Bumps [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum) from 1.16.8 to 1.17.0. - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](https://github.com/ethereum/go-ethereum/compare/v1.16.8...v1.17.0) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-version: 1.17.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/go.mod | 3 +-- pkg/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pkg/go.mod b/pkg/go.mod index 0f639818fa..9c1a4c9a66 100644 --- a/pkg/go.mod +++ b/pkg/go.mod @@ -33,7 +33,7 @@ require ( github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect - github.com/ethereum/go-ethereum v1.16.8 // indirect + github.com/ethereum/go-ethereum v1.17.0 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect @@ -44,7 +44,6 @@ require ( github.com/lib/pq v1.10.9 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/sagikazarmark/locafero v0.11.0 // indirect github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect github.com/spf13/cast v1.10.0 // indirect diff --git a/pkg/go.sum b/pkg/go.sum index 3c10460052..191fa6681d 100644 --- a/pkg/go.sum +++ b/pkg/go.sum @@ -25,8 +25,8 @@ github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4 github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/ecies/go/v2 v2.0.11 h1:xYhtMdLiqNi02oLirFmLyNbVXw6250h3WM6zJryQdiM= github.com/ecies/go/v2 v2.0.11/go.mod h1:LPRzoefP0Tam+1uesQOq3Gtb6M2OwlFUnXBTtBAKfDQ= -github.com/ethereum/go-ethereum v1.16.8 h1:LLLfkZWijhR5m6yrAXbdlTeXoqontH+Ga2f9igY7law= -github.com/ethereum/go-ethereum v1.16.8/go.mod h1:Fs6QebQbavneQTYcA39PEKv2+zIjX7rPUZ14DER46wk= +github.com/ethereum/go-ethereum v1.17.0 h1:2D+1Fe23CwZ5tQoAS5DfwKFNI1HGcTwi65/kRlAVxes= +github.com/ethereum/go-ethereum v1.17.0/go.mod h1:2W3msvdosS/MCWytpqTcqgFiRYbTH59FxDJzqah120o= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= From 3b68bf24d5045f8e63044b1c9715009728024a50 Mon Sep 17 00:00:00 2001 From: Andrew Valleteau Date: Mon, 23 Feb 2026 14:55:27 +0100 Subject: [PATCH 077/117] fix(pull): attempt to fix unkown authority error for db pull (#4886) * fix(pull): attempt to fix unkown authority error for db pull * fix(pull): allow to disable CA verify opt-in via env variable * fix: mute gosec on explicit skip --- internal/gen/types/types.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/internal/gen/types/types.go b/internal/gen/types/types.go index fef6a97726..e5e7d73633 100644 --- a/internal/gen/types/types.go +++ b/internal/gen/types/types.go @@ -129,7 +129,22 @@ func GetRootCA(ctx context.Context, dbURL string, options ...func(*pgx.ConnConfi } func isRequireSSL(ctx context.Context, dbUrl string, options ...func(*pgx.ConnConfig)) (bool, error) { - conn, err := utils.ConnectByUrl(ctx, dbUrl+"&sslmode=require", options...) + + // pgx v4's sslmode=require verifies the server certificate against system CAs, + // unlike libpq where require skips verification. When SUPABASE_CA_SKIP_VERIFY=true, + // skip verification for this probe only (detects whether the server speaks TLS). + // Cert validation happens downstream in the migra/pgdelta Deno scripts using GetRootCA. + opts := options + if os.Getenv("SUPABASE_CA_SKIP_VERIFY") == "true" { + opts = append(opts, func(cc *pgx.ConnConfig) { + if cc.TLSConfig != nil { + // #nosec G402 -- Intentionally skipped for this TLS capability probe only. + // Downstream migra/pgdelta flows still validate certificates using GetRootCA. + cc.TLSConfig.InsecureSkipVerify = true + } + }) + } + conn, err := utils.ConnectByUrl(ctx, dbUrl+"&sslmode=require", opts...) if err != nil { if strings.HasSuffix(err.Error(), "(server refused TLS connection)") { return false, nil From 2f6e0c328ad1782fbc42b799c4afe08a0595289c Mon Sep 17 00:00:00 2001 From: Andrew Valleteau Date: Mon, 23 Feb 2026 20:32:52 +0100 Subject: [PATCH 078/117] fix(updater): network restrictions not enabled (#4887) ## Summary Mitigates workflow failures caused by `400` responses from network restrictions endpoints when projects are not entitled to manage restrictions and local config has `db.network_restrictions.enabled = false` or not set. The fix ensures we only read/update network restrictions when local config explicitly enables the feature, while preserving strict failure behavior when it is enabled. --- pkg/config/updater.go | 3 +++ pkg/config/updater_test.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/pkg/config/updater.go b/pkg/config/updater.go index eb0e87c088..6c7e7eecd1 100644 --- a/pkg/config/updater.go +++ b/pkg/config/updater.go @@ -107,6 +107,9 @@ func (u *ConfigUpdater) UpdateDbConfig(ctx context.Context, projectRef string, c } func (u *ConfigUpdater) UpdateDbNetworkRestrictionsConfig(ctx context.Context, projectRef string, n networkRestrictions, filter ...func(string) bool) error { + if !n.Enabled { + return nil + } networkRestrictionsConfig, err := u.client.V1GetNetworkRestrictionsWithResponse(ctx, projectRef) if err != nil { return errors.Errorf("failed to read network restrictions config: %w", err) diff --git a/pkg/config/updater_test.go b/pkg/config/updater_test.go index 5759c9ba83..c88e646c5c 100644 --- a/pkg/config/updater_test.go +++ b/pkg/config/updater_test.go @@ -119,6 +119,41 @@ func TestUpdateDbConfig(t *testing.T) { }) } +func TestUpdateDbNetworkRestrictionsConfig(t *testing.T) { + server := "http://localhost" + client, err := v1API.NewClientWithResponses(server) + require.NoError(t, err) + + t.Run("skips update if disabled locally", func(t *testing.T) { + updater := NewConfigUpdater(*client) + // Run test + err := updater.UpdateDbNetworkRestrictionsConfig(context.Background(), "test-project", networkRestrictions{}) + // Check result + assert.NoError(t, err) + assert.False(t, gock.HasUnmatchedRequest()) + }) + + t.Run("returns error on 400 when enabled locally", func(t *testing.T) { + updater := NewConfigUpdater(*client) + // Setup mock server + defer gock.Off() + gock.New(server). + Get("/v1/projects/test-project/network-restrictions"). + Reply(http.StatusBadRequest). + JSON(map[string]any{ + "message": "project not allowed to set up network restrictions", + }) + // Run test + err := updater.UpdateDbNetworkRestrictionsConfig(context.Background(), "test-project", networkRestrictions{ + Enabled: true, + }) + // Check result + assert.Error(t, err) + assert.Contains(t, err.Error(), "unexpected status 400") + assert.True(t, gock.IsDone()) + }) +} + func TestUpdateExperimentalConfig(t *testing.T) { server := "http://localhost" client, err := v1API.NewClientWithResponses(server) From aee1f7b3d26595fbc882533e6de45c478be923cb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Feb 2026 00:48:32 +0000 Subject: [PATCH 079/117] fix(docker): bump supabase/postgres from 17.6.1.087 to 17.6.1.088 in /pkg/config/templates (#4889) fix(docker): bump supabase/postgres in /pkg/config/templates Bumps supabase/postgres from 17.6.1.087 to 17.6.1.088. --- updated-dependencies: - dependency-name: supabase/postgres dependency-version: 17.6.1.088 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 445ff4b25a..345029f14d 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:17.6.1.087 AS pg +FROM supabase/postgres:17.6.1.088 AS pg # 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 1d5b8ed5b1043591e7263b3c8e49535c139e6485 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Feb 2026 00:57:34 +0000 Subject: [PATCH 080/117] fix(docker): bump the docker-minor group in /pkg/config/templates with 2 updates (#4888) fix(docker): bump the docker-minor group Bumps the docker-minor group in /pkg/config/templates with 2 updates: supabase/edge-runtime and supabase/realtime. Updates `supabase/edge-runtime` from v1.70.3 to v1.70.5 Updates `supabase/realtime` from v2.77.0 to v2.78.0 --- updated-dependencies: - dependency-name: supabase/edge-runtime dependency-version: v1.70.5 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/realtime dependency-version: v2.78.0 dependency-type: direct:production dependency-group: docker-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 345029f14d..787248936d 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -7,11 +7,11 @@ FROM postgrest/postgrest:v14.5 AS postgrest FROM supabase/postgres-meta:v0.95.2 AS pgmeta FROM supabase/studio:2026.02.16-sha-26c615c AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy -FROM supabase/edge-runtime:v1.70.3 AS edgeruntime +FROM supabase/edge-runtime:v1.70.5 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.186.0 AS gotrue -FROM supabase/realtime:v2.77.0 AS realtime +FROM supabase/realtime:v2.78.0 AS realtime FROM supabase/storage-api:v1.38.0 AS storage FROM supabase/logflare:1.32.5 AS logflare # Append to JobImages when adding new dependencies below From 4c759e2d2997e9478b46b7c14f6643beb15d9817 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 00:13:48 +0000 Subject: [PATCH 081/117] fix(docker): bump the docker-minor group in /pkg/config/templates with 3 updates (#4892) fix(docker): bump the docker-minor group Bumps the docker-minor group in /pkg/config/templates with 3 updates: supabase/gotrue, supabase/storage-api and supabase/logflare. Updates `supabase/gotrue` from v2.186.0 to v2.187.0 Updates `supabase/storage-api` from v1.38.0 to v1.39.1 Updates `supabase/logflare` from 1.32.5 to 1.33.1 --- updated-dependencies: - dependency-name: supabase/gotrue dependency-version: v2.187.0 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/storage-api dependency-version: v1.39.1 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/logflare dependency-version: 1.33.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: docker-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 787248936d..257b7c830b 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -10,10 +10,10 @@ FROM darthsim/imgproxy:v3.8.0 AS imgproxy FROM supabase/edge-runtime:v1.70.5 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor -FROM supabase/gotrue:v2.186.0 AS gotrue +FROM supabase/gotrue:v2.187.0 AS gotrue FROM supabase/realtime:v2.78.0 AS realtime -FROM supabase/storage-api:v1.38.0 AS storage -FROM supabase/logflare:1.32.5 AS logflare +FROM supabase/storage-api:v1.39.1 AS storage +FROM supabase/logflare:1.33.1 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 3711d195c9f515ebf6c0150726d456ee2fb11964 Mon Sep 17 00:00:00 2001 From: "supabase-cli-releaser[bot]" <246109035+supabase-cli-releaser[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 10:13:02 +0000 Subject: [PATCH 082/117] chore: sync API types from infrastructure (#4890) Co-authored-by: supabase-cli-releaser[bot] <246109035+supabase-cli-releaser[bot]@users.noreply.github.com> --- pkg/api/types.gen.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/api/types.gen.go b/pkg/api/types.gen.go index aeaa350b76..c37ddadefd 100644 --- a/pkg/api/types.gen.go +++ b/pkg/api/types.gen.go @@ -1819,6 +1819,8 @@ type ApplyProjectAddonBody_AddonVariant struct { // AuthConfigResponse defines model for AuthConfigResponse. type AuthConfigResponse struct { ApiMaxRequestDuration nullable.Nullable[int] `json:"api_max_request_duration"` + CustomOauthEnabled bool `json:"custom_oauth_enabled"` + CustomOauthMaxProviders int `json:"custom_oauth_max_providers"` DbMaxPoolSize nullable.Nullable[int] `json:"db_max_pool_size"` DbMaxPoolSizeUnit nullable.Nullable[AuthConfigResponseDbMaxPoolSizeUnit] `json:"db_max_pool_size_unit"` DisableSignup nullable.Nullable[bool] `json:"disable_signup"` @@ -3733,6 +3735,7 @@ type UpdateApiKeyBody struct { // UpdateAuthConfigBody defines model for UpdateAuthConfigBody. type UpdateAuthConfigBody struct { ApiMaxRequestDuration nullable.Nullable[int] `json:"api_max_request_duration,omitempty"` + CustomOauthEnabled *bool `json:"custom_oauth_enabled,omitempty"` DbMaxPoolSize nullable.Nullable[int] `json:"db_max_pool_size,omitempty"` DbMaxPoolSizeUnit nullable.Nullable[UpdateAuthConfigBodyDbMaxPoolSizeUnit] `json:"db_max_pool_size_unit,omitempty"` DisableSignup nullable.Nullable[bool] `json:"disable_signup,omitempty"` From 11d000f3af87e87e2ba5ddc38e6157b8a370ae7e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 15:28:56 +0000 Subject: [PATCH 083/117] chore(deps): bump the go-minor group across 1 directory with 2 updates (#4893) Bumps the go-minor group with 2 updates in the / directory: [github.com/getsentry/sentry-go](https://github.com/getsentry/sentry-go) and [github.com/slack-go/slack](https://github.com/slack-go/slack). Updates `github.com/getsentry/sentry-go` from 0.42.0 to 0.43.0 - [Release notes](https://github.com/getsentry/sentry-go/releases) - [Changelog](https://github.com/getsentry/sentry-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-go/compare/v0.42.0...v0.43.0) Updates `github.com/slack-go/slack` from 0.17.3 to 0.18.0 - [Release notes](https://github.com/slack-go/slack/releases) - [Changelog](https://github.com/slack-go/slack/blob/master/CHANGELOG.md) - [Commits](https://github.com/slack-go/slack/compare/v0.17.3...v0.18.0) --- updated-dependencies: - dependency-name: github.com/getsentry/sentry-go dependency-version: 0.43.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor - dependency-name: github.com/slack-go/slack dependency-version: 0.18.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andrew Valleteau --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 17d7f581c3..5a7bbc032a 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/docker/go-connections v0.6.0 github.com/docker/go-units v0.5.0 github.com/fsnotify/fsnotify v1.9.0 - github.com/getsentry/sentry-go v0.42.0 + github.com/getsentry/sentry-go v0.43.0 github.com/go-errors/errors v1.5.1 github.com/go-git/go-git/v5 v5.16.5 github.com/go-playground/validator/v10 v10.30.1 @@ -42,7 +42,7 @@ require ( github.com/multigres/multigres v0.0.0-20260126223308-f5a52171bbc4 github.com/oapi-codegen/nullable v1.1.0 github.com/olekukonko/tablewriter v1.1.3 - github.com/slack-go/slack v0.17.3 + github.com/slack-go/slack v0.18.0 github.com/spf13/afero v1.15.0 github.com/spf13/cobra v1.10.2 github.com/spf13/pflag v1.0.10 diff --git a/go.sum b/go.sum index 561bce1123..b6b7bac885 100644 --- a/go.sum +++ b/go.sum @@ -347,8 +347,8 @@ github.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCK github.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= github.com/getkin/kin-openapi v0.131.0 h1:NO2UeHnFKRYhZ8wg6Nyh5Cq7dHk4suQQr72a4pMrDxE= github.com/getkin/kin-openapi v0.131.0/go.mod h1:3OlG51PCYNsPByuiMB0t4fjnNlIDnaEDsjiKUV8nL58= -github.com/getsentry/sentry-go v0.42.0 h1:eeFMACuZTbUQf90RE8dE4tXeSe4CZyfvR1MBL7RLEt8= -github.com/getsentry/sentry-go v0.42.0/go.mod h1:eRXCoh3uvmjQLY6qu63BjUZnaBu5L5WhMV1RwYO8W5s= +github.com/getsentry/sentry-go v0.43.0 h1:XbXLpFicpo8HmBDaInk7dum18G9KSLcjZiyUKS+hLW4= +github.com/getsentry/sentry-go v0.43.0/go.mod h1:XDotiNZbgf5U8bPDUAfvcFmOnMQQceESxyKaObSssW0= github.com/ghostiam/protogetter v0.3.15 h1:1KF5sXel0HE48zh1/vn0Loiw25A9ApyseLzQuif1mLY= github.com/ghostiam/protogetter v0.3.15/go.mod h1:WZ0nw9pfzsgxuRsPOFQomgDVSWtDLJRfQJEhsGbmQMA= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= @@ -1004,8 +1004,8 @@ github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnB github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= -github.com/slack-go/slack v0.17.3 h1:zV5qO3Q+WJAQ/XwbGfNFrRMaJ5T/naqaonyPV/1TP4g= -github.com/slack-go/slack v0.17.3/go.mod h1:X+UqOufi3LYQHDnMG1vxf0J8asC6+WllXrVrhl8/Prk= +github.com/slack-go/slack v0.18.0 h1:PM3IWgAoaPTnitOyfy8Unq/rk8OZLAxlBUhNLv8sbyg= +github.com/slack-go/slack v0.18.0/go.mod h1:K81UmCivcYd/5Jmz8vLBfuyoZ3B4rQC2GHVXHteXiAE= github.com/sonatard/noctx v0.1.0 h1:JjqOc2WN16ISWAjAk8M5ej0RfExEXtkEyExl2hLW+OM= github.com/sonatard/noctx v0.1.0/go.mod h1:0RvBxqY8D4j9cTTTWE8ylt2vqj2EPI8fHmrxHdsaZ2c= github.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0= From eac33cab87d8b590684be286f1159630dc7f034b Mon Sep 17 00:00:00 2001 From: "supabase-cli-releaser[bot]" <246109035+supabase-cli-releaser[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 18:31:56 +0100 Subject: [PATCH 084/117] chore: sync API types from infrastructure (#4895) Co-authored-by: supabase-cli-releaser[bot] <246109035+supabase-cli-releaser[bot]@users.noreply.github.com> --- pkg/api/client.gen.go | 16 ++++++++++++++++ pkg/api/types.gen.go | 3 +++ 2 files changed, 19 insertions(+) diff --git a/pkg/api/client.gen.go b/pkg/api/client.gen.go index ff2504973f..2a2672dc4a 100644 --- a/pkg/api/client.gen.go +++ b/pkg/api/client.gen.go @@ -3417,6 +3417,22 @@ func NewV1DiffABranchRequest(server string, branchIdOrRef string, params *V1Diff } + if params.Pgdelta != nil { + + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "pgdelta", runtime.ParamLocationQuery, *params.Pgdelta); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + + } + queryURL.RawQuery = queryValues.Encode() } diff --git a/pkg/api/types.gen.go b/pkg/api/types.gen.go index c37ddadefd..13fb1a8b7c 100644 --- a/pkg/api/types.gen.go +++ b/pkg/api/types.gen.go @@ -4818,6 +4818,9 @@ type V1DeleteABranchParams struct { // V1DiffABranchParams defines parameters for V1DiffABranch. type V1DiffABranchParams struct { IncludedSchemas *string `form:"included_schemas,omitempty" json:"included_schemas,omitempty"` + + // Pgdelta Use pg-delta instead of Migra for diffing when true + Pgdelta *bool `form:"pgdelta,omitempty" json:"pgdelta,omitempty"` } // V1AuthorizeUserParams defines parameters for V1AuthorizeUser. From f750a9b26879881c6fec44b65c43290d4c10e888 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Feb 2026 00:13:54 +0000 Subject: [PATCH 085/117] fix(docker): bump supabase/postgres from 17.6.1.088 to 17.6.1.089 in /pkg/config/templates (#4900) fix(docker): bump supabase/postgres in /pkg/config/templates Bumps supabase/postgres from 17.6.1.088 to 17.6.1.089. --- updated-dependencies: - dependency-name: supabase/postgres dependency-version: 17.6.1.089 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 257b7c830b..0baf20262d 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:17.6.1.088 AS pg +FROM supabase/postgres:17.6.1.089 AS pg # 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 6258d35f045f48551bfd699b9b324524be4019f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Feb 2026 00:19:42 +0000 Subject: [PATCH 086/117] fix(docker): bump the docker-minor group in /pkg/config/templates with 2 updates (#4899) fix(docker): bump the docker-minor group Bumps the docker-minor group in /pkg/config/templates with 2 updates: supabase/realtime and supabase/logflare. Updates `supabase/realtime` from v2.78.0 to v2.78.1 Updates `supabase/logflare` from 1.33.1 to 1.33.2 --- updated-dependencies: - dependency-name: supabase/realtime dependency-version: v2.78.1 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/logflare dependency-version: 1.33.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: docker-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 0baf20262d..8e85bce8eb 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -11,9 +11,9 @@ FROM supabase/edge-runtime:v1.70.5 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.187.0 AS gotrue -FROM supabase/realtime:v2.78.0 AS realtime +FROM supabase/realtime:v2.78.1 AS realtime FROM supabase/storage-api:v1.39.1 AS storage -FROM supabase/logflare:1.33.1 AS logflare +FROM supabase/logflare:1.33.2 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 2d64b8a8bafe06e306962549fb75962bb7e5e95b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Feb 2026 00:13:49 +0000 Subject: [PATCH 087/117] fix(docker): bump supabase/postgres from 17.6.1.089 to 17.6.1.090 in /pkg/config/templates (#4905) fix(docker): bump supabase/postgres in /pkg/config/templates Bumps supabase/postgres from 17.6.1.089 to 17.6.1.090. --- updated-dependencies: - dependency-name: supabase/postgres dependency-version: 17.6.1.090 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 8e85bce8eb..251742e92a 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:17.6.1.089 AS pg +FROM supabase/postgres:17.6.1.090 AS pg # 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 f01a81ca79f0c446a33e8de563fc3d12ca9e64cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Feb 2026 00:19:29 +0000 Subject: [PATCH 088/117] fix(docker): bump the docker-minor group in /pkg/config/templates with 3 updates (#4904) fix(docker): bump the docker-minor group Bumps the docker-minor group in /pkg/config/templates with 3 updates: supabase/realtime, supabase/storage-api and supabase/logflare. Updates `supabase/realtime` from v2.78.1 to v2.78.3 Updates `supabase/storage-api` from v1.39.1 to v1.39.2 Updates `supabase/logflare` from 1.33.2 to 1.33.3 --- updated-dependencies: - dependency-name: supabase/realtime dependency-version: v2.78.3 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/storage-api dependency-version: v1.39.2 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/logflare dependency-version: 1.33.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: docker-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 251742e92a..d83f0ffd9f 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -11,9 +11,9 @@ FROM supabase/edge-runtime:v1.70.5 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.187.0 AS gotrue -FROM supabase/realtime:v2.78.1 AS realtime -FROM supabase/storage-api:v1.39.1 AS storage -FROM supabase/logflare:1.33.2 AS logflare +FROM supabase/realtime:v2.78.3 AS realtime +FROM supabase/storage-api:v1.39.2 AS storage +FROM supabase/logflare:1.33.3 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 461fdd29f8d87139f24be6ee6f2cf886921a0b15 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 Feb 2026 00:07:14 +0000 Subject: [PATCH 089/117] fix(docker): bump the docker-minor group in /pkg/config/templates with 2 updates (#4909) fix(docker): bump the docker-minor group Bumps the docker-minor group in /pkg/config/templates with 2 updates: supabase/realtime and supabase/storage-api. Updates `supabase/realtime` from v2.78.3 to v2.78.5 Updates `supabase/storage-api` from v1.39.2 to v1.40.0 --- updated-dependencies: - dependency-name: supabase/realtime dependency-version: v2.78.5 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/storage-api dependency-version: v1.40.0 dependency-type: direct:production dependency-group: docker-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index d83f0ffd9f..c5f6fc8b92 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -11,8 +11,8 @@ FROM supabase/edge-runtime:v1.70.5 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.187.0 AS gotrue -FROM supabase/realtime:v2.78.3 AS realtime -FROM supabase/storage-api:v1.39.2 AS storage +FROM supabase/realtime:v2.78.5 AS realtime +FROM supabase/storage-api:v1.40.0 AS storage FROM supabase/logflare:1.33.3 AS logflare # Append to JobImages when adding new dependencies below FROM supabase/pgadmin-schema-diff:cli-0.0.5 AS differ From 635a283915ef0e28b777fd740980a1a6baf77738 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 Feb 2026 00:12:56 +0000 Subject: [PATCH 090/117] fix(docker): bump supabase/postgres from 17.6.1.090 to 17.6.1.091 in /pkg/config/templates (#4910) fix(docker): bump supabase/postgres in /pkg/config/templates Bumps supabase/postgres from 17.6.1.090 to 17.6.1.091. --- updated-dependencies: - dependency-name: supabase/postgres dependency-version: 17.6.1.091 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 c5f6fc8b92..254d34b1b3 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:17.6.1.090 AS pg +FROM supabase/postgres:17.6.1.091 AS pg # 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 5726ec3448fb5251c741ecab6a0f3081419d6fee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Mar 2026 00:12:46 +0000 Subject: [PATCH 091/117] fix(docker): bump supabase/postgres-meta from v0.95.2 to v0.96.0 in /pkg/config/templates in the docker-minor group (#4912) fix(docker): bump supabase/postgres-meta Bumps the docker-minor group in /pkg/config/templates with 1 update: supabase/postgres-meta. Updates `supabase/postgres-meta` from v0.95.2 to v0.96.0 --- updated-dependencies: - dependency-name: supabase/postgres-meta dependency-version: v0.96.0 dependency-type: direct:production dependency-group: docker-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 254d34b1b3..d645a0f48d 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -4,7 +4,7 @@ FROM supabase/postgres:17.6.1.091 AS pg FROM library/kong:2.8.1 AS kong FROM axllent/mailpit:v1.22.3 AS mailpit FROM postgrest/postgrest:v14.5 AS postgrest -FROM supabase/postgres-meta:v0.95.2 AS pgmeta +FROM supabase/postgres-meta:v0.96.0 AS pgmeta FROM supabase/studio:2026.02.16-sha-26c615c AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy FROM supabase/edge-runtime:v1.70.5 AS edgeruntime From 7c940eba368d1c0a268adfa6a077938588c73971 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Mar 2026 21:26:16 +0000 Subject: [PATCH 092/117] chore(deps): bump go.opentelemetry.io/otel/sdk from 1.39.0 to 1.40.0 (#4916) Bumps [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) from 1.39.0 to 1.40.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.39.0...v1.40.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel/sdk dependency-version: 1.40.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 5a7bbc032a..68e271c256 100644 --- a/go.mod +++ b/go.mod @@ -418,8 +418,8 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect go.opentelemetry.io/otel/metric v1.40.0 // indirect - go.opentelemetry.io/otel/sdk v1.39.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.40.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect go.opentelemetry.io/otel/trace v1.40.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.uber.org/automaxprocs v1.6.0 // indirect diff --git a/go.sum b/go.sum index b6b7bac885..b8f623dffd 100644 --- a/go.sum +++ b/go.sum @@ -1181,10 +1181,10 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= -go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= -go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= -go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= +go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= +go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= +go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= From 6f9e21dec84753b2309a83262e746f8d45760838 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Mar 2026 21:32:46 +0000 Subject: [PATCH 093/117] chore(deps): bump github.com/cloudflare/circl from 1.6.1 to 1.6.3 (#4897) Bumps [github.com/cloudflare/circl](https://github.com/cloudflare/circl) from 1.6.1 to 1.6.3. - [Release notes](https://github.com/cloudflare/circl/releases) - [Commits](https://github.com/cloudflare/circl/compare/v1.6.1...v1.6.3) --- updated-dependencies: - dependency-name: github.com/cloudflare/circl dependency-version: 1.6.3 dependency-type: indirect ... 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 68e271c256..c500bc44f0 100644 --- a/go.mod +++ b/go.mod @@ -133,7 +133,7 @@ require ( github.com/clipperhouse/displaywidth v0.9.0 // indirect github.com/clipperhouse/stringish v0.1.1 // indirect github.com/clipperhouse/uax29/v2 v2.5.0 // indirect - github.com/cloudflare/circl v1.6.1 // indirect + github.com/cloudflare/circl v1.6.3 // indirect github.com/containerd/console v1.0.5 // indirect github.com/containerd/containerd/api v1.9.0 // indirect github.com/containerd/containerd/v2 v2.1.5 // indirect diff --git a/go.sum b/go.sum index b8f623dffd..84b6184dfb 100644 --- a/go.sum +++ b/go.sum @@ -198,8 +198,8 @@ github.com/clipperhouse/uax29/v2 v2.5.0 h1:x7T0T4eTHDONxFJsL94uKNKPHrclyFI0lm7+w github.com/clipperhouse/uax29/v2 v2.5.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= 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.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= -github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= +github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8= +github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE= From 9cdc0238a5cfca3c19acc5066b3c17a15a662a49 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Mar 2026 21:39:33 +0000 Subject: [PATCH 094/117] chore(deps): bump the go-minor group across 2 directories with 3 updates (#4906) Bumps the go-minor group with 2 updates in the / directory: [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) and [golang.org/x/net](https://github.com/golang/net). Bumps the go-minor group with 1 update in the /pkg directory: [github.com/oapi-codegen/runtime](https://github.com/oapi-codegen/runtime). Updates `github.com/go-git/go-git/v5` from 5.16.5 to 5.17.0 - [Release notes](https://github.com/go-git/go-git/releases) - [Commits](https://github.com/go-git/go-git/compare/v5.16.5...v5.17.0) Updates `golang.org/x/net` from 0.50.0 to 0.51.0 - [Commits](https://github.com/golang/net/compare/v0.50.0...v0.51.0) Updates `github.com/oapi-codegen/runtime` from 1.1.2 to 1.2.0 - [Release notes](https://github.com/oapi-codegen/runtime/releases) - [Commits](https://github.com/oapi-codegen/runtime/compare/v1.1.2...v1.2.0) --- updated-dependencies: - dependency-name: github.com/go-git/go-git/v5 dependency-version: 5.17.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor - dependency-name: golang.org/x/net dependency-version: 0.51.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor - dependency-name: github.com/oapi-codegen/runtime dependency-version: 1.2.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 20 ++++++++++---------- pkg/go.mod | 2 +- pkg/go.sum | 4 ++-- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index c500bc44f0..c397c94802 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/fsnotify/fsnotify v1.9.0 github.com/getsentry/sentry-go v0.43.0 github.com/go-errors/errors v1.5.1 - github.com/go-git/go-git/v5 v5.16.5 + github.com/go-git/go-git/v5 v5.17.0 github.com/go-playground/validator/v10 v10.30.1 github.com/go-viper/mapstructure/v2 v2.5.0 github.com/go-xmlfmt/xmlfmt v1.1.3 @@ -55,7 +55,7 @@ require ( github.com/zalando/go-keyring v0.2.6 go.opentelemetry.io/otel v1.40.0 golang.org/x/mod v0.33.0 - golang.org/x/net v0.50.0 + golang.org/x/net v0.51.0 golang.org/x/oauth2 v0.35.0 golang.org/x/term v0.40.0 google.golang.org/grpc v1.79.1 @@ -182,7 +182,7 @@ require ( github.com/ghostiam/protogetter v0.3.15 // indirect github.com/go-critic/go-critic v0.13.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.6.2 // indirect + github.com/go-git/go-billy/v5 v5.8.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect @@ -319,7 +319,7 @@ require ( github.com/nishanths/predeclared v0.2.2 // indirect github.com/nunnatsa/ginkgolinter v0.19.1 // indirect github.com/oapi-codegen/oapi-codegen/v2 v2.4.1 // indirect - github.com/oapi-codegen/runtime v1.1.2 // indirect + github.com/oapi-codegen/runtime v1.2.0 // indirect github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect diff --git a/go.sum b/go.sum index 84b6184dfb..0c7debbb91 100644 --- a/go.sum +++ b/go.sum @@ -359,12 +359,12 @@ github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8b github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM= -github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= +github.com/go-git/go-billy/v5 v5.8.0 h1:I8hjc3LbBlXTtVuFNJuwYuMiHvQJDq1AT6u4DwDzZG0= +github.com/go-git/go-billy/v5 v5.8.0/go.mod h1:RpvI/rw4Vr5QA+Z60c6d6LXH0rYJo0uD5SqfmrrheCY= 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.16.5 h1:mdkuqblwr57kVfXri5TTH+nMFLNUxIj9Z7F5ykFbw5s= -github.com/go-git/go-git/v5 v5.16.5/go.mod h1:QOMLpNf1qxuSY4StA/ArOdfFR2TrKEjJiye2kel2m+M= +github.com/go-git/go-git/v5 v5.17.0 h1:AbyI4xf+7DsjINHMu35quAh4wJygKBKBuXVjV/pxesM= +github.com/go-git/go-git/v5 v5.17.0/go.mod h1:f82C4YiLx+Lhi8eHxltLeGC5uBTXSFa6PC5WW9o4SjI= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= @@ -834,8 +834,8 @@ github.com/oapi-codegen/nullable v1.1.0 h1:eAh8JVc5430VtYVnq00Hrbpag9PFRGWLjxR1/ github.com/oapi-codegen/nullable v1.1.0/go.mod h1:KUZ3vUzkmEKY90ksAmit2+5juDIhIZhfDl+0PwOQlFY= github.com/oapi-codegen/oapi-codegen/v2 v2.4.1 h1:ykgG34472DWey7TSjd8vIfNykXgjOgYJZoQbKfEeY/Q= github.com/oapi-codegen/oapi-codegen/v2 v2.4.1/go.mod h1:N5+lY1tiTDV3V1BeHtOxeWXHoPVeApvsvjJqegfoaz8= -github.com/oapi-codegen/runtime v1.1.2 h1:P2+CubHq8fO4Q6fV1tqDBZHCwpVpvPg7oKiYzQgXIyI= -github.com/oapi-codegen/runtime v1.1.2/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= +github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+LpmzwHMP4= +github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= @@ -1090,8 +1090,8 @@ github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea h1:SXhTLE6pb6eld/ github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk= github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab h1:H6aJ0yKQ0gF49Qb2z5hI1UHxSQt4JMyxebFR15KnApw= github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab/go.mod h1:ulncasL3N9uLrVann0m+CDlJKWsIAP34MPcOJF6VRvc= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ultraware/funlen v0.2.0 h1:gCHmCn+d2/1SemTdYMiKLAHFYxTYz7z9VIDRaTGyLkI= github.com/ultraware/funlen v0.2.0/go.mod h1:ZE0q4TsJ8T1SQcjmkhN/w+MceuatI6pBFSxxyteHIJA= github.com/ultraware/whitespace v0.2.0 h1:TYowo2m9Nfj1baEQBjuHzvMRbp19i+RCcRYrSWoFa+g= @@ -1282,8 +1282,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= -golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/pkg/go.mod b/pkg/go.mod index 9c1a4c9a66..0004ae2bcb 100644 --- a/pkg/go.mod +++ b/pkg/go.mod @@ -20,7 +20,7 @@ require ( github.com/jackc/pgx/v4 v4.18.3 github.com/joho/godotenv v1.5.1 github.com/oapi-codegen/nullable v1.1.0 - github.com/oapi-codegen/runtime v1.1.2 + github.com/oapi-codegen/runtime v1.2.0 github.com/spf13/afero v1.15.0 github.com/spf13/viper v1.21.0 github.com/stretchr/testify v1.11.1 diff --git a/pkg/go.sum b/pkg/go.sum index 191fa6681d..183dac46bc 100644 --- a/pkg/go.sum +++ b/pkg/go.sum @@ -132,8 +132,8 @@ github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/oapi-codegen/nullable v1.1.0 h1:eAh8JVc5430VtYVnq00Hrbpag9PFRGWLjxR1/3KntMs= github.com/oapi-codegen/nullable v1.1.0/go.mod h1:KUZ3vUzkmEKY90ksAmit2+5juDIhIZhfDl+0PwOQlFY= -github.com/oapi-codegen/runtime v1.1.2 h1:P2+CubHq8fO4Q6fV1tqDBZHCwpVpvPg7oKiYzQgXIyI= -github.com/oapi-codegen/runtime v1.1.2/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= +github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+LpmzwHMP4= +github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= From 46661e22b78551a7334e535b65015cad26faa364 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2026 01:11:35 +0000 Subject: [PATCH 095/117] fix(docker): bump supabase/postgres from 17.6.1.091 to 17.6.1.093 in /pkg/config/templates (#4923) fix(docker): bump supabase/postgres in /pkg/config/templates Bumps supabase/postgres from 17.6.1.091 to 17.6.1.093. --- updated-dependencies: - dependency-name: supabase/postgres dependency-version: 17.6.1.093 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 d645a0f48d..f27b34967d 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:17.6.1.091 AS pg +FROM supabase/postgres:17.6.1.093 AS pg # 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 d1c9f69b870abc4be96fe4b831868659118ab5fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2026 01:17:29 +0000 Subject: [PATCH 096/117] fix(docker): bump the docker-minor group in /pkg/config/templates with 4 updates (#4922) fix(docker): bump the docker-minor group Bumps the docker-minor group in /pkg/config/templates with 4 updates: supabase/studio, supabase/realtime, supabase/storage-api and supabase/logflare. Updates `supabase/studio` from 2026.02.16-sha-26c615c to 2026.03.02-sha-5644bee Updates `supabase/realtime` from v2.78.5 to v2.78.6 Updates `supabase/storage-api` from v1.40.0 to v1.41.0 Updates `supabase/logflare` from 1.33.3 to 1.34.3 --- updated-dependencies: - dependency-name: supabase/studio dependency-version: 2026.03.02-sha-5644bee dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/realtime dependency-version: v2.78.6 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/storage-api dependency-version: v1.41.0 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/logflare dependency-version: 1.34.3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: docker-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index f27b34967d..dfe765fa8f 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -5,15 +5,15 @@ FROM library/kong:2.8.1 AS kong FROM axllent/mailpit:v1.22.3 AS mailpit FROM postgrest/postgrest:v14.5 AS postgrest FROM supabase/postgres-meta:v0.96.0 AS pgmeta -FROM supabase/studio:2026.02.16-sha-26c615c AS studio +FROM supabase/studio:2026.03.02-sha-5644bee AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy FROM supabase/edge-runtime:v1.70.5 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.187.0 AS gotrue -FROM supabase/realtime:v2.78.5 AS realtime -FROM supabase/storage-api:v1.40.0 AS storage -FROM supabase/logflare:1.33.3 AS logflare +FROM supabase/realtime:v2.78.6 AS realtime +FROM supabase/storage-api:v1.41.0 AS storage +FROM supabase/logflare:1.34.3 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 fa1a7ddc44f8e62ce0778d04d6a60c2272927d21 Mon Sep 17 00:00:00 2001 From: "supabase-cli-releaser[bot]" <246109035+supabase-cli-releaser[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2026 10:04:20 +0100 Subject: [PATCH 097/117] chore: sync API types from infrastructure (#4918) * chore: sync API types from infrastructure * fix: remove stale `pico` project size enum reference from API-sync update (#4925) * Initial plan * fix: remove stale pico project size enum reference Co-authored-by: avallete <8771783+avallete@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: avallete <8771783+avallete@users.noreply.github.com> --------- Co-authored-by: supabase-cli-releaser[bot] <246109035+supabase-cli-releaser[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: avallete <8771783+avallete@users.noreply.github.com> --- cmd/projects.go | 1 - pkg/api/types.gen.go | 63 +++++++++++--------------------------------- 2 files changed, 16 insertions(+), 48 deletions(-) diff --git a/cmd/projects.go b/cmd/projects.go index 93a75fb20b..2b4763c6d1 100644 --- a/cmd/projects.go +++ b/cmd/projects.go @@ -49,7 +49,6 @@ var ( string(api.V1CreateProjectBodyDesiredInstanceSizeN48xlargeOptimizedMemory), string(api.V1CreateProjectBodyDesiredInstanceSizeN4xlarge), string(api.V1CreateProjectBodyDesiredInstanceSizeN8xlarge), - string(api.V1CreateProjectBodyDesiredInstanceSizePico), string(api.V1CreateProjectBodyDesiredInstanceSizeSmall), string(api.V1CreateProjectBodyDesiredInstanceSizeXlarge), }, diff --git a/pkg/api/types.gen.go b/pkg/api/types.gen.go index 13fb1a8b7c..d995161a51 100644 --- a/pkg/api/types.gen.go +++ b/pkg/api/types.gen.go @@ -828,11 +828,11 @@ const ( // Defines values for ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersion. const ( - ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersionN13 ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersion = "13" - ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersionN14 ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersion = "14" - ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersionN15 ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersion = "15" - ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersionN17 ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersion = "17" - ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersionN17Oriole ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersion = "17-oriole" + N13 ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersion = "13" + N14 ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersion = "14" + N15 ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersion = "15" + N17 ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersion = "17" + N17Oriole ProjectUpgradeEligibilityResponseTargetUpgradeVersionsPostgresVersion = "17-oriole" ) // Defines values for ProjectUpgradeEligibilityResponseTargetUpgradeVersionsReleaseChannel. @@ -1299,7 +1299,6 @@ const ( V1CreateProjectBodyDesiredInstanceSizeN4xlarge V1CreateProjectBodyDesiredInstanceSize = "4xlarge" V1CreateProjectBodyDesiredInstanceSizeN8xlarge V1CreateProjectBodyDesiredInstanceSize = "8xlarge" V1CreateProjectBodyDesiredInstanceSizeNano V1CreateProjectBodyDesiredInstanceSize = "nano" - V1CreateProjectBodyDesiredInstanceSizePico V1CreateProjectBodyDesiredInstanceSize = "pico" V1CreateProjectBodyDesiredInstanceSizeSmall V1CreateProjectBodyDesiredInstanceSize = "small" V1CreateProjectBodyDesiredInstanceSizeXlarge V1CreateProjectBodyDesiredInstanceSize = "xlarge" ) @@ -1310,13 +1309,6 @@ const ( V1CreateProjectBodyPlanPro V1CreateProjectBodyPlan = "pro" ) -// Defines values for V1CreateProjectBodyPostgresEngine. -const ( - V1CreateProjectBodyPostgresEngineN15 V1CreateProjectBodyPostgresEngine = "15" - V1CreateProjectBodyPostgresEngineN17 V1CreateProjectBodyPostgresEngine = "17" - V1CreateProjectBodyPostgresEngineN17Oriole V1CreateProjectBodyPostgresEngine = "17-oriole" -) - // Defines values for V1CreateProjectBodyRegion. const ( V1CreateProjectBodyRegionApEast1 V1CreateProjectBodyRegion = "ap-east-1" @@ -1378,24 +1370,14 @@ const ( SmartGroup V1CreateProjectBodyRegionSelection1Type = "smartGroup" ) -// Defines values for V1CreateProjectBodyReleaseChannel. -const ( - V1CreateProjectBodyReleaseChannelAlpha V1CreateProjectBodyReleaseChannel = "alpha" - V1CreateProjectBodyReleaseChannelBeta V1CreateProjectBodyReleaseChannel = "beta" - V1CreateProjectBodyReleaseChannelGa V1CreateProjectBodyReleaseChannel = "ga" - V1CreateProjectBodyReleaseChannelInternal V1CreateProjectBodyReleaseChannel = "internal" - V1CreateProjectBodyReleaseChannelPreview V1CreateProjectBodyReleaseChannel = "preview" - V1CreateProjectBodyReleaseChannelWithdrawn V1CreateProjectBodyReleaseChannel = "withdrawn" -) - // Defines values for V1OrganizationSlugResponseAllowedReleaseChannels. const ( - Alpha V1OrganizationSlugResponseAllowedReleaseChannels = "alpha" - Beta V1OrganizationSlugResponseAllowedReleaseChannels = "beta" - Ga V1OrganizationSlugResponseAllowedReleaseChannels = "ga" - Internal V1OrganizationSlugResponseAllowedReleaseChannels = "internal" - Preview V1OrganizationSlugResponseAllowedReleaseChannels = "preview" - Withdrawn V1OrganizationSlugResponseAllowedReleaseChannels = "withdrawn" + V1OrganizationSlugResponseAllowedReleaseChannelsAlpha V1OrganizationSlugResponseAllowedReleaseChannels = "alpha" + V1OrganizationSlugResponseAllowedReleaseChannelsBeta V1OrganizationSlugResponseAllowedReleaseChannels = "beta" + V1OrganizationSlugResponseAllowedReleaseChannelsGa V1OrganizationSlugResponseAllowedReleaseChannels = "ga" + V1OrganizationSlugResponseAllowedReleaseChannelsInternal V1OrganizationSlugResponseAllowedReleaseChannels = "internal" + V1OrganizationSlugResponseAllowedReleaseChannelsPreview V1OrganizationSlugResponseAllowedReleaseChannels = "preview" + V1OrganizationSlugResponseAllowedReleaseChannelsWithdrawn V1OrganizationSlugResponseAllowedReleaseChannels = "withdrawn" ) // Defines values for V1OrganizationSlugResponseOptInTags. @@ -1625,7 +1607,6 @@ const ( V1GetAvailableRegionsParamsDesiredInstanceSizeN4xlarge V1GetAvailableRegionsParamsDesiredInstanceSize = "4xlarge" V1GetAvailableRegionsParamsDesiredInstanceSizeN8xlarge V1GetAvailableRegionsParamsDesiredInstanceSize = "8xlarge" V1GetAvailableRegionsParamsDesiredInstanceSizeNano V1GetAvailableRegionsParamsDesiredInstanceSize = "nano" - V1GetAvailableRegionsParamsDesiredInstanceSizePico V1GetAvailableRegionsParamsDesiredInstanceSize = "pico" V1GetAvailableRegionsParamsDesiredInstanceSizeSmall V1GetAvailableRegionsParamsDesiredInstanceSize = "small" V1GetAvailableRegionsParamsDesiredInstanceSizeXlarge V1GetAvailableRegionsParamsDesiredInstanceSize = "xlarge" ) @@ -4319,7 +4300,9 @@ type V1CreateMigrationBody struct { // V1CreateProjectBody defines model for V1CreateProjectBody. type V1CreateProjectBody struct { // DbPass Database password - DbPass string `json:"db_pass"` + DbPass string `json:"db_pass"` + + // DesiredInstanceSize Desired instance size. Omit this field to always default to the smallest possible size. DesiredInstanceSize *V1CreateProjectBodyDesiredInstanceSize `json:"desired_instance_size,omitempty"` // KpsEnabled This field is deprecated and is ignored in this request @@ -4340,10 +4323,6 @@ type V1CreateProjectBody struct { // Deprecated: Plan *V1CreateProjectBodyPlan `json:"plan,omitempty"` - // PostgresEngine Postgres engine version. If not provided, the latest version will be used. - // Deprecated: - PostgresEngine *V1CreateProjectBodyPostgresEngine `json:"postgres_engine,omitempty"` - // Region Region you want your server to reside in. Use region_selection instead. // Deprecated: Region *V1CreateProjectBodyRegion `json:"region,omitempty"` @@ -4351,23 +4330,16 @@ type V1CreateProjectBody struct { // RegionSelection Region selection. Only one of region or region_selection can be specified. RegionSelection *V1CreateProjectBody_RegionSelection `json:"region_selection,omitempty"` - // ReleaseChannel Release channel. If not provided, GA will be used. - // Deprecated: - ReleaseChannel *V1CreateProjectBodyReleaseChannel `json:"release_channel,omitempty"` - // TemplateUrl Template URL used to create the project from the CLI. TemplateUrl *string `json:"template_url,omitempty"` } -// V1CreateProjectBodyDesiredInstanceSize defines model for V1CreateProjectBody.DesiredInstanceSize. +// V1CreateProjectBodyDesiredInstanceSize Desired instance size. Omit this field to always default to the smallest possible size. type V1CreateProjectBodyDesiredInstanceSize string // V1CreateProjectBodyPlan Subscription Plan is now set on organization level and is ignored in this request type V1CreateProjectBodyPlan string -// V1CreateProjectBodyPostgresEngine Postgres engine version. If not provided, the latest version will be used. -type V1CreateProjectBodyPostgresEngine string - // V1CreateProjectBodyRegion Region you want your server to reside in. Use region_selection instead. type V1CreateProjectBodyRegion string @@ -4402,9 +4374,6 @@ type V1CreateProjectBody_RegionSelection struct { union json.RawMessage } -// V1CreateProjectBodyReleaseChannel Release channel. If not provided, GA will be used. -type V1CreateProjectBodyReleaseChannel string - // V1GetMigrationResponse defines model for V1GetMigrationResponse. type V1GetMigrationResponse struct { CreatedBy *string `json:"created_by,omitempty"` @@ -4897,7 +4866,7 @@ type V1GetAvailableRegionsParams struct { // Continent Continent code to determine regional recommendations: NA (North America), SA (South America), EU (Europe), AF (Africa), AS (Asia), OC (Oceania), AN (Antarctica) Continent *V1GetAvailableRegionsParamsContinent `form:"continent,omitempty" json:"continent,omitempty"` - // DesiredInstanceSize Desired instance size + // DesiredInstanceSize Desired instance size. Omit this field to always default to the smallest possible size. DesiredInstanceSize *V1GetAvailableRegionsParamsDesiredInstanceSize `form:"desired_instance_size,omitempty" json:"desired_instance_size,omitempty"` } From 3defd608a41611650e2670f6424047178d15bc8d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2026 09:09:32 +0000 Subject: [PATCH 098/117] chore(deps): bump go.opentelemetry.io/otel from 1.40.0 to 1.41.0 in the go-minor group across 1 directory (#4924) chore(deps): bump go.opentelemetry.io/otel Bumps the go-minor group with 1 update in the / directory: [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go). Updates `go.opentelemetry.io/otel` from 1.40.0 to 1.41.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.40.0...v1.41.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel dependency-version: 1.41.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andrew Valleteau --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index c397c94802..b716809d6c 100644 --- a/go.mod +++ b/go.mod @@ -53,7 +53,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.40.0 + go.opentelemetry.io/otel v1.41.0 golang.org/x/mod v0.33.0 golang.org/x/net v0.51.0 golang.org/x/oauth2 v0.35.0 @@ -417,10 +417,10 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect - go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/otel/metric v1.41.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.41.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect diff --git a/go.sum b/go.sum index 0c7debbb91..913e69a127 100644 --- a/go.sum +++ b/go.sum @@ -1167,8 +1167,8 @@ go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0. go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0/go.mod h1:CosX/aS4eHnG9D7nESYpV753l4j9q5j3SL/PUYd2lR8= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 h1:ssfIgGNANqpVFCndZvcuyKbl0g+UAVcbBcqGkG28H0Y= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0/go.mod h1:GQ/474YrbE4Jx8gZ4q5I4hrhUzM6UPzyrqJYV2AqPoQ= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= +go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c= +go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0 h1:cEf8jF6WbuGQWUVcqgyWtTR0kOOAWY1DYZ+UhvdmQPw= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0/go.mod h1:k1lzV5n5U3HkGvTCJHraTAGJ7MqsgL1wrGwTj1Isfiw= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0 h1:nKP4Z2ejtHn3yShBb+2KawiXgpn8In5cT7aO2wXuOTE= @@ -1179,14 +1179,14 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ= +go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= +go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0= +go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= From e575ff04d08742e5c60efab837873641793274ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Mar 2026 00:13:49 +0000 Subject: [PATCH 099/117] fix(docker): bump the docker-minor group in /pkg/config/templates with 4 updates (#4926) fix(docker): bump the docker-minor group Bumps the docker-minor group in /pkg/config/templates with 4 updates: supabase/edge-runtime, supabase/realtime, supabase/storage-api and supabase/logflare. Updates `supabase/edge-runtime` from v1.70.5 to v1.71.0 Updates `supabase/realtime` from v2.78.6 to v2.78.7 Updates `supabase/storage-api` from v1.41.0 to v1.41.3 Updates `supabase/logflare` from 1.34.3 to 1.34.5 --- updated-dependencies: - dependency-name: supabase/edge-runtime dependency-version: v1.71.0 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/realtime dependency-version: v2.78.7 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/storage-api dependency-version: v1.41.3 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/logflare dependency-version: 1.34.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: docker-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index dfe765fa8f..089287562d 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -7,13 +7,13 @@ FROM postgrest/postgrest:v14.5 AS postgrest FROM supabase/postgres-meta:v0.96.0 AS pgmeta FROM supabase/studio:2026.03.02-sha-5644bee AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy -FROM supabase/edge-runtime:v1.70.5 AS edgeruntime +FROM supabase/edge-runtime:v1.71.0 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.187.0 AS gotrue -FROM supabase/realtime:v2.78.6 AS realtime -FROM supabase/storage-api:v1.41.0 AS storage -FROM supabase/logflare:1.34.3 AS logflare +FROM supabase/realtime:v2.78.7 AS realtime +FROM supabase/storage-api:v1.41.3 AS storage +FROM supabase/logflare:1.34.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 4544462f76b5e7eb9c267d328bc9eab6b82f9966 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Mar 2026 00:09:59 +0000 Subject: [PATCH 100/117] chore(deps): bump tar from 7.5.9 to 7.5.10 in the npm-major group (#4928) Bumps the npm-major group with 1 update: [tar](https://github.com/isaacs/node-tar). Updates `tar` from 7.5.9 to 7.5.10 - [Release notes](https://github.com/isaacs/node-tar/releases) - [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md) - [Commits](https://github.com/isaacs/node-tar/compare/v7.5.9...v7.5.10) --- updated-dependencies: - dependency-name: tar dependency-version: 7.5.10 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: npm-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0a51561953..dabbc87a07 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "bin-links": "^6.0.0", "https-proxy-agent": "^7.0.2", "node-fetch": "^3.3.2", - "tar": "7.5.9" + "tar": "7.5.10" }, "release": { "branches": [ From 9efbdaa9e371c83c1503043ee73a91db2119b50b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Mar 2026 00:16:11 +0000 Subject: [PATCH 101/117] chore(deps): bump github.com/slack-go/slack from 0.18.0 to 0.19.0 in the go-minor group across 1 directory (#4931) chore(deps): bump github.com/slack-go/slack Bumps the go-minor group with 1 update in the / directory: [github.com/slack-go/slack](https://github.com/slack-go/slack). Updates `github.com/slack-go/slack` from 0.18.0 to 0.19.0 - [Release notes](https://github.com/slack-go/slack/releases) - [Changelog](https://github.com/slack-go/slack/blob/master/CHANGELOG.md) - [Commits](https://github.com/slack-go/slack/compare/v0.18.0...v0.19.0) --- updated-dependencies: - dependency-name: github.com/slack-go/slack dependency-version: 0.19.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-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 b716809d6c..41b48076b9 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,7 @@ require ( github.com/multigres/multigres v0.0.0-20260126223308-f5a52171bbc4 github.com/oapi-codegen/nullable v1.1.0 github.com/olekukonko/tablewriter v1.1.3 - github.com/slack-go/slack v0.18.0 + github.com/slack-go/slack v0.19.0 github.com/spf13/afero v1.15.0 github.com/spf13/cobra v1.10.2 github.com/spf13/pflag v1.0.10 diff --git a/go.sum b/go.sum index 913e69a127..11203b2d0e 100644 --- a/go.sum +++ b/go.sum @@ -1004,8 +1004,8 @@ github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnB github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= -github.com/slack-go/slack v0.18.0 h1:PM3IWgAoaPTnitOyfy8Unq/rk8OZLAxlBUhNLv8sbyg= -github.com/slack-go/slack v0.18.0/go.mod h1:K81UmCivcYd/5Jmz8vLBfuyoZ3B4rQC2GHVXHteXiAE= +github.com/slack-go/slack v0.19.0 h1:J8lL/nGTsIUX53HU8YxZeI3PDkA+sxZsFrI2Dew7h44= +github.com/slack-go/slack v0.19.0/go.mod h1:K81UmCivcYd/5Jmz8vLBfuyoZ3B4rQC2GHVXHteXiAE= github.com/sonatard/noctx v0.1.0 h1:JjqOc2WN16ISWAjAk8M5ej0RfExEXtkEyExl2hLW+OM= github.com/sonatard/noctx v0.1.0/go.mod h1:0RvBxqY8D4j9cTTTWE8ylt2vqj2EPI8fHmrxHdsaZ2c= github.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0= From 67510a2edf2276a41ea0bec4bba835b0a177157c Mon Sep 17 00:00:00 2001 From: Geoffrey Sechter Date: Thu, 5 Mar 2026 06:37:36 -0700 Subject: [PATCH 102/117] fix(function): support multiline import type statements in import scanning (#4872) * fix(function): support multiline import type statements in import scanning The regex pattern `.*?` does not match newlines, causing multiline `import type { X }` statements to be skipped during bind-mount file scanning. This results in type-only imports not being mounted in the Docker container, causing runtime errors like: worker boot error: Module not found "file:///.../types/MyType.ts" Changed `.*?` to `[\s\S]*?` to match any character including newlines, consistent with the `{[^{}]+}` pattern used for braced imports. This fix enables proper handling of Deno 2.x style multiline type imports: ```typescript import type { MyType, OtherType, } from './types.ts' ``` Includes test case to prevent regression. * test(function): add non-braced default type import to fixture Cover `import type Foo from '...'` pattern in the multiline import type test. This form also routes through the `[\s\S]*?` branch and was previously untested. * fix(function): use (?:type\s+)? for multiline import type matching Narrow the regex fix for multiline import type statements per PR review feedback. Instead of widening .*? to [\s\S]*? (which affects all import patterns), add (?:type\s+)? to consume the type keyword so braced imports route into the {[^{}]+} branch that already handles newlines. --------- Co-authored-by: Andrew Valleteau --- pkg/function/deno.go | 2 +- pkg/function/deno_test.go | 15 +++++++++++++ pkg/function/testdata/modules/import_types.ts | 22 +++++++++++++++++++ pkg/function/testdata/types/database.ts | 11 ++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 pkg/function/testdata/modules/import_types.ts create mode 100644 pkg/function/testdata/types/database.ts diff --git a/pkg/function/deno.go b/pkg/function/deno.go index ec785c2467..6c98b367b7 100644 --- a/pkg/function/deno.go +++ b/pkg/function/deno.go @@ -111,7 +111,7 @@ func resolveHostPath(jsonPath, hostPath string) string { } // Ref: https://regex101.com/r/DfBdJA/1 -var importPathPattern = regexp.MustCompile(`(?i)(?:import|export)\s+(?:{[^{}]+}|.*?)\s*(?:from)?\s*['"](.*?)['"]|import\(\s*['"](.*?)['"]\)`) +var importPathPattern = regexp.MustCompile(`(?i)(?:import|export)\s+(?:type\s+)?(?:{[^{}]+}|.*?)\s*(?:from)?\s*['"](.*?)['"]|import\(\s*['"](.*?)['"]\)`) func (importMap *ImportMap) WalkImportPaths(srcPath string, readFile func(curr string, w io.Writer) error) error { seen := map[string]struct{}{} diff --git a/pkg/function/deno_test.go b/pkg/function/deno_test.go index ee3ac77956..aa9677f5ad 100644 --- a/pkg/function/deno_test.go +++ b/pkg/function/deno_test.go @@ -86,6 +86,21 @@ func TestImportPaths(t *testing.T) { assert.NoError(t, err) fsys.AssertExpectations(t) }) + + t.Run("iterates multiline import type statements", func(t *testing.T) { + // This test verifies that multiline import type statements are correctly parsed. + // The (?:type\s+)? group consumes the type keyword so braced imports hit the {[^{}]+} branch. + // Setup in-memory fs + fsys := MockFS{} + fsys.On("ReadFile", "testdata/modules/import_types.ts").Once() + fsys.On("ReadFile", "testdata/types/database.ts").Once() + // Run test + im := ImportMap{} + err := im.WalkImportPaths("testdata/modules/import_types.ts", fsys.ReadFile) + // Check error + assert.NoError(t, err) + fsys.AssertExpectations(t) + }) } func TestResolveImports(t *testing.T) { diff --git a/pkg/function/testdata/modules/import_types.ts b/pkg/function/testdata/modules/import_types.ts new file mode 100644 index 0000000000..d285ab0ee8 --- /dev/null +++ b/pkg/function/testdata/modules/import_types.ts @@ -0,0 +1,22 @@ +// Test file for multiline import type statements +// This pattern requires (?:type\s+)? to route braced imports into the {[^{}]+} branch + +// Multiline import type - should be matched by the regex +import type { + Database, + Json +} from '../types/database.ts' + +// Single line import type - should also work +import type { Database as DB } from '../types/database.ts' + +// Re-export type to verify export pattern +export type { Database } from '../types/database.ts' + +// Multiline export type +export type { + Json +} from '../types/database.ts' + +// Non-braced default type import - exercises the .*? branch on single-line +import type Database from '../types/database.ts' diff --git a/pkg/function/testdata/types/database.ts b/pkg/function/testdata/types/database.ts new file mode 100644 index 0000000000..4c49d8e2d0 --- /dev/null +++ b/pkg/function/testdata/types/database.ts @@ -0,0 +1,11 @@ +export type Database = { + public: { + Tables: { + users: { + Row: { id: string; name: string } + } + } + } +} + +export type Json = string | number | boolean | null | { [key: string]: Json } | Json[] From 7404c577b14f87274e4526d223959e2d4c3bf691 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 00:14:09 +0000 Subject: [PATCH 103/117] fix(docker): bump the docker-minor group across 1 directory with 5 updates (#4935) Bumps the docker-minor group with 5 updates in the /pkg/config/templates directory: | Package | From | To | | --- | --- | --- | | supabase/postgres-meta | `v0.96.0` | `v0.96.1` | | supabase/studio | `2026.03.02-sha-5644bee` | `2026.03.04-sha-0043607` | | supabase/realtime | `v2.78.7` | `v2.78.10` | | supabase/storage-api | `v1.41.3` | `v1.41.8` | | supabase/logflare | `1.34.5` | `1.34.7` | Updates `supabase/postgres-meta` from v0.96.0 to v0.96.1 Updates `supabase/studio` from 2026.03.02-sha-5644bee to 2026.03.04-sha-0043607 Updates `supabase/realtime` from v2.78.7 to v2.78.10 Updates `supabase/storage-api` from v1.41.3 to v1.41.8 Updates `supabase/logflare` from 1.34.5 to 1.34.7 --- updated-dependencies: - dependency-name: supabase/postgres-meta dependency-version: v0.96.1 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/studio dependency-version: 2026.03.04-sha-0043607 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/realtime dependency-version: v2.78.10 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/storage-api dependency-version: v1.41.8 dependency-type: direct:production dependency-group: docker-minor - dependency-name: supabase/logflare dependency-version: 1.34.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: docker-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkg/config/templates/Dockerfile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 089287562d..f3c85597f1 100644 --- a/pkg/config/templates/Dockerfile +++ b/pkg/config/templates/Dockerfile @@ -4,16 +4,16 @@ FROM supabase/postgres:17.6.1.093 AS pg FROM library/kong:2.8.1 AS kong FROM axllent/mailpit:v1.22.3 AS mailpit FROM postgrest/postgrest:v14.5 AS postgrest -FROM supabase/postgres-meta:v0.96.0 AS pgmeta -FROM supabase/studio:2026.03.02-sha-5644bee AS studio +FROM supabase/postgres-meta:v0.96.1 AS pgmeta +FROM supabase/studio:2026.03.04-sha-0043607 AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy FROM supabase/edge-runtime:v1.71.0 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.187.0 AS gotrue -FROM supabase/realtime:v2.78.7 AS realtime -FROM supabase/storage-api:v1.41.3 AS storage -FROM supabase/logflare:1.34.5 AS logflare +FROM supabase/realtime:v2.78.10 AS realtime +FROM supabase/storage-api:v1.41.8 AS storage +FROM supabase/logflare:1.34.7 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 fa5bc6cc7b6d427a9d99aca0dd52c5ac83b898b9 Mon Sep 17 00:00:00 2001 From: Charis <26616127+charislam@users.noreply.github.com> Date: Fri, 6 Mar 2026 10:06:11 -0500 Subject: [PATCH 104/117] feat: pass pgrst config to studio container (#4920) Co-authored-by: Andrew Valleteau --- internal/start/start.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/start/start.go b/internal/start/start.go index 5a5cec56c6..53c0032de2 100644 --- a/internal/start/start.go +++ b/internal/start/start.go @@ -1168,6 +1168,9 @@ EOF "SUPABASE_SERVICE_KEY=" + utils.Config.Auth.ServiceRoleKey.Value, "LOGFLARE_PRIVATE_ACCESS_TOKEN=" + utils.Config.Analytics.ApiKey, "OPENAI_API_KEY=" + utils.Config.Studio.OpenaiApiKey.Value, + "PGRST_DB_SCHEMAS=" + strings.Join(utils.Config.Api.Schemas, ","), + "PGRST_DB_EXTRA_SEARCH_PATH=" + strings.Join(utils.Config.Api.ExtraSearchPath, ","), + fmt.Sprintf("PGRST_DB_MAX_ROWS=%d", utils.Config.Api.MaxRows), 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), From 31a4925438ad247e8c21d7d171ab8bc09daee7bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 7 Mar 2026 00:07:40 +0000 Subject: [PATCH 105/117] fix(docker): bump supabase/postgres from 17.6.1.093 to 17.6.1.095 in /pkg/config/templates (#4938) fix(docker): bump supabase/postgres in /pkg/config/templates Bumps supabase/postgres from 17.6.1.093 to 17.6.1.095. --- updated-dependencies: - dependency-name: supabase/postgres dependency-version: 17.6.1.095 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 f3c85597f1..6c21addec8 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:17.6.1.093 AS pg +FROM supabase/postgres:17.6.1.095 AS pg # 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 db0bfe728883eb7fc235a7279154b615d91e2418 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Mar 2026 00:25:59 +0000 Subject: [PATCH 106/117] chore(deps): bump the go-minor group across 2 directories with 2 updates (#4939) Bumps the go-minor group with 2 updates in the / directory: [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) and [google.golang.org/grpc](https://github.com/grpc/grpc-go). Bumps the go-minor group with 1 update in the /pkg directory: [google.golang.org/grpc](https://github.com/grpc/grpc-go). Updates `go.opentelemetry.io/otel` from 1.41.0 to 1.42.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.41.0...v1.42.0) Updates `google.golang.org/grpc` from 1.79.1 to 1.79.2 - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.79.1...v1.79.2) Updates `google.golang.org/grpc` from 1.79.1 to 1.79.2 - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.79.1...v1.79.2) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel dependency-version: 1.42.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor - dependency-name: google.golang.org/grpc dependency-version: 1.79.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-minor - dependency-name: google.golang.org/grpc dependency-version: 1.79.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- pkg/go.mod | 2 +- pkg/go.sum | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 41b48076b9..2c22ecf79d 100644 --- a/go.mod +++ b/go.mod @@ -53,12 +53,12 @@ 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.41.0 + go.opentelemetry.io/otel v1.42.0 golang.org/x/mod v0.33.0 golang.org/x/net v0.51.0 golang.org/x/oauth2 v0.35.0 golang.org/x/term v0.40.0 - google.golang.org/grpc v1.79.1 + google.golang.org/grpc v1.79.2 gopkg.in/yaml.v3 v3.0.1 ) @@ -417,10 +417,10 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect - go.opentelemetry.io/otel/metric v1.41.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/sdk v1.40.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.41.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect diff --git a/go.sum b/go.sum index 11203b2d0e..c141b87fbf 100644 --- a/go.sum +++ b/go.sum @@ -1167,8 +1167,8 @@ go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0. go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0/go.mod h1:CosX/aS4eHnG9D7nESYpV753l4j9q5j3SL/PUYd2lR8= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 h1:ssfIgGNANqpVFCndZvcuyKbl0g+UAVcbBcqGkG28H0Y= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0/go.mod h1:GQ/474YrbE4Jx8gZ4q5I4hrhUzM6UPzyrqJYV2AqPoQ= -go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c= -go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0 h1:cEf8jF6WbuGQWUVcqgyWtTR0kOOAWY1DYZ+UhvdmQPw= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0/go.mod h1:k1lzV5n5U3HkGvTCJHraTAGJ7MqsgL1wrGwTj1Isfiw= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0 h1:nKP4Z2ejtHn3yShBb+2KawiXgpn8In5cT7aO2wXuOTE= @@ -1179,14 +1179,14 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= -go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ= -go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0= -go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1421,8 +1421,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= -google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU= +google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= 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= diff --git a/pkg/go.mod b/pkg/go.mod index 0004ae2bcb..c45734b6e9 100644 --- a/pkg/go.mod +++ b/pkg/go.mod @@ -26,7 +26,7 @@ require ( github.com/stretchr/testify v1.11.1 github.com/tidwall/jsonc v0.3.2 golang.org/x/mod v0.33.0 - google.golang.org/grpc v1.79.1 + google.golang.org/grpc v1.79.2 ) require ( diff --git a/pkg/go.sum b/pkg/go.sum index 183dac46bc..98408e3a7c 100644 --- a/pkg/go.sum +++ b/pkg/go.sum @@ -290,8 +290,8 @@ golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= -google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU= +google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= From ba32edc29e0f71015b8839673944137f94d2a9d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 00:17:17 +0000 Subject: [PATCH 107/117] chore(deps): bump golang.org/x/oauth2 from 0.35.0 to 0.36.0 in the go-minor group across 1 directory (#4942) chore(deps): bump golang.org/x/oauth2 Bumps the go-minor group with 1 update in the / directory: [golang.org/x/oauth2](https://github.com/golang/oauth2). Updates `golang.org/x/oauth2` from 0.35.0 to 0.36.0 - [Commits](https://github.com/golang/oauth2/compare/v0.35.0...v0.36.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-version: 0.36.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-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 2c22ecf79d..7319abe1ab 100644 --- a/go.mod +++ b/go.mod @@ -56,7 +56,7 @@ require ( go.opentelemetry.io/otel v1.42.0 golang.org/x/mod v0.33.0 golang.org/x/net v0.51.0 - golang.org/x/oauth2 v0.35.0 + golang.org/x/oauth2 v0.36.0 golang.org/x/term v0.40.0 google.golang.org/grpc v1.79.2 gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index c141b87fbf..97727f4fe4 100644 --- a/go.sum +++ b/go.sum @@ -1284,8 +1284,8 @@ golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= -golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= +golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= 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 b4918f383f80633db5e46946e4960552e3fa08ee Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Mon, 9 Mar 2026 23:12:29 +0800 Subject: [PATCH 108/117] fix: save profile to global path (#4697) Co-authored-by: Andrew Valleteau --- cmd/login.go | 2 +- internal/utils/misc.go | 1 - internal/utils/profile.go | 25 +++++++++++++++++++++++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/cmd/login.go b/cmd/login.go index d1d4086fdf..64de8c77a9 100644 --- a/cmd/login.go +++ b/cmd/login.go @@ -42,7 +42,7 @@ var ( PostRunE: func(cmd *cobra.Command, args []string) error { if prof := viper.GetString("PROFILE"); viper.IsSet("PROFILE") { // Failure to save should block subsequent commands on CI - return utils.WriteFile(utils.ProfilePath, []byte(prof), afero.NewOsFs()) + return utils.SaveProfileName(prof, afero.NewOsFs()) } return nil }, diff --git a/internal/utils/misc.go b/internal/utils/misc.go index b7e6315ff4..e08c991a61 100644 --- a/internal/utils/misc.go +++ b/internal/utils/misc.go @@ -75,7 +75,6 @@ var ( PoolerVersionPath = filepath.Join(TempDir, "pooler-version") RealtimeVersionPath = filepath.Join(TempDir, "realtime-version") CliVersionPath = filepath.Join(TempDir, "cli-latest") - ProfilePath = filepath.Join(TempDir, "profile") CurrBranchPath = filepath.Join(SupabaseDirPath, ".branches", "_current_branch") ClusterDir = filepath.Join(SupabaseDirPath, "cluster") SchemasDir = filepath.Join(SupabaseDirPath, "schemas") diff --git a/internal/utils/profile.go b/internal/utils/profile.go index 723b52fa87..e9495a481b 100644 --- a/internal/utils/profile.go +++ b/internal/utils/profile.go @@ -3,6 +3,8 @@ package utils import ( "context" "fmt" + "os" + "path/filepath" "sort" "strings" @@ -121,8 +123,11 @@ func getProfileName(fsys afero.Fs) string { if prof := viper.GetString("PROFILE"); viper.IsSet("PROFILE") { fmt.Fprintln(debuglogger, "Loading profile from flag:", prof) return prof - } else if content, err := afero.ReadFile(fsys, ProfilePath); err == nil { - fmt.Fprintln(debuglogger, "Loading profile from file:", ProfilePath) + } else if profilePath, err := getProfilePath(); err != nil { + fmt.Fprintln(debuglogger, err) + return prof + } else if content, err := afero.ReadFile(fsys, profilePath); err == nil { + fmt.Fprintln(debuglogger, "Loading profile from file:", profilePath) return string(content) } else { fmt.Fprintln(debuglogger, err) @@ -130,6 +135,22 @@ func getProfileName(fsys afero.Fs) string { } } +func getProfilePath() (string, error) { + home, err := os.UserHomeDir() + if err != nil { + return "", errors.Errorf("failed to get $HOME directory: %w", err) + } + return filepath.Join(home, ".supabase", "profile"), nil +} + +func SaveProfileName(prof string, fsys afero.Fs) error { + profilePath, err := getProfilePath() + if err != nil { + return err + } + return WriteFile(profilePath, []byte(prof), fsys) +} + func AwsRegions() []string { result := make([]string, len(allProfiles[0].ProjectRegions)) for i, region := range allProfiles[0].ProjectRegions { From e616dbce6efc2a96c835bb91fa088758caaa8a40 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 00:09:42 +0000 Subject: [PATCH 109/117] chore(deps): bump tar from 7.5.10 to 7.5.11 in the npm-major group (#4944) Bumps the npm-major group with 1 update: [tar](https://github.com/isaacs/node-tar). Updates `tar` from 7.5.10 to 7.5.11 - [Release notes](https://github.com/isaacs/node-tar/releases) - [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md) - [Commits](https://github.com/isaacs/node-tar/compare/v7.5.10...v7.5.11) --- updated-dependencies: - dependency-name: tar dependency-version: 7.5.11 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: npm-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dabbc87a07..bee0e8bb8b 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "bin-links": "^6.0.0", "https-proxy-agent": "^7.0.2", "node-fetch": "^3.3.2", - "tar": "7.5.10" + "tar": "7.5.11" }, "release": { "branches": [ From f73cfdcff19c8ad84827e1c43cbe0a3faebd9007 Mon Sep 17 00:00:00 2001 From: "supabase-cli-releaser[bot]" <246109035+supabase-cli-releaser[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 14:51:38 +0100 Subject: [PATCH 110/117] chore: sync API types from infrastructure (#4943) Co-authored-by: supabase-cli-releaser[bot] <246109035+supabase-cli-releaser[bot]@users.noreply.github.com> --- pkg/api/types.gen.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pkg/api/types.gen.go b/pkg/api/types.gen.go index d995161a51..1e95e93da7 100644 --- a/pkg/api/types.gen.go +++ b/pkg/api/types.gen.go @@ -3397,10 +3397,13 @@ type RealtimeConfigResponse struct { // MaxPresenceEventsPerSecond Sets maximum number of presence events per second rate limit MaxPresenceEventsPerSecond nullable.Nullable[int] `json:"max_presence_events_per_second"` + // PresenceEnabled Whether to enable presence + PresenceEnabled bool `json:"presence_enabled"` + // PrivateOnly Whether to only allow private channels PrivateOnly nullable.Nullable[bool] `json:"private_only"` - // Suspend Whether to suspend realtime + // Suspend Disables the Realtime service for this project when true. Set to false to re-enable it. Suspend nullable.Nullable[bool] `json:"suspend"` } @@ -4152,10 +4155,13 @@ type UpdateRealtimeConfigBody struct { // MaxPresenceEventsPerSecond Sets maximum number of presence events per second rate limit MaxPresenceEventsPerSecond *int `json:"max_presence_events_per_second,omitempty"` + // PresenceEnabled Whether to enable presence + PresenceEnabled *bool `json:"presence_enabled,omitempty"` + // PrivateOnly Whether to only allow private channels PrivateOnly *bool `json:"private_only,omitempty"` - // Suspend Whether to suspend realtime + // Suspend Disables the Realtime service for this project when true. Set to false to re-enable it. Suspend *bool `json:"suspend,omitempty"` } From 35867ca643cbd393afbaccc92cf718cf2cd984b3 Mon Sep 17 00:00:00 2001 From: Kalleby Santos <105971119+kallebysantos@users.noreply.github.com> Date: Tue, 10 Mar 2026 14:00:31 +0000 Subject: [PATCH 111/117] feat: add hybrid jwt verification (#4721) * feat: adding hybrid jwt verification Allows verify new JWTs as well legacy * stamp: detect algorithm before verify JWT It helps to reduce latency for Legacy token verifications, since it avoid unnecessary requests. * feat: passing down JWKs as internal env - It reduces functions bootime, since there's no need to fetch JWK on fly * stamp: using URL object instead of string concatenation * stamp: codegen --------- Co-authored-by: Andrew Valleteau --- internal/functions/serve/serve.go | 2 + internal/functions/serve/templates/main.ts | 57 +++++++++++++++++++--- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/internal/functions/serve/serve.go b/internal/functions/serve/serve.go index 730e626dac..ba3346413e 100644 --- a/internal/functions/serve/serve.go +++ b/internal/functions/serve/serve.go @@ -126,12 +126,14 @@ func ServeFunctions(ctx context.Context, envFilePath string, noVerifyJWT *bool, if err != nil { return err } + jwks, _ := utils.Config.Auth.ResolveJWKS(ctx) env = append(env, fmt.Sprintf("SUPABASE_URL=http://%s:8000", utils.KongAliases[0]), "SUPABASE_ANON_KEY="+utils.Config.Auth.AnonKey.Value, "SUPABASE_SERVICE_ROLE_KEY="+utils.Config.Auth.ServiceRoleKey.Value, "SUPABASE_DB_URL="+dbUrl, "SUPABASE_INTERNAL_JWT_SECRET="+utils.Config.Auth.JwtSecret.Value, + "SUPABASE_INTERNAL_JWKS="+jwks, fmt.Sprintf("SUPABASE_INTERNAL_HOST_PORT=%d", utils.Config.Api.Port), ) if viper.GetBool("DEBUG") { diff --git a/internal/functions/serve/templates/main.ts b/internal/functions/serve/templates/main.ts index 60ea512713..f9a5febace 100644 --- a/internal/functions/serve/templates/main.ts +++ b/internal/functions/serve/templates/main.ts @@ -1,7 +1,7 @@ import { STATUS_CODE, STATUS_TEXT } from "https://deno.land/std/http/status.ts"; import * as posix from "https://deno.land/std/path/posix/mod.ts"; -import * as jose from "https://deno.land/x/jose@v4.13.1/index.ts"; +import * as jose from "jsr:@panva/jose@6"; const SB_SPECIFIC_ERROR_CODE = { BootError: @@ -29,8 +29,9 @@ const SB_SPECIFIC_ERROR_REASON = { // OS stuff - we don't want to expose these to the functions. const EXCLUDED_ENVS = ["HOME", "HOSTNAME", "PATH", "PWD"]; -const JWT_SECRET = Deno.env.get("SUPABASE_INTERNAL_JWT_SECRET")!; const HOST_PORT = Deno.env.get("SUPABASE_INTERNAL_HOST_PORT")!; +const JWT_SECRET = Deno.env.get("SUPABASE_INTERNAL_JWT_SECRET")!; +const JWKS_ENDPOINT = new URL('/auth/v1/.well-known/jwks.json', Deno.env.get("SUPABASE_URL")!) const DEBUG = Deno.env.get("SUPABASE_INTERNAL_DEBUG") === "true"; const FUNCTIONS_CONFIG_STRING = Deno.env.get( "SUPABASE_INTERNAL_FUNCTIONS_CONFIG", @@ -105,18 +106,62 @@ function getAuthToken(req: Request) { return token; } -async function verifyJWT(jwt: string): Promise { +async function isValidLegacyJWT(jwtSecret: string, jwt: string): Promise { const encoder = new TextEncoder(); - const secretKey = encoder.encode(JWT_SECRET); + const secretKey = encoder.encode(jwtSecret); try { await jose.jwtVerify(jwt, secretKey); } catch (e) { - console.error(e); + console.error('Symmetric Legacy JWT verification error', e); + return false; + } + return true; +} + +// Lazy-loading JWKs +let jwks = (() => { + try { + // using injected JWKS from cli + return jose.createLocalJWKSet(JSON.parse(Deno.env.get('SUPABASE_INTERNAL_JWKS'))); + } catch (error) { + return null + } +})(); + +async function isValidJWT(jwksUrl: string, jwt: string): Promise { + try { + if (!jwks) { + // Loading from remote-url on fly + jwks = jose.createRemoteJWKSet(new URL(jwksUrl)); + } + await jose.jwtVerify(jwt, jwks); + } catch (e) { + console.error('Asymmetric JWT verification error', e); return false; } return true; } +/** + * Applies hybrid JWT verification, using JWK as primary and Legacy Secret as fallback. + * Use only during 'New JWT Keys' migration period, while `JWT_SECRET` is still available. + */ +export async function verifyHybridJWT(jwtSecret: string, jwksUrl: string, jwt: string): Promise { + const { alg: jwtAlgorithm } = jose.decodeProtectedHeader(jwt) + + if (jwtAlgorithm === 'HS256') { + console.log(`Legacy token type detected, attempting ${jwtAlgorithm} verification.`) + + return await isValidLegacyJWT(jwtSecret, jwt) + } + + if (jwtAlgorithm === 'ES256' || jwtAlgorithm === 'RS256') { + return await isValidJWT(jwksUrl, jwt) + } + + return false; +} + // Ref: https://docs.deno.com/examples/checking_file_existence/ async function shouldUsePackageJsonDiscovery({ entrypointPath, importMapPath }: FunctionConfig): Promise { if (importMapPath) { @@ -159,7 +204,7 @@ Deno.serve({ if (req.method !== "OPTIONS" && functionsConfig[functionName].verifyJWT) { try { const token = getAuthToken(req); - const isValidJWT = await verifyJWT(token); + const isValidJWT = await verifyHybridJWT(JWT_SECRET, JWKS_ENDPOINT, token); if (!isValidJWT) { return getResponse({ msg: "Invalid JWT" }, STATUS_CODE.Unauthorized); From 0335b2434d9ac3996d797337c079d1d4f188ed06 Mon Sep 17 00:00:00 2001 From: Geoffrey Sechter Date: Tue, 10 Mar 2026 07:06:26 -0700 Subject: [PATCH 112/117] chore(ci): skip Link job on fork PRs (#4915) The Link job requires SUPABASE_ACCESS_TOKEN and SUPABASE_PROJECT_ID secrets which are unavailable to fork PRs. Without this guard, the job always fails on external contributions, creating a misleading red CI status that distracts both contributors and reviewers. The if condition checks github.event.pull_request.head.repo.fork and skips the job entirely for fork PRs, showing it as 'skipped' instead of 'failed'. On pushes to develop and PRs from branches within the main repo, the job continues to run normally. Co-authored-by: Andrew Valleteau --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3f8d28368e..344738f138 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -89,6 +89,7 @@ jobs: link: name: Link + if: ${{ !github.event.pull_request.head.repo.fork }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 From 3db642adde91f7f784437dd54af863791375411e Mon Sep 17 00:00:00 2001 From: Vaibhav <117663341+7ttp@users.noreply.github.com> Date: Tue, 10 Mar 2026 21:46:01 +0530 Subject: [PATCH 113/117] fix: add privilege migration note for db dump (#4885) docs: add privilege migration note for db dump Co-authored-by: Kalleby Santos <105971119+kallebysantos@users.noreply.github.com> --- docs/supabase/db/dump.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/supabase/db/dump.md b/docs/supabase/db/dump.md index 2ccfef091e..3d5c4fae54 100644 --- a/docs/supabase/db/dump.md +++ b/docs/supabase/db/dump.md @@ -7,3 +7,12 @@ Requires your local project to be linked to a remote database by running `supaba Runs `pg_dump` in a container with additional flags to exclude Supabase managed schemas. The ignored schemas include auth, storage, and those created by extensions. The default dump does not contain any data or custom roles. To dump those contents explicitly, specify either the `--data-only` and `--role-only` flag. + +### Note on Privilege Migration + +When restoring to a new project, tables inherit ALL privileges from default privileges in the target database. To preserve specific privileges from your dump, revoke defaults before restoring: + +```sql +-- Run BEFORE restoring your schema +ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON TABLES FROM anon, authenticated; +``` From b4e7e64115741a0a3c359a7307c2864d1fe3bf40 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2026 00:53:57 +0000 Subject: [PATCH 114/117] chore(deps): bump the go-minor group across 2 directories with 1 update (#4948) Bumps the go-minor group with 1 update in the / directory: [github.com/tidwall/jsonc](https://github.com/tidwall/jsonc). Bumps the go-minor group with 1 update in the /pkg directory: [github.com/tidwall/jsonc](https://github.com/tidwall/jsonc). Updates `github.com/tidwall/jsonc` from 0.3.2 to 0.3.3 - [Commits](https://github.com/tidwall/jsonc/compare/v0.3.2...v0.3.3) Updates `github.com/tidwall/jsonc` from 0.3.2 to 0.3.3 - [Commits](https://github.com/tidwall/jsonc/compare/v0.3.2...v0.3.3) --- updated-dependencies: - dependency-name: github.com/tidwall/jsonc dependency-version: 0.3.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-minor - dependency-name: github.com/tidwall/jsonc dependency-version: 0.3.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- pkg/go.mod | 2 +- pkg/go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 7319abe1ab..af0835be17 100644 --- a/go.mod +++ b/go.mod @@ -50,7 +50,7 @@ require ( github.com/stretchr/testify v1.11.1 github.com/stripe/pg-schema-diff v1.0.5 github.com/supabase/cli/pkg v1.0.0 - github.com/tidwall/jsonc v0.3.2 + github.com/tidwall/jsonc v0.3.3 github.com/withfig/autocomplete-tools/packages/cobra v1.2.0 github.com/zalando/go-keyring v0.2.6 go.opentelemetry.io/otel v1.42.0 diff --git a/go.sum b/go.sum index 97727f4fe4..f2691a9dc7 100644 --- a/go.sum +++ b/go.sum @@ -1068,8 +1068,8 @@ github.com/tetafro/godot v1.5.1 h1:PZnjCol4+FqaEzvZg5+O8IY2P3hfY9JzRBNPv1pEDS4= github.com/tetafro/godot v1.5.1/go.mod h1:cCdPtEndkmqqrhiCfkmxDodMQJ/f3L1BCNskCUZdTwk= 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= -github.com/tidwall/jsonc v0.3.2/go.mod h1:dw+3CIxqHi+t8eFSpzzMlcVYxKp08UP5CD8/uSFCyJE= +github.com/tidwall/jsonc v0.3.3 h1:RVQqL3xFfDkKKXIDsrBiVQiEpBtxoKbmMXONb2H/y2w= +github.com/tidwall/jsonc v0.3.3/go.mod h1:dw+3CIxqHi+t8eFSpzzMlcVYxKp08UP5CD8/uSFCyJE= github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375 h1:QB54BJwA6x8QU9nHY3xJSZR2kX9bgpZekRKGkLTmEXA= github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375/go.mod h1:xRroudyp5iVtxKqZCrA6n2TLFRBf8bmnjr1UD4x+z7g= github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67 h1:9LPGD+jzxMlnk5r6+hJnar67cgpDIz/iyD+rfl5r2Vk= diff --git a/pkg/go.mod b/pkg/go.mod index c45734b6e9..6ed23c5070 100644 --- a/pkg/go.mod +++ b/pkg/go.mod @@ -24,7 +24,7 @@ require ( github.com/spf13/afero v1.15.0 github.com/spf13/viper v1.21.0 github.com/stretchr/testify v1.11.1 - github.com/tidwall/jsonc v0.3.2 + github.com/tidwall/jsonc v0.3.3 golang.org/x/mod v0.33.0 google.golang.org/grpc v1.79.2 ) diff --git a/pkg/go.sum b/pkg/go.sum index 98408e3a7c..d38f78054f 100644 --- a/pkg/go.sum +++ b/pkg/go.sum @@ -186,8 +186,8 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/tidwall/jsonc v0.3.2 h1:ZTKrmejRlAJYdn0kcaFqRAKlxxFIC21pYq8vLa4p2Wc= -github.com/tidwall/jsonc v0.3.2/go.mod h1:dw+3CIxqHi+t8eFSpzzMlcVYxKp08UP5CD8/uSFCyJE= +github.com/tidwall/jsonc v0.3.3 h1:RVQqL3xFfDkKKXIDsrBiVQiEpBtxoKbmMXONb2H/y2w= +github.com/tidwall/jsonc v0.3.3/go.mod h1:dw+3CIxqHi+t8eFSpzzMlcVYxKp08UP5CD8/uSFCyJE= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= From f9cc8a96f3e60657eb7d147a10b36b91e77f1ca9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Mar 2026 15:44:42 +0100 Subject: [PATCH 115/117] chore(deps): bump github.com/charmbracelet/glamour from 0.10.0 to 1.0.0 (#4945) Bumps [github.com/charmbracelet/glamour](https://github.com/charmbracelet/glamour) from 0.10.0 to 1.0.0. - [Release notes](https://github.com/charmbracelet/glamour/releases) - [Commits](https://github.com/charmbracelet/glamour/compare/v0.10.0...v1.0.0) --- updated-dependencies: - dependency-name: github.com/charmbracelet/glamour dependency-version: 1.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 21 ++++++++++----------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index af0835be17..df59c3b560 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/cenkalti/backoff/v4 v4.3.0 github.com/charmbracelet/bubbles v1.0.0 github.com/charmbracelet/bubbletea v1.3.10 - github.com/charmbracelet/glamour v0.10.0 + github.com/charmbracelet/glamour v1.0.0 github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 github.com/compose-spec/compose-go/v2 v2.9.1 github.com/containerd/errdefs v1.0.0 @@ -81,7 +81,7 @@ require ( github.com/OpenPeeDeeP/depguard/v2 v2.2.1 // indirect github.com/ProtonMail/go-crypto v1.1.6 // indirect github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect - github.com/alecthomas/chroma/v2 v2.17.2 // indirect + github.com/alecthomas/chroma/v2 v2.20.0 // indirect github.com/alecthomas/go-check-sumtype v0.3.1 // indirect github.com/alexkohler/nakedret/v2 v2.0.6 // indirect github.com/alexkohler/prealloc v1.0.0 // indirect @@ -401,8 +401,8 @@ require ( github.com/yagipy/maintidx v1.0.0 // indirect github.com/yeya24/promlinter v0.3.0 // indirect github.com/ykadowak/zerologlint v0.1.5 // indirect - github.com/yuin/goldmark v1.7.8 // indirect - github.com/yuin/goldmark-emoji v1.0.5 // indirect + github.com/yuin/goldmark v1.7.13 // indirect + github.com/yuin/goldmark-emoji v1.0.6 // indirect github.com/zclconf/go-cty v1.17.0 // indirect gitlab.com/bosi/decorder v0.4.2 // indirect go-simpler.org/musttag v0.13.1 // indirect diff --git a/go.sum b/go.sum index f2691a9dc7..95e8407ef2 100644 --- a/go.sum +++ b/go.sum @@ -50,12 +50,12 @@ github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpH github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= -github.com/alecthomas/chroma/v2 v2.17.2 h1:Rm81SCZ2mPoH+Q8ZCc/9YvzPUN/E7HgPiPJD8SLV6GI= -github.com/alecthomas/chroma/v2 v2.17.2/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk= +github.com/alecthomas/chroma/v2 v2.20.0 h1:sfIHpxPyR07/Oylvmcai3X/exDlE8+FA820NTz+9sGw= +github.com/alecthomas/chroma/v2 v2.20.0/go.mod h1:e7tViK0xh/Nf4BYHl00ycY6rV7b8iXBksI9E359yNmA= github.com/alecthomas/go-check-sumtype v0.3.1 h1:u9aUvbGINJxLVXiFvHUlPEaD7VDULsrxJb4Aq31NLkU= github.com/alecthomas/go-check-sumtype v0.3.1/go.mod h1:A8TSiN3UPRw3laIgWEUOHHLPa6/r9MtoigdlP5h3K/E= -github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= -github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +github.com/alecthomas/repr v0.5.1 h1:E3G4t2QbHTSNpPKBgMTln5KLkZHLOcU7r37J4pXBuIg= +github.com/alecthomas/repr v0.5.1/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alexkohler/nakedret/v2 v2.0.6 h1:ME3Qef1/KIKr3kWX3nti3hhgNxw6aqN5pZmQiFSsuzQ= @@ -167,8 +167,8 @@ github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlv github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk= github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk= -github.com/charmbracelet/glamour v0.10.0 h1:MtZvfwsYCx8jEPFJm3rIBFIMZUfUJ765oX8V6kXldcY= -github.com/charmbracelet/glamour v0.10.0/go.mod h1:f+uf+I/ChNmqo087elLnVdCiVgjSKWuXa/l6NU2ndYk= +github.com/charmbracelet/glamour v1.0.0 h1:AWMLOVFHTsysl4WV8T8QgkQ0s/ZNZo7CiE4WKhk8l08= +github.com/charmbracelet/glamour v1.0.0/go.mod h1:DSdohgOBkMr2ZQNhw4LZxSGpx3SvpeujNoXrQyH2hxo= github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 h1:ZR7e0ro+SZZiIZD7msJyA+NjkCNNavuiPBLgerbOziE= @@ -1137,11 +1137,10 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= -github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -github.com/yuin/goldmark-emoji v1.0.5 h1:EMVWyCGPlXJfUXBXpuMu+ii3TIaxbVBnEX9uaDC4cIk= -github.com/yuin/goldmark-emoji v1.0.5/go.mod h1:tTkZEbwu5wkPmgTcitqddVxY9osFZiavD+r4AzQrh1U= +github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= +github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= +github.com/yuin/goldmark-emoji v1.0.6 h1:QWfF2FYaXwL74tfGOW5izeiZepUDroDJfWubQI9HTHs= +github.com/yuin/goldmark-emoji v1.0.6/go.mod h1:ukxJDKFpdFb5x0a5HqbdlcKtebh086iJpI31LTKmWuA= github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8ua9s= github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI= github.com/zclconf/go-cty v1.17.0 h1:seZvECve6XX4tmnvRzWtJNHdscMtYEx5R7bnnVyd/d0= From 8687a9b62c89a590e239422ed7c8ba9847b8e65e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Mar 2026 17:21:00 +0100 Subject: [PATCH 116/117] chore(deps): bump the actions-major group across 1 directory with 6 updates (#4934) Bumps the actions-major group with 6 updates in the / directory: | Package | From | To | | --- | --- | --- | | [actions/upload-artifact](https://github.com/actions/upload-artifact) | `6` | `7` | | [actions/download-artifact](https://github.com/actions/download-artifact) | `7` | `8` | | [docker/login-action](https://github.com/docker/login-action) | `3` | `4` | | [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `3` | `4` | | [docker/build-push-action](https://github.com/docker/build-push-action) | `6` | `7` | | [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) | `6` | `7` | Updates `actions/upload-artifact` from 6 to 7 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v6...v7) Updates `actions/download-artifact` from 7 to 8 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v7...v8) Updates `docker/login-action` from 3 to 4 - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v3...v4) Updates `docker/setup-buildx-action` from 3 to 4 - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4) Updates `docker/build-push-action` from 6 to 7 - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v6...v7) Updates `goreleaser/goreleaser-action` from 6 to 7 - [Release notes](https://github.com/goreleaser/goreleaser-action/releases) - [Commits](https://github.com/goreleaser/goreleaser-action/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions-major - dependency-name: actions/download-artifact dependency-version: '8' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions-major - dependency-name: docker/login-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions-major - dependency-name: docker/setup-buildx-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions-major - dependency-name: docker/build-push-action dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions-major - dependency-name: goreleaser/goreleaser-action dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andrew Valleteau --- .github/workflows/ci.yml | 4 ++-- .github/workflows/install.yml | 12 ++++++------ .github/workflows/mirror-image.yml | 4 ++-- .github/workflows/pg-prove.yml | 14 +++++++------- .github/workflows/publish-migra.yml | 14 +++++++------- .github/workflows/release-beta.yml | 2 +- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 344738f138..67deb0d279 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,7 +28,7 @@ jobs: go tool gotestsum -- -race -v -count=1 ./... \ -coverpkg="./cmd/...,./internal/...,${pkgs}" -coverprofile=coverage.out - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7 with: name: code-coverage-report path: coverage.out @@ -39,7 +39,7 @@ jobs: - test runs-on: ubuntu-latest steps: - - uses: actions/download-artifact@v7 + - uses: actions/download-artifact@v8 with: name: code-coverage-report - uses: coverallsapp/github-action@v2 diff --git a/.github/workflows/install.yml b/.github/workflows/install.yml index a28df0d176..8b7296ea45 100644 --- a/.github/workflows/install.yml +++ b/.github/workflows/install.yml @@ -30,7 +30,7 @@ jobs: mv tmp.$$.json package.json npm pack - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7 with: name: installer path: supabase-1.28.0.tgz @@ -43,7 +43,7 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/download-artifact@v7 + - uses: actions/download-artifact@v8 with: name: installer @@ -59,7 +59,7 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/download-artifact@v7 + - uses: actions/download-artifact@v8 with: name: installer @@ -75,7 +75,7 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/download-artifact@v7 + - uses: actions/download-artifact@v8 with: name: installer @@ -98,7 +98,7 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/download-artifact@v7 + - uses: actions/download-artifact@v8 with: name: installer @@ -117,7 +117,7 @@ jobs: os: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/download-artifact@v7 + - uses: actions/download-artifact@v8 with: name: installer diff --git a/.github/workflows/mirror-image.yml b/.github/workflows/mirror-image.yml index 0f8204f23d..1cd9e2d949 100644 --- a/.github/workflows/mirror-image.yml +++ b/.github/workflows/mirror-image.yml @@ -34,10 +34,10 @@ jobs: with: role-to-assume: ${{ secrets.PROD_AWS_ROLE }} aws-region: us-east-1 - - uses: docker/login-action@v3 + - uses: docker/login-action@v4 with: registry: public.ecr.aws - - uses: docker/login-action@v3 + - uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} diff --git a/.github/workflows/pg-prove.yml b/.github/workflows/pg-prove.yml index 052ac65832..83812a58ee 100644 --- a/.github/workflows/pg-prove.yml +++ b/.github/workflows/pg-prove.yml @@ -12,8 +12,8 @@ jobs: outputs: image_tag: supabase/pg_prove:${{ steps.version.outputs.pg_prove }} steps: - - uses: docker/setup-buildx-action@v3 - - uses: docker/build-push-action@v6 + - uses: docker/setup-buildx-action@v4 + - uses: docker/build-push-action@v7 with: load: true context: https://github.com/horrendo/pg_prove.git @@ -43,15 +43,15 @@ jobs: image_digest: ${{ steps.build.outputs.digest }} steps: - run: docker context create builders - - uses: docker/setup-buildx-action@v3 + - uses: docker/setup-buildx-action@v4 with: endpoint: builders - - uses: docker/login-action@v3 + - uses: docker/login-action@v4 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - id: build - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: push: true context: https://github.com/horrendo/pg_prove.git @@ -66,8 +66,8 @@ jobs: - build_image runs-on: ubuntu-latest steps: - - uses: docker/setup-buildx-action@v3 - - uses: docker/login-action@v3 + - uses: docker/setup-buildx-action@v4 + - uses: docker/login-action@v4 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} diff --git a/.github/workflows/publish-migra.yml b/.github/workflows/publish-migra.yml index b4a2625c54..e0223a6d60 100644 --- a/.github/workflows/publish-migra.yml +++ b/.github/workflows/publish-migra.yml @@ -12,8 +12,8 @@ jobs: outputs: image_tag: supabase/migra:${{ steps.version.outputs.migra }} steps: - - uses: docker/setup-buildx-action@v3 - - uses: docker/build-push-action@v6 + - uses: docker/setup-buildx-action@v4 + - uses: docker/build-push-action@v7 with: load: true context: https://github.com/djrobstep/migra.git @@ -43,15 +43,15 @@ jobs: image_digest: ${{ steps.build.outputs.digest }} steps: - run: docker context create builders - - uses: docker/setup-buildx-action@v3 + - uses: docker/setup-buildx-action@v4 with: endpoint: builders - - uses: docker/login-action@v3 + - uses: docker/login-action@v4 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - id: build - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: push: true context: https://github.com/djrobstep/migra.git @@ -66,8 +66,8 @@ jobs: - build_image runs-on: ubuntu-latest steps: - - uses: docker/setup-buildx-action@v3 - - uses: docker/login-action@v3 + - uses: docker/setup-buildx-action@v4 + - uses: docker/login-action@v4 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} diff --git a/.github/workflows/release-beta.yml b/.github/workflows/release-beta.yml index fca87826e8..b354f785d0 100644 --- a/.github/workflows/release-beta.yml +++ b/.github/workflows/release-beta.yml @@ -44,7 +44,7 @@ jobs: go-version-file: go.mod cache: true - - uses: goreleaser/goreleaser-action@v6 + - uses: goreleaser/goreleaser-action@v7 with: distribution: goreleaser version: ~> v2 From 5025dd2abcde1c5575ca31624bf2e83b696d7f43 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 00:16:15 +0000 Subject: [PATCH 117/117] chore(deps): bump the go-minor group across 2 directories with 4 updates (#4952) Bumps the go-minor group with 3 updates in the / directory: [github.com/olekukonko/tablewriter](https://github.com/olekukonko/tablewriter), [golang.org/x/mod](https://github.com/golang/mod) and [golang.org/x/net](https://github.com/golang/net). Bumps the go-minor group with 1 update in the /pkg directory: [golang.org/x/mod](https://github.com/golang/mod). Updates `github.com/olekukonko/tablewriter` from 1.1.3 to 1.1.4 - [Release notes](https://github.com/olekukonko/tablewriter/releases) - [Commits](https://github.com/olekukonko/tablewriter/compare/v1.1.3...v1.1.4) Updates `golang.org/x/mod` from 0.33.0 to 0.34.0 - [Commits](https://github.com/golang/mod/compare/v0.33.0...v0.34.0) Updates `golang.org/x/net` from 0.51.0 to 0.52.0 - [Commits](https://github.com/golang/net/compare/v0.51.0...v0.52.0) Updates `golang.org/x/term` from 0.40.0 to 0.41.0 - [Commits](https://github.com/golang/term/compare/v0.40.0...v0.41.0) Updates `golang.org/x/mod` from 0.33.0 to 0.34.0 - [Commits](https://github.com/golang/mod/compare/v0.33.0...v0.34.0) --- updated-dependencies: - dependency-name: github.com/olekukonko/tablewriter dependency-version: 1.1.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-minor - dependency-name: golang.org/x/mod dependency-version: 0.34.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor - dependency-name: golang.org/x/net dependency-version: 0.52.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor - dependency-name: golang.org/x/term dependency-version: 0.41.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor - dependency-name: golang.org/x/mod dependency-version: 0.34.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 27 +++++++++++++-------------- go.sum | 54 ++++++++++++++++++++++++++---------------------------- pkg/go.mod | 4 ++-- pkg/go.sum | 4 ++-- 4 files changed, 43 insertions(+), 46 deletions(-) diff --git a/go.mod b/go.mod index df59c3b560..dc28821eae 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,7 @@ require ( github.com/muesli/reflow v0.3.0 github.com/multigres/multigres v0.0.0-20260126223308-f5a52171bbc4 github.com/oapi-codegen/nullable v1.1.0 - github.com/olekukonko/tablewriter v1.1.3 + github.com/olekukonko/tablewriter v1.1.4 github.com/slack-go/slack v0.19.0 github.com/spf13/afero v1.15.0 github.com/spf13/cobra v1.10.2 @@ -54,10 +54,10 @@ require ( github.com/withfig/autocomplete-tools/packages/cobra v1.2.0 github.com/zalando/go-keyring v0.2.6 go.opentelemetry.io/otel v1.42.0 - golang.org/x/mod v0.33.0 - golang.org/x/net v0.51.0 + golang.org/x/mod v0.34.0 + golang.org/x/net v0.52.0 golang.org/x/oauth2 v0.36.0 - golang.org/x/term v0.40.0 + golang.org/x/term v0.41.0 google.golang.org/grpc v1.79.2 gopkg.in/yaml.v3 v3.0.1 ) @@ -130,9 +130,8 @@ require ( github.com/charmbracelet/x/term v0.2.2 // indirect github.com/chavacava/garif v0.1.0 // indirect github.com/ckaznocha/intrange v0.3.1 // indirect - github.com/clipperhouse/displaywidth v0.9.0 // indirect - github.com/clipperhouse/stringish v0.1.1 // indirect - github.com/clipperhouse/uax29/v2 v2.5.0 // indirect + github.com/clipperhouse/displaywidth v0.10.0 // indirect + github.com/clipperhouse/uax29/v2 v2.6.0 // indirect github.com/cloudflare/circl v1.6.3 // indirect github.com/containerd/console v1.0.5 // indirect github.com/containerd/containerd/api v1.9.0 // indirect @@ -323,8 +322,8 @@ require ( github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect - github.com/olekukonko/errors v1.1.0 // indirect - github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0 // indirect + github.com/olekukonko/errors v1.2.0 // indirect + github.com/olekukonko/ll v0.1.6 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect github.com/pelletier/go-toml v1.9.5 // indirect @@ -427,13 +426,13 @@ require ( go.uber.org/zap v1.27.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.48.0 // indirect + golang.org/x/crypto v0.49.0 // indirect golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac // indirect - golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.41.0 // indirect - golang.org/x/text v0.34.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/sys v0.42.0 // indirect + golang.org/x/text v0.35.0 // indirect golang.org/x/time v0.11.0 // indirect - golang.org/x/tools v0.41.0 // indirect + golang.org/x/tools v0.42.0 // indirect golang.org/x/tools/go/expect v0.1.1-deprecated // indirect golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b // indirect diff --git a/go.sum b/go.sum index 95e8407ef2..c18ac2d16b 100644 --- a/go.sum +++ b/go.sum @@ -190,12 +190,10 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/ckaznocha/intrange v0.3.1 h1:j1onQyXvHUsPWujDH6WIjhyH26gkRt/txNlV7LspvJs= github.com/ckaznocha/intrange v0.3.1/go.mod h1:QVepyz1AkUoFQkpEqksSYpNpUo3c5W7nWh/s6SHIJJk= -github.com/clipperhouse/displaywidth v0.9.0 h1:Qb4KOhYwRiN3viMv1v/3cTBlz3AcAZX3+y9OLhMtAtA= -github.com/clipperhouse/displaywidth v0.9.0/go.mod h1:aCAAqTlh4GIVkhQnJpbL0T/WfcrJXHcj8C0yjYcjOZA= -github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= -github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= -github.com/clipperhouse/uax29/v2 v2.5.0 h1:x7T0T4eTHDONxFJsL94uKNKPHrclyFI0lm7+w94cO8U= -github.com/clipperhouse/uax29/v2 v2.5.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= +github.com/clipperhouse/displaywidth v0.10.0 h1:GhBG8WuerxjFQQYeuZAeVTuyxuX+UraiZGD4HJQ3Y8g= +github.com/clipperhouse/displaywidth v0.10.0/go.mod h1:XqJajYsaiEwkxOj4bowCTMcT1SgvHo9flfF3jQasdbs= +github.com/clipperhouse/uax29/v2 v2.6.0 h1:z0cDbUV+aPASdFb2/ndFnS9ts/WNXgTNNGFoKXuhpos= +github.com/clipperhouse/uax29/v2 v2.6.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= 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.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8= @@ -842,12 +840,12 @@ github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletI github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 h1:zrbMGy9YXpIeTnGj4EljqMiZsIcE09mmF8XsD5AYOJc= github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6/go.mod h1:rEKTHC9roVVicUIfZK7DYrdIoM0EOr8mK1Hj5s3JjH0= -github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM= -github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y= -github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0 h1:jrYnow5+hy3WRDCBypUFvVKNSPPCdqgSXIE9eJDD8LM= -github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0/go.mod h1:b52bVQRRPObe+yyBl0TxNfhesL0nedD4Cht0/zx55Ew= -github.com/olekukonko/tablewriter v1.1.3 h1:VSHhghXxrP0JHl+0NnKid7WoEmd9/urKRJLysb70nnA= -github.com/olekukonko/tablewriter v1.1.3/go.mod h1:9VU0knjhmMkXjnMKrZ3+L2JhhtsQ/L38BbL3CRNE8tM= +github.com/olekukonko/errors v1.2.0 h1:10Zcn4GeV59t/EGqJc8fUjtFT/FuUh5bTMzZ1XwmCRo= +github.com/olekukonko/errors v1.2.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y= +github.com/olekukonko/ll v0.1.6 h1:lGVTHO+Qc4Qm+fce/2h2m5y9LvqaW+DCN7xW9hsU3uA= +github.com/olekukonko/ll v0.1.6/go.mod h1:NVUmjBb/aCtUpjKk75BhWrOlARz3dqsM+OtszpY4o88= +github.com/olekukonko/tablewriter v1.1.4 h1:ORUMI3dXbMnRlRggJX3+q7OzQFDdvgbN9nVWj1drm6I= +github.com/olekukonko/tablewriter v1.1.4/go.mod h1:+kedxuyTtgoZLwif3P1Em4hARJs+mVnzKxmsCL/C5RY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= @@ -1232,8 +1230,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= 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.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= @@ -1254,8 +1252,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= -golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= +golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1281,8 +1279,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1297,8 +1295,8 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1343,8 +1341,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= -golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= 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= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1355,8 +1353,8 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= 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.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= -golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= +golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= +golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -1369,8 +1367,8 @@ golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= +golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1401,8 +1399,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= -golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= -golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM= golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= diff --git a/pkg/go.mod b/pkg/go.mod index 6ed23c5070..ec55d969bf 100644 --- a/pkg/go.mod +++ b/pkg/go.mod @@ -1,6 +1,6 @@ module github.com/supabase/cli/pkg -go 1.24.10 +go 1.25.0 require ( github.com/BurntSushi/toml v1.6.0 @@ -25,7 +25,7 @@ require ( github.com/spf13/viper v1.21.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/jsonc v0.3.3 - golang.org/x/mod v0.33.0 + golang.org/x/mod v0.34.0 google.golang.org/grpc v1.79.2 ) diff --git a/pkg/go.sum b/pkg/go.sum index d38f78054f..1611824c64 100644 --- a/pkg/go.sum +++ b/pkg/go.sum @@ -224,8 +224,8 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= -golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= +golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=