chore: production deploy#5408
Merged
Merged
Conversation
Contributor
supabase-cli-releaser
Bot
commented
Jun 1, 2026
- feat(cli): migrate network bans (feat(cli): migrate network bans #5382)
- chore(ci): gh action hardening (chore(ci): gh action hardening #5388)
- fix(docker): bump the docker-minor group across 1 directory with 2 updates (fix(docker): bump the docker-minor group across 1 directory with 2 updates #5385)
- ci: notify Slack on beta and stable CLI releases (ci: notify Slack on beta and stable CLI releases #5389)
- feat(cli): port snippets commands to native TypeScript (feat(cli): port snippets commands to native TypeScript #5381)
- ci(cli): only notify Slack for stable releases (ci(cli): only notify Slack for stable releases #5393)
- feat(cli): migrate vanity-subdomains (feat(cli): migrate vanity-subdomains #5394)
- fix(docker): bump supabase/realtime from v2.101.0 to v2.102.1 in /apps/cli-go/pkg/config/templates in the docker-minor group (fix(docker): bump supabase/realtime from v2.101.0 to v2.102.1 in /apps/cli-go/pkg/config/templates in the docker-minor group #5399)
- fix(auth): propagate passkey config to env (fix(auth): propagate passkey config to env #5401)
- fix(docker): bump supabase/postgres from 17.6.1.131 to 17.6.1.132 in /apps/cli-go/pkg/config/templates (fix(docker): bump supabase/postgres from 17.6.1.131 to 17.6.1.132 in /apps/cli-go/pkg/config/templates #5402)
- fix(cli): drop redundant identify from identity stitch (fix(cli): drop redundant identify from identity stitch #5396)
- feat(cli): port domains commands to native TypeScript (feat(cli): port domains commands to native TypeScript #5391)
- feat(cli): port projects commands to native TypeScript (feat(cli): port projects commands to native TypeScript #5392)
- feat(cli): replace legacy hidden flags (feat(cli): replace legacy hidden flags #5403)
- chore(deps): harden supply chain policy (chore(deps): harden supply chain policy #5387)
- fix(cli): decode Go keyring tokens (fix(cli): decode Go keyring tokens #5406)
## TL;DR Ports `supabase network-bans get` and `supabase network-bans remove` from the Go proxy to native TypeScript ## What's Introduced Replaces the `LegacyGoProxy` path for both `network-bans` leaf commands with native handlers wired through the existing legacy management-api runtime and instrumentation path ## Coverage Added a small integration suite covering this as well --------- Co-authored-by: Colum Ferry <cferry09@gmail.com>
## What kind of change does this PR introduce? chore ## Additional context Applies most of zizmor's hardening suggestions. Brings some action usage up to date (client-id instead of app-id). And does some action pinning. Co-authored-by: Julien Goux <hi@jgoux.dev>
…dates (#5385) Bumps the docker-minor group with 2 updates in the /apps/cli-go/pkg/config/templates directory: supabase/realtime and supabase/storage-api. Updates `supabase/realtime` from v2.100.0 to v2.101.0 Updates `supabase/storage-api` from v1.60.0 to v1.60.2 Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## What changed Adds a Slack release notifier to the CLI release pipeline. - **New `.github/workflows/slack-notify.yml`** — a reusable workflow (`on: workflow_call`) that posts a release message to a Slack **Incoming Webhook** via `curl`, mirroring the pattern used in `supabase-js`. Takes `version` + `channel` inputs and a required `SLACK_RELEASE_WEBHOOK` secret, and renders a Block Kit message with links to the changelog (GitHub release), the commit, and the workflow run. - **`.github/workflows/release.yml`** — adds a `notify-slack` job that calls the reusable workflow once the release succeeds. ## Why / behaviour - `needs: [plan, release]` with an `if:` that contains no status function keeps the implicit `success()` gate, so the notification only fires when both `plan` and `release` succeeded. - The `if:` further restricts to **non-dry-run beta/stable** cuts — alpha and dry runs stay silent. - Nothing depends on `notify-slack`, so a webhook/Slack failure cannot affect the already-completed release. - Reuses existing `plan` outputs (`version`, `channel`); `secrets: inherit` forwards the webhook, same as the existing `release` job. ## Reviewer note: required repo configuration This needs a new repository secret before it can post: 1. Create a Slack **Incoming Webhook** for the target channel. 2. Add it as a repo secret named **`SLACK_RELEASE_WEBHOOK`** (Settings → Secrets and variables → Actions). Must be a secret (not a variable) so `secrets: inherit` can forward it. A `workflow_dispatch` dry-run will not exercise the Slack job (gated on `dry_run != 'true'` by design); the first real signal is the next merged beta cut from `develop`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Summary
Replaces the Phase 0 Go-binary proxies for `supabase snippets list` and
`supabase snippets download` with native Effect handlers. Mirrors Go's
output bytes, error messages, exit codes, and lifecycle (linked-project
cache + telemetry flush on every exit). Adds TS-only `--output-format
json|stream-json` events on top, exposing the full Management-API
payload to scripted callers.
## Changes
- **`snippets list`**: native handler against `GET
/v1/snippets?project_ref=<ref>` with Glamour ASCII table, `--output env`
rejection after ref resolution (Go-bytes), Go-compatible JSON/YAML/TOML
encoders, `nullForEmptyArrays: ["data"]` for empty-list parity
- **`snippets download`**: native handler against `GET
/v1/snippets/{id}` with UUID pre-validation reproducing google/uuid
v1.6.0's two-flavor error surface (`invalid UUID length: N` / `invalid
UUID format`); raw SQL + trailing `\n` in text mode; full response
payload under `--output-format json`
- **Lifecycle parity**: both handlers wrap in nested `Effect.gen` blocks
so `telemetryState.flush` (Go `Execute`) fires on every exit and
`linkedProjectCache.cache(ref)` (Go `PersistentPostRun`) fires for every
path where the ref resolved — including `--output env` and invalid-UUID
early-exits
- **Hoist**: `formatBackupTimestamp` →
`legacy/shared/legacy-timestamp.format.ts::formatLegacyTimestamp`
(snippets is the second consumer, per `apps/cli/CLAUDE.md` "Hoist Before
You Duplicate")
- **Test helpers**: `LegacyRecordedRequest` now captures `urlParams` +
`urlWithParams` so tests can assert on GET query parameters
- **Docs**: `SIDE_EFFECTS.md` rewritten for both commands;
`docs/go-cli-porting-status.md` flips both from `wrapped` → `ported`
## Go parity contract
| Surface | Verified against |
| --- | --- |
| `--output env` rejection | `apps/cli-go/internal/utils/output.go:41`
(byte-exact `--output env flag is not supported`) |
| UUID error prefix |
`apps/cli-go/internal/snippets/download/download.go:17` + google/uuid
v1.6.0 |
| Table columns / pipe escape |
`apps/cli-go/internal/snippets/list/list.go:27-41` |
| JSON `"data": null` for empty list | `list_test.go::encodes json
output` fixture |
| `download` ignores `--output` | `download.go:25` (`fmt.Println`
unconditional) |
| Telemetry safe-flag policy | `apps/cli-go/cmd/snippets.go` has no
`markFlagTelemetrySafe` — `--project-ref` value is redacted |
Fixes CLI-1299
## What changed The `notify-slack` job in the Release workflow now only fires for **stable** releases. Previously it ran for both beta and stable cuts. ## Why Beta release notifications were adding noise to the release Slack channel. Stable releases are the only ones we want to broadcast there. Alpha, beta, and dry-run cuts now stay silent. The reusable `slack-notify.yml` workflow is left untouched (still channel-agnostic) in case it's reused for another channel later.
## TL;DR Ports `supabase vanity-subdomains get`, `check-availability`, `activate`, and `delete` from the legacy Go proxy to native TypeScript ## What's Introduced This replaces the `LegacyGoProxy` path for the `vanity-subdomains` command family with native handlers wired through the existing legacy management-api runtime, instrumentation, and JSON error handling path ## Ref: closes CLI-1294 --------- Co-authored-by: Colum Ferry <cferry09@gmail.com>
…s/cli-go/pkg/config/templates in the docker-minor group (#5399) Bumps the docker-minor group in /apps/cli-go/pkg/config/templates with 1 update: supabase/realtime. Updates `supabase/realtime` from v2.101.0 to v2.102.1 [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…/apps/cli-go/pkg/config/templates (#5402) Bumps supabase/postgres from 17.6.1.131 to 17.6.1.132. [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## Problem Both the Go CLI's `StitchLogin` and the TS CLI's `X-Gotrue-Id` interception fire `$create_alias` AND `$identify(distinctID, nil)` back-to-back on a user's first successful stitch. The `$identify` carries no person properties, so `$create_alias` already owns the entire device→user merge in the person graph. The Identify is pure event-volume waste. This is the follow-up to #5366. That PR gated stitching in ephemeral environments (CI, Docker, npx) to stop the identify spike. This one tightens the path that still runs — persistent developer laptops — by dropping the redundant call. We verified the redundancy empirically: of 638K `posthog-go` `$identify` events on 2026-05-26, zero carried `$anon_distinct_id` linkage, confirming the merge comes entirely from the alias. ## Changes - Go: remove `s.analytics.Identify(distinctID, nil)` from `StitchLogin` in `apps/cli-go/internal/telemetry/service.go`. - TS: remove `analytics.identify(gotrueId)` from the stitch in `apps/cli/src/legacy/auth/legacy-platform-api.layer.ts`. The TS `identify()` may have set default person properties (`cli_version`, `os`, `arch`); accepting that small loss since subsequent `cli_*` capture events carry the same data as event properties. - Tests updated on both surfaces to assert `Alias` fires and `Identify` does not. Kept the surfaces 1:1 so the Go/TS telemetry parity holds. `identify` stays on the `Analytics` interface — the `login` command still uses it for `cli_login_completed`, which is a separate path. Halves the remaining persistent-laptop stitch volume (~15K/day → ~7K/day). No effect on the spike population already handled by #5366. GROWTH-890 --------- Co-authored-by: Julien Goux <hi@jgoux.dev>
Ports `supabase domains` (custom hostname management) from the Phase 0
Go-binary proxy to a native TypeScript/Effect implementation in the
legacy shell, as a strict 1:1 port of the Go CLI. Closes CLI-1293.
## What changed
- **5 native handlers** (`create`, `get`, `reverify`, `activate`,
`delete`) replacing the Go-proxy wrappers. Each resolves the project
ref, calls the typed Management API custom-hostname endpoint, and
reproduces Go's `PrintStatus` contract: status text to **stderr**,
structured output to **stdout** when `-o != pretty`. All three
`--output-format` modes (text/json/stream-json) and Go's `-o
{pretty,json,yaml,toml,env}` are honored, and PersistentPostRun parity
(linked-project cache + telemetry flush) runs on success and failure.
- **`create` CNAME pre-check** — Cloudflare DNS-over-HTTPS
(`https://1.1.1.1`, 10s timeout) verifying the hostname's CNAME points
at `<ref>.<projectHost>.` before initializing; short-circuits before any
POST on failure.
- **Restored `--include-raw-output`** (deprecated) — was missing from
the proxy port. Forces `-o json` when `-o` is unset/pretty; inert on
`delete`, matching Go.
- **`LegacyCliConfig.projectHost`** — sourced from the single-source
`legacy-profile.ts` map (also used by `branches get`), with the YAML
`project_host` override. Added the `snap` built-in profile so its CNAME
targets resolve to `snapcloud.dev`.
- **Docs** — consolidated the 5 per-subcommand `SIDE_EFFECTS.md` files
into one group-level document; flipped the 5 `domains` rows to `ported`
in the porting-status tracker.
## Reviewer notes
- `--include-raw-output` is declared per-subcommand (Effect CLI has no
persistent-group-flag support, consistent with how `--project-ref` is
handled shell-wide) and cannot reproduce Cobra's help-hiding or
deprecation warning. Documented as an intentional divergence in
`SIDE_EFFECTS.md`, alongside the snake-case encoder output and the `%+v`
SSL-struct dump approximation.
- New colocated modules: `domains.errors.ts`, `domains.format.ts` (pure
`PrintStatus` port), `domains.cname.ts` (DNS verifier),
`domains.emit.ts` (shared output-mode branching). The per-profile host
map lives only in `legacy-profile.ts` (single source of truth).
---------
Co-authored-by: Julien Goux <hi@jgoux.dev>
## What changed
Replaces the four Phase-0 Go proxies in the legacy `projects` command
group with native TypeScript Effect implementations that call the
Management API directly, and flips their rows in
`go-cli-porting-status.md` from `wrapped` to `ported`.
- **`list`** — `GET /v1/projects`; soft linked-ref marker via the new
`resolveOptional` (never prompts/fails); two-axis output (Go `--output
pretty|json|yaml|toml|env` × TS `--output-format
text|json|stream-json`), with `--output env` unsupported, matching Go.
- **`create`** — interactive/non-interactive gating on `--interactive` +
TTY + output mode; prompts for name/org/region/password when omitted;
crypto-RNG 16-char password fallback; `desired_instance_size` only when
`--size` set; `--plan` accepted-but-ignored (hidden, vestigial in Go);
dashboard URL resolved per profile.
- **`delete`** — arg-or-prompt ref resolution (never reads the linked
file as a source); confirmation defaulting to **No** and honouring
`--yes`; 404 → does-not-exist, other non-2xx → failed; best-effort
`supabase/.temp` unlink when the deleted ref matches the linked one.
- **`api-keys`** — ref resolution through the shared resolver (flag →
env → linked file → prompt on a TTY → error); `NAME | KEY VALUE` table
with `******` masking; `SUPABASE_<NAME>_KEY` env/toml encoding; raw
`ApiKeyResponse[]` for json/yaml.
## Shared infrastructure
- `LegacyProjectRefResolver` gains `resolveOptional` (soft marker for
`list`) and `promptProjectRef(title)` (per-command prompt label for
`delete`); existing `resolve` unchanged.
- Hoists `apiKeysToEnv` into `legacy/shared/legacy-api-keys.format.ts`
and reuses the existing `legacy-timestamp.format.ts` instead of
duplicating a timestamp formatter (per the hoist-before-duplicate
policy).
## Reviewer notes
- **Strict Go parity** for stdout/stderr text, flags, exit codes, API
routes, and error-message phrasing. Refs are validated against
`^[a-z]{20}$` before reaching any API path.
- **Intentional divergences** (documented in `SIDE_EFFECTS.md`):
terminal ANSI color is omitted (Go disables color on non-TTY output, so
piped output matches byte-for-byte); the non-interactive `create` error
consolidates cobra's per-flag "required" errors into one message;
`DB_PASSWORD` is not consumed (Go only mirrors `--db-password` into
viper for local-stack reuse).
- New unit + integration coverage across all four commands and the
resolver; per-command and group-level `SIDE_EFFECTS.md`.
Closes CLI-1288.
---------
Co-authored-by: Julien Goux <hi@jgoux.dev>
## TL;DR replaces the remaining legacy hidden flag shim with native `Flag.withHidden` ## What's Introduced This switches the remaining hidden legacy flags to Effect's native `Flag.withHidden` support and removes the old local hidden-flag shim entirely also dropped the formatter side help stripping workaround, since hidden flags are now handled natively by the upstream layer added tests around it as well..... ## ref: - follows up the earlier hidden subcommands support: #5378 - extends: Effect-TS/effect-smol#2227 --------- Co-authored-by: Julien Goux <hi@jgoux.dev>
## What changed - Bumps the workspace package manager metadata to pnpm 11.4.0 and updates the lockfile accordingly. - Makes exotic transitive source blocking explicit with `blockExoticSubdeps: true`. - Temporarily disables pnpm release-age enforcement with `minimumReleaseAge: 0`, because the current lockfile contains packages newer than pnpm v11's default 24-hour window. - Keeps the branch rebased on the latest develop changes, including the existing 7-day Dependabot cooldowns. ## Context Recent npm supply-chain incidents make dependency freshness delay and stricter lockfile verification worth encoding as repository policy. Dependabot now carries the 7-day cooldown policy, while pnpm release-age enforcement can be enabled in a follow-up once the current lockfile has aged enough. The stricter pnpm trust downgrade policy is intentionally left out for now because it needs more review before enforcement.
## What changed Decode `go-keyring-base64:` wrapped access tokens when reading from the OS keyring in both the legacy and next CLI credential layers. ## Why The Go keyring backend can store the real `sbp_...` access token inside a `go-keyring-base64:` wrapper. The TypeScript credential readers were validating and using the raw wrapped value, so legacy Management API commands such as `supabase secrets set` failed with an invalid access token format error even though the decoded token was valid. ## Notes for reviewers The normalization happens at the keyring-read boundary so existing validation continues to run against the actual token value, not the storage representation.
Coverage Report for CI Build 26744353826Warning No base build found for commit Coverage: 63.785%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsRequires a base build to compare against. How to fix this → Coverage Stats
💛 - Coveralls |
jgoux
approved these changes
Jun 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.