diff --git a/.github/workflows/api-sync.yml b/.github/workflows/api-sync.yml index 8efeabf14..0295e028f 100644 --- a/.github/workflows/api-sync.yml +++ b/.github/workflows/api-sync.yml @@ -36,12 +36,19 @@ jobs: echo "has_changes=true" >> $GITHUB_OUTPUT fi + - name: Generate token + id: app-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + - name: Create Pull Request if: steps.check.outputs.has_changes == 'true' id: cpr uses: peter-evans/create-pull-request@v7 with: - token: ${{ secrets.GH_PAT }} + token: ${{ steps.app-token.outputs.token }} commit-message: "chore: sync API types from infrastructure" title: "chore: sync API types from infrastructure" body: | @@ -58,4 +65,4 @@ jobs: if: steps.check.outputs.has_changes == 'true' run: gh pr merge --auto --squash "${{ steps.cpr.outputs.pull-request-number }}" env: - GH_TOKEN: ${{ secrets.GH_PAT }} + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 5cf15ef53..89933c333 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -22,12 +22,19 @@ jobs: with: github-token: "${{ secrets.GITHUB_TOKEN }}" + - name: Generate token + id: app-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + # Here the PR gets approved. - name: Approve a PR if: ${{ steps.meta.outputs.update-type == 'version-update:semver-patch' || (!startsWith(steps.meta.outputs.previous-version, '0.') && steps.meta.outputs.update-type == 'version-update:semver-minor') }} run: gh pr review --approve "${{ github.event.pull_request.html_url }}" env: - GITHUB_TOKEN: ${{ secrets.GH_PAT }} + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} # Finally, this sets the PR to allow auto-merging for patch and minor # updates if all checks pass @@ -35,4 +42,4 @@ jobs: if: ${{ steps.meta.outputs.update-type == 'version-update:semver-patch' || (!startsWith(steps.meta.outputs.previous-version, '0.') && steps.meta.outputs.update-type == 'version-update:semver-minor') }} run: gh pr merge --auto --squash "${{ github.event.pull_request.html_url }}" env: - GITHUB_TOKEN: ${{ secrets.GH_PAT }} + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 6ab69d0d2..6c0bed92b 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -17,6 +17,6 @@ jobs: - uses: actions/checkout@v6 with: fetch-depth: 0 - - run: gh pr create -B main -H develop --title 'Prod deploy' --fill + - run: gh pr create -B main -H develop --title 'Prod deploy' --label 'do not merge' --fill env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/fast-forward.yml b/.github/workflows/fast-forward.yml index 7b198d129..c2c289c04 100644 --- a/.github/workflows/fast-forward.yml +++ b/.github/workflows/fast-forward.yml @@ -30,6 +30,8 @@ jobs: permissions: contents: write packages: write + # Required for npm OIDC + id-token: write # Call workflow explicitly because events from actions cannot trigger more actions uses: ./.github/workflows/release.yml secrets: inherit diff --git a/.github/workflows/release-beta.yml b/.github/workflows/release-beta.yml index a74314299..7c7f87e03 100644 --- a/.github/workflows/release-beta.yml +++ b/.github/workflows/release-beta.yml @@ -70,9 +70,21 @@ jobs: with: go-version-file: go.mod cache: true + # use GitHub app to create a release token that can publish to homebrew-tap and scoop + - name: Generate token + id: app-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: | + cli + homebrew-tap + scoop-bucket - run: go run tools/publish/main.go --beta "${{ needs.release.outputs.new-release-version }}" env: - GITHUB_TOKEN: ${{ secrets.GH_PAT }} + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} publish: name: Publish NPM @@ -80,14 +92,15 @@ jobs: - release - goreleaser if: needs.release.outputs.new-release-published == 'true' + permissions: + contents: read + id-token: write runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: - node-version: "16.x" - registry-url: "https://registry.npmjs.org" + node-version: latest + registry-url: https://registry.npmjs.org - run: npm --git-tag-version=false version ${{ needs.release.outputs.new-release-version }} - run: npm publish --tag ${{ needs.release.outputs.new-release-channel }} - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9b85ec4a5..1acc7f28f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,6 +9,8 @@ on: permissions: contents: write packages: write + # Required for npm OIDC + id-token: write jobs: settings: @@ -17,6 +19,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} outputs: release_tag: ${{ steps.prerelease.outputs.tagName }} + app_token: ${{ steps.app-token.outputs.token }} steps: - uses: actions/checkout@v6 - id: prerelease @@ -24,6 +27,17 @@ jobs: gh release list --limit 1 --json tagName --jq \ '.[]|to_entries|map("\(.key)=\(.value|tostring)")|.[]' >> $GITHUB_OUTPUT - run: gh release edit ${{ steps.prerelease.outputs.tagName }} --latest --prerelease=false + - id: app-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: | + cli + homebrew-tap + scoop-bucket + supabase commit: name: Publish Brew and Scoop @@ -38,12 +52,15 @@ jobs: cache: true - run: go run tools/publish/main.go ${{ needs.settings.outputs.release_tag }} env: - GITHUB_TOKEN: ${{ secrets.GH_PAT }} + GITHUB_TOKEN: ${{ needs.settings.outputs.app_token }} publish: name: Publish NPM needs: - settings + permissions: + contents: read + id-token: write uses: ./.github/workflows/tag-npm.yml with: release: ${{ needs.settings.outputs.release_tag }} @@ -51,6 +68,8 @@ jobs: compose: name: Bump self-hosted versions + needs: + - settings runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 @@ -60,11 +79,12 @@ jobs: cache: true - run: go run tools/selfhost/main.go env: - GITHUB_TOKEN: ${{ secrets.GH_PAT }} + GITHUB_TOKEN: ${{ needs.settings.outputs.app_token }} changelog: name: Publish changelog needs: + - settings - commit - publish runs-on: ubuntu-latest @@ -76,7 +96,7 @@ jobs: cache: true - run: go run tools/changelog/main.go ${{ secrets.SLACK_CHANNEL }} env: - GITHUB_TOKEN: ${{ secrets.GH_PAT }} + GITHUB_TOKEN: ${{ needs.settings.outputs.app_token }} SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }} docs: @@ -92,4 +112,4 @@ jobs: cache: true - run: go run docs/main.go ${{ needs.settings.outputs.release_tag }} | go run tools/bumpdoc/main.go apps/docs/spec/cli_v1_commands.yaml env: - GITHUB_TOKEN: ${{ secrets.GH_PAT }} + GITHUB_TOKEN: ${{ needs.settings.outputs.app_token }} diff --git a/.github/workflows/tag-npm.yml b/.github/workflows/tag-npm.yml index fe239608c..53a7c9a31 100644 --- a/.github/workflows/tag-npm.yml +++ b/.github/workflows/tag-npm.yml @@ -15,6 +15,7 @@ on: permissions: contents: read + id-token: write jobs: tag: @@ -22,11 +23,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 with: - node-version: "16.x" - registry-url: "https://registry.npmjs.org" + node-version: latest + registry-url: https://registry.npmjs.org + - run: npm dist-tag add "supabase@${RELEASE_TAG#v}" latest env: RELEASE_TAG: ${{ inputs.release }} - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/internal/utils/flags/db_url.go b/internal/utils/flags/db_url.go index 26282d346..3ec94073b 100644 --- a/internal/utils/flags/db_url.go +++ b/internal/utils/flags/db_url.go @@ -133,7 +133,8 @@ func NewDbConfigWithPassword(ctx context.Context, projectRef string) (pgconn.Con logger := utils.GetDebugLogger() // Use pooler if host is not reachable directly d := net.Dialer{Timeout: 5 * time.Second} - if conn, err := d.DialContext(ctx, "udp", config.Host+":53"); err == nil { + addr := fmt.Sprintf("%s:%d", config.Host, config.Port) + if conn, err := d.DialContext(ctx, "tcp", addr); err == nil { if err := conn.Close(); err != nil { fmt.Fprintln(logger, err) } diff --git a/pkg/api/client.gen.go b/pkg/api/client.gen.go index bf73deb2a..f6411a0c1 100644 --- a/pkg/api/client.gen.go +++ b/pkg/api/client.gen.go @@ -372,6 +372,14 @@ type ClientInterface interface { V1UpdatePostgresConfig(ctx context.Context, ref string, body V1UpdatePostgresConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // V1GetRealtimeConfig request + V1GetRealtimeConfig(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) + + // V1UpdateRealtimeConfigWithBody request with any body + V1UpdateRealtimeConfigWithBody(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + V1UpdateRealtimeConfig(ctx context.Context, ref string, body V1UpdateRealtimeConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // V1GetStorageConfig request V1GetStorageConfig(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -1858,6 +1866,42 @@ func (c *Client) V1UpdatePostgresConfig(ctx context.Context, ref string, body V1 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 { + 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) V1UpdateRealtimeConfigWithBody(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewV1UpdateRealtimeConfigRequestWithBody(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) V1UpdateRealtimeConfig(ctx context.Context, ref string, body V1UpdateRealtimeConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewV1UpdateRealtimeConfigRequest(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) V1GetStorageConfig(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewV1GetStorageConfigRequest(c.Server, ref) if err != nil { @@ -6852,6 +6896,87 @@ func NewV1UpdatePostgresConfigRequestWithBody(server string, ref string, content return req, nil } +// NewV1GetRealtimeConfigRequest generates requests for V1GetRealtimeConfig +func NewV1GetRealtimeConfigRequest(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", 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 +} + +// NewV1UpdateRealtimeConfigRequest calls the generic V1UpdateRealtimeConfig builder with application/json body +func NewV1UpdateRealtimeConfigRequest(server string, ref string, body V1UpdateRealtimeConfigJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewV1UpdateRealtimeConfigRequestWithBody(server, ref, "application/json", bodyReader) +} + +// NewV1UpdateRealtimeConfigRequestWithBody generates requests for V1UpdateRealtimeConfig with any type of body +func NewV1UpdateRealtimeConfigRequestWithBody(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/realtime", pathParam0) + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("PATCH", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + // NewV1GetStorageConfigRequest generates requests for V1GetStorageConfig func NewV1GetStorageConfigRequest(server string, ref string) (*http.Request, error) { var err error @@ -10520,6 +10645,14 @@ type ClientWithResponsesInterface interface { V1UpdatePostgresConfigWithResponse(ctx context.Context, ref string, body V1UpdatePostgresConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*V1UpdatePostgresConfigResponse, error) + // V1GetRealtimeConfigWithResponse request + V1GetRealtimeConfigWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetRealtimeConfigResponse, error) + + // V1UpdateRealtimeConfigWithBodyWithResponse request with any body + V1UpdateRealtimeConfigWithBodyWithResponse(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*V1UpdateRealtimeConfigResponse, error) + + V1UpdateRealtimeConfigWithResponse(ctx context.Context, ref string, body V1UpdateRealtimeConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*V1UpdateRealtimeConfigResponse, error) + // V1GetStorageConfigWithResponse request V1GetStorageConfigWithResponse(ctx context.Context, ref string, reqEditors ...RequestEditorFn) (*V1GetStorageConfigResponse, error) @@ -12497,6 +12630,49 @@ func (r V1UpdatePostgresConfigResponse) StatusCode() int { return 0 } +type V1GetRealtimeConfigResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *RealtimeConfigResponse +} + +// Status returns HTTPResponse.Status +func (r V1GetRealtimeConfigResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r V1GetRealtimeConfigResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + +type V1UpdateRealtimeConfigResponse struct { + Body []byte + HTTPResponse *http.Response +} + +// Status returns HTTPResponse.Status +func (r V1UpdateRealtimeConfigResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r V1UpdateRealtimeConfigResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type V1GetStorageConfigResponse struct { Body []byte HTTPResponse *http.Response @@ -14924,6 +15100,32 @@ func (c *ClientWithResponses) V1UpdatePostgresConfigWithResponse(ctx context.Con return ParseV1UpdatePostgresConfigResponse(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...) + if err != nil { + return nil, err + } + return ParseV1GetRealtimeConfigResponse(rsp) +} + +// V1UpdateRealtimeConfigWithBodyWithResponse request with arbitrary body returning *V1UpdateRealtimeConfigResponse +func (c *ClientWithResponses) V1UpdateRealtimeConfigWithBodyWithResponse(ctx context.Context, ref string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*V1UpdateRealtimeConfigResponse, error) { + rsp, err := c.V1UpdateRealtimeConfigWithBody(ctx, ref, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseV1UpdateRealtimeConfigResponse(rsp) +} + +func (c *ClientWithResponses) V1UpdateRealtimeConfigWithResponse(ctx context.Context, ref string, body V1UpdateRealtimeConfigJSONRequestBody, reqEditors ...RequestEditorFn) (*V1UpdateRealtimeConfigResponse, error) { + rsp, err := c.V1UpdateRealtimeConfig(ctx, ref, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseV1UpdateRealtimeConfigResponse(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...) @@ -17713,6 +17915,48 @@ func ParseV1UpdatePostgresConfigResponse(rsp *http.Response) (*V1UpdatePostgresC 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) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &V1GetRealtimeConfigResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest RealtimeConfigResponse + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + +// ParseV1UpdateRealtimeConfigResponse parses an HTTP response from a V1UpdateRealtimeConfigWithResponse call +func ParseV1UpdateRealtimeConfigResponse(rsp *http.Response) (*V1UpdateRealtimeConfigResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &V1UpdateRealtimeConfigResponse{ + 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) diff --git a/pkg/api/types.gen.go b/pkg/api/types.gen.go index 27402ad64..9483eddbd 100644 --- a/pkg/api/types.gen.go +++ b/pkg/api/types.gen.go @@ -97,6 +97,12 @@ const ( ApplyProjectAddonBodyAddonVariant3Ipv4Default ApplyProjectAddonBodyAddonVariant3 = "ipv4_default" ) +// Defines values for AuthConfigResponseDbMaxPoolSizeUnit. +const ( + AuthConfigResponseDbMaxPoolSizeUnitConnections AuthConfigResponseDbMaxPoolSizeUnit = "connections" + AuthConfigResponseDbMaxPoolSizeUnitPercent AuthConfigResponseDbMaxPoolSizeUnit = "percent" +) + // Defines values for AuthConfigResponsePasswordRequiredCharacters. const ( AuthConfigResponsePasswordRequiredCharactersAbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 AuthConfigResponsePasswordRequiredCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ:0123456789" @@ -969,6 +975,12 @@ const ( SupavisorConfigResponsePoolModeTransaction SupavisorConfigResponsePoolMode = "transaction" ) +// Defines values for UpdateAuthConfigBodyDbMaxPoolSizeUnit. +const ( + UpdateAuthConfigBodyDbMaxPoolSizeUnitConnections UpdateAuthConfigBodyDbMaxPoolSizeUnit = "connections" + UpdateAuthConfigBodyDbMaxPoolSizeUnitPercent UpdateAuthConfigBodyDbMaxPoolSizeUnit = "percent" +) + // Defines values for UpdateAuthConfigBodyPasswordRequiredCharacters. const ( UpdateAuthConfigBodyPasswordRequiredCharactersAbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 UpdateAuthConfigBodyPasswordRequiredCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ:0123456789" @@ -1687,6 +1699,7 @@ type ApplyProjectAddonBody_AddonVariant struct { type AuthConfigResponse struct { ApiMaxRequestDuration nullable.Nullable[int] `json:"api_max_request_duration"` 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"` ExternalAnonymousUsersEnabled nullable.Nullable[bool] `json:"external_anonymous_users_enabled"` ExternalAppleAdditionalClientIds nullable.Nullable[string] `json:"external_apple_additional_client_ids"` @@ -1909,6 +1922,9 @@ type AuthConfigResponse struct { UriAllowList nullable.Nullable[string] `json:"uri_allow_list"` } +// AuthConfigResponseDbMaxPoolSizeUnit defines model for AuthConfigResponse.DbMaxPoolSizeUnit. +type AuthConfigResponseDbMaxPoolSizeUnit string + // AuthConfigResponsePasswordRequiredCharacters defines model for AuthConfigResponse.PasswordRequiredCharacters. type AuthConfigResponsePasswordRequiredCharacters string @@ -3051,6 +3067,39 @@ type ReadOnlyStatusResponse struct { OverrideEnabled bool `json:"override_enabled"` } +// RealtimeConfigResponse defines model for RealtimeConfigResponse. +type RealtimeConfigResponse struct { + // ConnectionPool Sets connection pool size for Realtime Authorization + ConnectionPool nullable.Nullable[int] `json:"connection_pool"` + + // MaxBytesPerSecond Sets maximum number of bytes per second rate per channel limit + MaxBytesPerSecond nullable.Nullable[int] `json:"max_bytes_per_second"` + + // MaxChannelsPerClient Sets maximum number of channels per client rate limit + MaxChannelsPerClient nullable.Nullable[int] `json:"max_channels_per_client"` + + // MaxConcurrentUsers Sets maximum number of concurrent users rate limit + MaxConcurrentUsers nullable.Nullable[int] `json:"max_concurrent_users"` + + // MaxEventsPerSecond Sets maximum number of events per second rate per channel limit + MaxEventsPerSecond nullable.Nullable[int] `json:"max_events_per_second"` + + // MaxJoinsPerSecond Sets maximum number of joins per second rate limit + MaxJoinsPerSecond nullable.Nullable[int] `json:"max_joins_per_second"` + + // MaxPayloadSizeInKb Sets maximum number of payload size in KB rate limit + MaxPayloadSizeInKb nullable.Nullable[int] `json:"max_payload_size_in_kb"` + + // MaxPresenceEventsPerSecond Sets maximum number of presence events per second rate limit + MaxPresenceEventsPerSecond nullable.Nullable[int] `json:"max_presence_events_per_second"` + + // PrivateOnly Whether to only allow private channels + PrivateOnly nullable.Nullable[bool] `json:"private_only"` + + // Suspend Whether to suspend realtime + Suspend nullable.Nullable[bool] `json:"suspend"` +} + // RegionsInfo defines model for RegionsInfo. type RegionsInfo struct { All struct { @@ -3276,7 +3325,10 @@ type StorageConfigResponse struct { } `json:"external"` Features struct { IcebergCatalog *struct { - Enabled bool `json:"enabled"` + Enabled bool `json:"enabled"` + MaxCatalogs int `json:"maxCatalogs"` + MaxNamespaces int `json:"maxNamespaces"` + MaxTables int `json:"maxTables"` } `json:"icebergCatalog,omitempty"` ImageTransformation struct { Enabled bool `json:"enabled"` @@ -3284,6 +3336,11 @@ type StorageConfigResponse struct { S3Protocol struct { Enabled bool `json:"enabled"` } `json:"s3Protocol"` + VectorBuckets *struct { + Enabled bool `json:"enabled"` + MaxBuckets int `json:"maxBuckets"` + MaxIndexes int `json:"maxIndexes"` + } `json:"vectorBuckets,omitempty"` } `json:"features"` FileSizeLimit int64 `json:"fileSizeLimit"` MigrationVersion string `json:"migrationVersion"` @@ -3350,6 +3407,7 @@ type UpdateApiKeyBody struct { type UpdateAuthConfigBody struct { ApiMaxRequestDuration nullable.Nullable[int] `json:"api_max_request_duration,omitempty"` DbMaxPoolSize nullable.Nullable[int] `json:"db_max_pool_size,omitempty"` + DbMaxPoolSizeUnit nullable.Nullable[UpdateAuthConfigBodyDbMaxPoolSizeUnit] `json:"db_max_pool_size_unit"` DisableSignup nullable.Nullable[bool] `json:"disable_signup,omitempty"` ExternalAnonymousUsersEnabled nullable.Nullable[bool] `json:"external_anonymous_users_enabled,omitempty"` ExternalAppleAdditionalClientIds nullable.Nullable[string] `json:"external_apple_additional_client_ids,omitempty"` @@ -3570,6 +3628,9 @@ type UpdateAuthConfigBody struct { UriAllowList nullable.Nullable[string] `json:"uri_allow_list,omitempty"` } +// UpdateAuthConfigBodyDbMaxPoolSizeUnit defines model for UpdateAuthConfigBody.DbMaxPoolSizeUnit. +type UpdateAuthConfigBodyDbMaxPoolSizeUnit string + // UpdateAuthConfigBodyPasswordRequiredCharacters defines model for UpdateAuthConfigBody.PasswordRequiredCharacters. type UpdateAuthConfigBodyPasswordRequiredCharacters string @@ -3746,6 +3807,39 @@ type UpdateProviderResponse struct { UpdatedAt *string `json:"updated_at,omitempty"` } +// UpdateRealtimeConfigBody defines model for UpdateRealtimeConfigBody. +type UpdateRealtimeConfigBody struct { + // ConnectionPool Sets connection pool size for Realtime Authorization + ConnectionPool *int `json:"connection_pool,omitempty"` + + // MaxBytesPerSecond Sets maximum number of bytes per second rate per channel limit + MaxBytesPerSecond *int `json:"max_bytes_per_second,omitempty"` + + // MaxChannelsPerClient Sets maximum number of channels per client rate limit + MaxChannelsPerClient *int `json:"max_channels_per_client,omitempty"` + + // MaxConcurrentUsers Sets maximum number of concurrent users rate limit + MaxConcurrentUsers *int `json:"max_concurrent_users,omitempty"` + + // MaxEventsPerSecond Sets maximum number of events per second rate per channel limit + MaxEventsPerSecond *int `json:"max_events_per_second,omitempty"` + + // MaxJoinsPerSecond Sets maximum number of joins per second rate limit + MaxJoinsPerSecond *int `json:"max_joins_per_second,omitempty"` + + // MaxPayloadSizeInKb Sets maximum number of payload size in KB rate limit + MaxPayloadSizeInKb *int `json:"max_payload_size_in_kb,omitempty"` + + // MaxPresenceEventsPerSecond Sets maximum number of presence events per second rate limit + MaxPresenceEventsPerSecond *int `json:"max_presence_events_per_second,omitempty"` + + // PrivateOnly Whether to only allow private channels + PrivateOnly *bool `json:"private_only,omitempty"` + + // Suspend Whether to suspend realtime + Suspend *bool `json:"suspend,omitempty"` +} + // UpdateRunStatusBody defines model for UpdateRunStatusBody. type UpdateRunStatusBody struct { Clone *UpdateRunStatusBodyClone `json:"clone,omitempty"` @@ -3801,7 +3895,10 @@ type UpdateStorageConfigBody struct { } `json:"external,omitempty"` Features *struct { IcebergCatalog *struct { - Enabled bool `json:"enabled"` + Enabled bool `json:"enabled"` + MaxCatalogs int `json:"maxCatalogs"` + MaxNamespaces int `json:"maxNamespaces"` + MaxTables int `json:"maxTables"` } `json:"icebergCatalog,omitempty"` ImageTransformation struct { Enabled bool `json:"enabled"` @@ -3809,6 +3906,11 @@ type UpdateStorageConfigBody struct { S3Protocol struct { Enabled bool `json:"enabled"` } `json:"s3Protocol"` + VectorBuckets *struct { + Enabled bool `json:"enabled"` + MaxBuckets int `json:"maxBuckets"` + MaxIndexes int `json:"maxIndexes"` + } `json:"vectorBuckets,omitempty"` } `json:"features,omitempty"` FileSizeLimit *int64 `json:"fileSizeLimit,omitempty"` } @@ -4713,6 +4815,9 @@ type V1UpdatePoolerConfigJSONRequestBody = UpdateSupavisorConfigBody // V1UpdatePostgresConfigJSONRequestBody defines body for V1UpdatePostgresConfig for application/json ContentType. type V1UpdatePostgresConfigJSONRequestBody = UpdatePostgresConfigBody +// V1UpdateRealtimeConfigJSONRequestBody defines body for V1UpdateRealtimeConfig for application/json ContentType. +type V1UpdateRealtimeConfigJSONRequestBody = UpdateRealtimeConfigBody + // V1UpdateStorageConfigJSONRequestBody defines body for V1UpdateStorageConfig for application/json ContentType. type V1UpdateStorageConfigJSONRequestBody = UpdateStorageConfigBody diff --git a/pkg/config/storage.go b/pkg/config/storage.go index 0c50cbb6d..a692d238e 100644 --- a/pkg/config/storage.go +++ b/pkg/config/storage.go @@ -46,7 +46,10 @@ func (s *storage) ToUpdateStorageConfigBody() v1API.UpdateStorageConfigBody { if s.ImageTransformation != nil { body.Features = &struct { IcebergCatalog *struct { - Enabled bool `json:"enabled"` + Enabled bool `json:"enabled"` + MaxCatalogs int `json:"maxCatalogs"` + MaxNamespaces int `json:"maxNamespaces"` + MaxTables int `json:"maxTables"` } `json:"icebergCatalog,omitempty"` ImageTransformation struct { Enabled bool `json:"enabled"` @@ -54,6 +57,11 @@ func (s *storage) ToUpdateStorageConfigBody() v1API.UpdateStorageConfigBody { S3Protocol struct { Enabled bool `json:"enabled"` } `json:"s3Protocol"` + VectorBuckets *struct { + Enabled bool `json:"enabled"` + MaxBuckets int `json:"maxBuckets"` + MaxIndexes int `json:"maxIndexes"` + } `json:"vectorBuckets,omitempty"` }{} body.Features.ImageTransformation.Enabled = s.ImageTransformation.Enabled } diff --git a/pkg/config/templates/Dockerfile b/pkg/config/templates/Dockerfile index 745746d63..52fbd6229 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:v13.0.7 AS postgrest FROM supabase/postgres-meta:v0.93.1 AS pgmeta -FROM supabase/studio:2025.11.24-sha-d990ae8 AS studio +FROM supabase/studio:2025.11.25-sha-8de52c4 AS studio FROM darthsim/imgproxy:v3.8.0 AS imgproxy FROM supabase/edge-runtime:v1.69.25 AS edgeruntime FROM timberio/vector:0.28.1-alpine AS vector FROM supabase/supavisor:2.7.4 AS supavisor FROM supabase/gotrue:v2.183.0 AS gotrue -FROM supabase/realtime:v2.65.2 AS realtime +FROM supabase/realtime:v2.65.3 AS realtime FROM supabase/storage-api:v1.32.0 AS storage -FROM supabase/logflare:1.26.12 AS logflare +FROM supabase/logflare:1.26.13 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 diff --git a/pkg/config/updater_test.go b/pkg/config/updater_test.go index 98d56068a..7c6deb410 100644 --- a/pkg/config/updater_test.go +++ b/pkg/config/updater_test.go @@ -224,7 +224,10 @@ func TestUpdateStorageConfig(t *testing.T) { FileSizeLimit: 100, Features: struct { IcebergCatalog *struct { - Enabled bool `json:"enabled"` + Enabled bool `json:"enabled"` + MaxCatalogs int `json:"maxCatalogs"` + MaxNamespaces int `json:"maxNamespaces"` + MaxTables int `json:"maxTables"` } `json:"icebergCatalog,omitempty"` ImageTransformation struct { Enabled bool `json:"enabled"` @@ -232,6 +235,11 @@ func TestUpdateStorageConfig(t *testing.T) { S3Protocol struct { Enabled bool `json:"enabled"` } `json:"s3Protocol"` + VectorBuckets *struct { + Enabled bool `json:"enabled"` + MaxBuckets int `json:"maxBuckets"` + MaxIndexes int `json:"maxIndexes"` + } `json:"vectorBuckets,omitempty"` }{}, } mockStorage.Features.ImageTransformation.Enabled = true