Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions .github/workflows/automerge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ jobs:

- name: Generate token
id: app-token
if: ${{ steps.meta.outputs.update-type == null || 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') }}
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
client-id: ${{ vars.GH_APP_CLIENT_ID }}
Expand All @@ -33,16 +32,14 @@ jobs:

# Here the PR gets approved.
- name: Approve a PR
if: ${{ steps.meta.outputs.update-type == null || 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: ${{ steps.app-token.outputs.token }}
GITHUB_EVENT_PULL_REQUEST_HTML_URL: ${{ github.event.pull_request.html_url }}

# Finally, this sets the PR to allow auto-merging for patch and minor
# updates if all checks pass
# Finally, this sets the PR to allow auto-merging once all required
# checks pass.
- name: Enable auto-merge for Dependabot PRs
if: ${{ steps.meta.outputs.update-type == null || 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: ${{ steps.app-token.outputs.token }}
Expand Down
4 changes: 2 additions & 2 deletions apps/cli-e2e/src/tests/stack.e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ function testParityStack(cmd: string[], opts?: { workspaceSetup?: (dir: string)
// ---------------------------------------------------------------------------
// services
// ---------------------------------------------------------------------------
// `services` reads service image names from config (not Docker) so DOCKER_HOST
// is not needed.
// `services` prints a baked-in Go-parity service matrix, so DOCKER_HOST is not
// needed.

describe("services", () => {
testBehaviour("lists known service images", async ({ run }) => {
Expand Down
2 changes: 1 addition & 1 deletion apps/cli-go/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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.4
github.com/posthog/posthog-go v1.13.0
github.com/posthog/posthog-go v1.13.1
github.com/spf13/afero v1.15.0
github.com/spf13/cobra v1.10.2
github.com/spf13/pflag v1.0.10
Expand Down
4 changes: 2 additions & 2 deletions apps/cli-go/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -941,8 +941,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/polyfloyd/go-errorlint v1.8.0 h1:DL4RestQqRLr8U4LygLw8g2DX6RN1eBJOpa2mzsrl1Q=
github.com/polyfloyd/go-errorlint v1.8.0/go.mod h1:G2W0Q5roxbLCt0ZQbdoxQxXktTjwNyDbEaj3n7jvl4s=
github.com/posthog/posthog-go v1.13.0 h1:+i+t6txCczJcGZj7ME2ry4sLhPYvq3q7RYuUZ0z6NpQ=
github.com/posthog/posthog-go v1.13.0/go.mod h1:xsVOW9YImilUcazwPNEq4PJDqEZf2KeCS758zXjwkPg=
github.com/posthog/posthog-go v1.13.1 h1:7OtfgOEM9fC2n4Hbs4e5mK1uaLuNguoYWFEI4kEnTUY=
github.com/posthog/posthog-go v1.13.1/go.mod h1:xsVOW9YImilUcazwPNEq4PJDqEZf2KeCS758zXjwkPg=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/prometheus/client_golang v0.9.0-pre1.0.20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
Expand Down
24 changes: 24 additions & 0 deletions apps/cli-go/internal/utils/connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net"
"net/url"
"os"
"regexp"
"strings"
"time"

Expand Down Expand Up @@ -173,6 +174,24 @@ func ConnectByUrl(ctx context.Context, url string, options ...func(*pgx.ConnConf

const SuggestEnvVar = "Connect to your database by setting the env var correctly: SUPABASE_DB_PASSWORD"

// ipv6LiteralPattern matches a bracketed IPv6 address (e.g. [2406:da18:...]) as
// it appears in a Go dial error such as
// "dial tcp [2406:da18:...]:5432: connect: network is unreachable".
var ipv6LiteralPattern = regexp.MustCompile(`\[[0-9a-fA-F:]*:[0-9a-fA-F:]*\]`)

// isIPv6ConnectivityError reports whether the connection failure stems from the
// host resolving to an IPv6 address that the current network cannot route to.
// Supabase direct database connections (db.<ref>.supabase.co:5432) are
// IPv6-only unless the IPv4 add-on is enabled, so users on IPv4-only networks
// hit "network is unreachable" / "no route to host" against an IPv6 literal.
func isIPv6ConnectivityError(msg string) bool {
if !strings.Contains(msg, "network is unreachable") &&
!strings.Contains(msg, "no route to host") {
return false
}
return ipv6LiteralPattern.MatchString(msg)
}

// Sets CmdSuggestion to an actionable hint based on the given pg connection error.
func SetConnectSuggestion(err error) {
if err == nil {
Expand All @@ -190,6 +209,11 @@ func SetConnectSuggestion(err error) {
} else if strings.Contains(msg, "SCRAM exchange: Wrong password") || strings.Contains(msg, "failed SASL auth") {
// password authentication failed for user / invalid SCRAM server-final-message received from server
CmdSuggestion = SuggestEnvVar
} else if isIPv6ConnectivityError(msg) {
CmdSuggestion = fmt.Sprintf(
"Your network does not support IPv6, which is required for direct connections to the database.\nRun %s to connect through the IPv4 connection pooler instead.",
Aqua("supabase link"),
)
} else if strings.Contains(msg, "connect: no route to host") || strings.Contains(msg, "Tenant or user not found") {
// Assumes IPv6 check has been performed before this
CmdSuggestion = "Make sure your project exists on profile: " + CurrentProfile.Name
Expand Down
12 changes: 11 additions & 1 deletion apps/cli-go/internal/utils/connect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,17 @@ func TestSetConnectSuggestion(t *testing.T) {
suggestion: "Connect to your database by setting the env var correctly: SUPABASE_DB_PASSWORD",
},
{
name: "no route to host",
name: "ipv6 no route to host",
err: errors.New("dial tcp [2406:da18:4fd:9b0d:80ec:9812:3e65:450b]:5432: connect: no route to host"),
suggestion: "Your network does not support IPv6",
},
{
name: "ipv6 network is unreachable",
err: errors.New("dial tcp [2406:da18:4fd:9b0d:80ec:9812:3e65:450b]:5432: connect: network is unreachable"),
suggestion: "Your network does not support IPv6",
},
{
name: "no route to host without ipv6 address",
err: errors.New("connect: no route to host"),
suggestion: "Make sure your project exists on profile: " + CurrentProfile.Name,
},
Expand Down
6 changes: 3 additions & 3 deletions apps/cli-go/pkg/config/templates/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ FROM supabase/postgres:17.6.1.132 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.12 AS postgrest
FROM postgrest/postgrest:v14.13 AS postgrest
FROM supabase/postgres-meta:v0.96.6 AS pgmeta
FROM supabase/studio:2026.06.03-sha-0bca601 AS studio
FROM darthsim/imgproxy:v3.8.0 AS imgproxy
FROM supabase/edge-runtime:v1.74.0 AS edgeruntime
FROM timberio/vector:0.53.0-alpine AS vector
FROM supabase/supavisor:2.9.7 AS supavisor
FROM supabase/gotrue:v2.189.0 AS gotrue
FROM supabase/realtime:v2.103.2 AS realtime
FROM supabase/realtime:v2.103.4 AS realtime
FROM supabase/storage-api:v1.60.4 AS storage
FROM supabase/logflare:1.43.3 AS logflare
FROM supabase/logflare:1.43.4 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
Expand Down
12 changes: 6 additions & 6 deletions apps/cli/docs/go-cli-porting-status.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ These commands exist in the TS CLI today but have no direct top-level equivalent

## Quick Start

| Old command | TS status | TS command path or `missing` | Missing flags/params | Extra TS flags/params | Notes |
| ----------- | --------- | ---------------------------- | -------------------- | --------------------- | ------------------------------------------- |
| `bootstrap` | `missing` | `missing` | `n/a` | `n/a` | No TS command yet. Wrapped in legacy shell. |
| Old command | TS status | TS command path or `missing` | Missing flags/params | Extra TS flags/params | Notes |
| ----------- | --------- | ---------------------------- | -------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `bootstrap` | `missing` | `missing` | `n/a` | `n/a` | No `next/` command yet. Ported to native TS in the legacy shell; the migration-push sub-step is delegated to the Go binary as a documented interim until `db push` is natively ported. |

## Project / Stack Lifecycle

Expand All @@ -76,7 +76,7 @@ These commands exist in the TS CLI today but have no direct top-level equivalent

<!-- Note: start, stop, and status are also wrapped in the legacy shell — see Legacy Shell Wrapping Status below. -->

| `services` | `partial` | `supabase status` + `supabase stack update` | Go-style dedicated `services` command shape | `--stack` | The old version-reporting and linked-version drift behavior exists in TS, but it is split across `status` for per-service versions and `stack update` for refreshing pinned versions instead of a single `services` command. |
| `services` | `ported` | [`../src/next/commands/services/services.command.ts`](../src/next/commands/services/services.command.ts) | `--output` remains a global legacy-shell concern rather than a next-only command flag | `--output-format` | TS restores the dedicated `services` command, prints the bundled local service image matrix, and best-effort compares linked remote versions without proxying to Go. |

## Database

Expand Down Expand Up @@ -265,9 +265,9 @@ Legend:
| `logout` | `ported` | [`../src/legacy/commands/logout/logout.command.ts`](../src/legacy/commands/logout/logout.command.ts) |
| `link` | `ported` | [`../src/legacy/commands/link/link.command.ts`](../src/legacy/commands/link/link.command.ts) |
| `unlink` | `ported` | [`../src/legacy/commands/unlink/unlink.command.ts`](../src/legacy/commands/unlink/unlink.command.ts) |
| `bootstrap` | `wrapped` | [`../src/legacy/commands/bootstrap/bootstrap.command.ts`](../src/legacy/commands/bootstrap/bootstrap.command.ts) |
| `bootstrap` | `ported` | [`../src/legacy/commands/bootstrap/bootstrap.command.ts`](../src/legacy/commands/bootstrap/bootstrap.command.ts) (native; `db push` step delegated to the Go binary — interim) |
| `init` | `ported` | [`../src/legacy/commands/init/init.command.ts`](../src/legacy/commands/init/init.command.ts) |
| `services` | `wrapped` | [`../src/legacy/commands/services/services.command.ts`](../src/legacy/commands/services/services.command.ts) |
| `services` | `ported` | [`../src/legacy/commands/services/services.command.ts`](../src/legacy/commands/services/services.command.ts) |
| `start` | `wrapped` | [`../src/legacy/commands/start/start.command.ts`](../src/legacy/commands/start/start.command.ts) |
| `stop` | `wrapped` | [`../src/legacy/commands/stop/stop.command.ts`](../src/legacy/commands/stop/stop.command.ts) |
| `status` | `wrapped` | [`../src/legacy/commands/status/status.command.ts`](../src/legacy/commands/status/status.command.ts) |
Expand Down
6 changes: 3 additions & 3 deletions apps/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
"fix:all": "nx run-many -t lint:fix fmt:fix knip:fix --projects=$npm_package_name"
},
"devDependencies": {
"@anthropic-ai/claude-agent-sdk": "^0.3.146",
"@anthropic-ai/sdk": "^0.97.1",
"@anthropic-ai/claude-agent-sdk": "^0.3.156",
"@anthropic-ai/sdk": "^0.100.0",
"@clack/prompts": "^1.4.0",
"@effect/atom-react": "catalog:",
"@effect/platform-bun": "catalog:",
Expand All @@ -64,7 +64,7 @@
"oxfmt": "catalog:",
"oxlint": "catalog:",
"oxlint-tsgolint": "catalog:",
"posthog-node": "^5.35.5",
"posthog-node": "^5.35.6",
"react": "^19.2.6",
"react-devtools-core": "^7.0.1",
"semantic-release": "^25.0.3",
Expand Down
30 changes: 21 additions & 9 deletions apps/cli/scripts/update-scoop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,35 +58,47 @@ const baseUrl = local
? `file:///${distDir.replace(/\\/g, "/")}`
: `https://github.com/${repo}/releases/download/v${version}`;

// Main-bucket layout uses unversioned Windows tarballs on GitHub Releases
// (release-shared.yml copies versioned builds to supabase_windows_*.tar.gz).
// Local builds only emit versioned archives, so --local keeps those names.
const amd64Tar = local
? `supabase_${version}_windows_amd64.tar.gz`
: "supabase_windows_amd64.tar.gz";
const arm64Tar = local
? `supabase_${version}_windows_arm64.tar.gz`
: "supabase_windows_arm64.tar.gz";

const manifest = {
version,
description: "Supabase CLI",
homepage: "https://supabase.com",
homepage: "https://supabase.com/",
license: "MIT",
architecture: {
"64bit": {
url: `${baseUrl}/supabase_${version}_windows_amd64.zip`,
hash: sha(`supabase_${version}_windows_amd64.zip`),
bin: [binEntry],
url: `${baseUrl}/${amd64Tar}`,
hash: sha(`supabase_${version}_windows_amd64.tar.gz`),
},
arm64: {
url: `${baseUrl}/supabase_${version}_windows_arm64.zip`,
hash: sha(`supabase_${version}_windows_arm64.zip`),
bin: [binEntry],
url: `${baseUrl}/${arm64Tar}`,
hash: sha(`supabase_${version}_windows_arm64.tar.gz`),
},
},
bin: binEntry,
checkver: {
github: `https://github.com/${repo}`,
},
autoupdate: {
architecture: {
"64bit": {
url: `https://github.com/${repo}/releases/download/v$version/supabase_$version_windows_amd64.zip`,
url: `https://github.com/${repo}/releases/download/v$version/supabase_windows_amd64.tar.gz`,
},
arm64: {
url: `https://github.com/${repo}/releases/download/v$version/supabase_$version_windows_arm64.zip`,
url: `https://github.com/${repo}/releases/download/v$version/supabase_windows_arm64.tar.gz`,
},
},
hash: {
url: "$baseurl/supabase_$version_checksums.txt",
},
},
};

Expand Down
Loading
Loading