Skip to content
Merged
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
8 changes: 5 additions & 3 deletions .github/workflows/cli-go-pg-prove.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,12 @@ jobs:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Merge multi-arch manifests
env:
IMAGE_TAG: ${{ needs.settings.outputs.image_tag }}
run: |
docker buildx imagetools create -t ${{ needs.settings.outputs.image_tag }} \
${{ needs.settings.outputs.image_tag }}_amd64 \
${{ needs.settings.outputs.image_tag }}_arm64
docker buildx imagetools create -t "${IMAGE_TAG}" \
"${IMAGE_TAG}_amd64" \
"${IMAGE_TAG}_arm64"
publish:
needs:
Expand Down
8 changes: 5 additions & 3 deletions .github/workflows/cli-go-publish-migra.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,12 @@ jobs:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Merge multi-arch manifests
env:
IMAGE_TAG: ${{ needs.settings.outputs.image_tag }}
run: |
docker buildx imagetools create -t "${{ needs.settings.outputs.image_tag }}" \
"${{ needs.settings.outputs.image_tag }}_amd64" \
"${{ needs.settings.outputs.image_tag }}_arm64"
docker buildx imagetools create -t "${IMAGE_TAG}" \
"${IMAGE_TAG}_amd64" \
"${IMAGE_TAG}_arm64"

publish:
needs:
Expand Down
40 changes: 28 additions & 12 deletions .github/workflows/release-shared.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ on:
jobs:
build:
runs-on: large-linux-x86
env:
BUN_SHELL: ${{ inputs.shell }}
VERSION: ${{ inputs.version }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
Expand All @@ -71,10 +74,10 @@ jobs:
sudo apt-get install -y nfpm

- name: Sync versions
run: pnpm exec bun apps/cli/scripts/sync-versions.ts --version ${{ inputs.version }}
run: pnpm exec bun apps/cli/scripts/sync-versions.ts --version "${VERSION}"

- name: Build selected shell
run: pnpm exec bun apps/cli/scripts/build.ts --version ${{ inputs.version }} --shell ${{ inputs.shell }}
run: pnpm exec bun apps/cli/scripts/build.ts --version "${VERSION}" --shell "${BUN_SHELL}"

- name: Verify build artifacts
run: |
Expand All @@ -100,6 +103,9 @@ jobs:
matrix:
runner: [ubuntu-latest, macos-latest, macos-15-intel, windows-latest]
runs-on: ${{ matrix.runner }}
env:
NPM_TAG: ${{ inputs.npm_tag }}
VERSION: ${{ inputs.version }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
Expand Down Expand Up @@ -128,13 +134,17 @@ jobs:
run: chmod +x packages/cli-*/bin/supabase || true

- name: Run smoke tests
run: pnpm run test:smoke -- --version ${{ inputs.version }} --tag ${{ inputs.npm_tag }}
run: pnpm run test:smoke -- --version "${VERSION}" --tag "${NPM_TAG}"
working-directory: apps/cli

publish:
needs: smoke-test
if: ${{ !inputs.dry_run }}
runs-on: ubuntu-latest
env:
CHANNEL: ${{ inputs.channel }}
NPM_TAG: ${{ inputs.npm_tag }}
VERSION: ${{ inputs.version }}
permissions:
contents: write
id-token: write
Expand All @@ -151,10 +161,10 @@ jobs:
name: cli-build-${{ inputs.shell }}-${{ inputs.version }}

- name: Sync versions
run: pnpm exec bun apps/cli/scripts/sync-versions.ts --version ${{ inputs.version }}
run: pnpm exec bun apps/cli/scripts/sync-versions.ts --version "${VERSION}"

- name: Publish to npm
run: pnpm exec bun apps/cli/scripts/publish.ts --tag ${{ inputs.npm_tag }}
run: pnpm exec bun apps/cli/scripts/publish.ts --tag ""${NPM_TAG}""

# Push the version tag to origin as soon as npm has the bytes, before any
# downstream step that can fail. Without this, a failure in the GH-release
Expand All @@ -166,7 +176,7 @@ jobs:
- name: Push version tag
run: |
set -euo pipefail
tag="v${{ inputs.version }}"
tag="v${VERSION}"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
if git ls-remote --tags origin "refs/tags/${tag}" | grep -q .; then
Expand All @@ -193,8 +203,8 @@ jobs:
if: ${{ inputs.prerelease }}
run: |
set -euo pipefail
tag="v${{ inputs.version }}"
channel="${{ inputs.channel }}"
tag="v${VERSION}"
channel="${CHANNEL}"
note_ref="refs/notes/semantic-release-${tag}"
if git ls-remote origin "${note_ref}" | grep -q .; then
echo "Channel note ${note_ref} already on origin; skipping push."
Expand All @@ -211,7 +221,7 @@ jobs:
run: |
set -euo pipefail
for triple in darwin_arm64 darwin_amd64 linux_arm64 linux_amd64 windows_arm64 windows_amd64; do
cp "dist/supabase_${{ inputs.version }}_${triple}.tar.gz" "dist/supabase_${triple}.tar.gz"
cp "dist/supabase_${VERSION}_${triple}.tar.gz" "dist/supabase_${triple}.tar.gz"
done

- name: Create draft GitHub Release
Expand Down Expand Up @@ -247,12 +257,15 @@ jobs:
- name: Publish GitHub Release (immutable)
env:
GH_TOKEN: ${{ github.token }}
run: gh release edit v${{ inputs.version }} --draft=false
run: gh release edit "v${VERSION}" --draft=false

publish-homebrew:
needs: publish
if: ${{ !inputs.dry_run && inputs.publish_brew_scoop }}
runs-on: ubuntu-latest
env:
BREW_NAME: ${{ inputs.brew_name }}
VERSION: ${{ inputs.version }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
Expand Down Expand Up @@ -284,14 +297,17 @@ jobs:
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"

- name: Update Homebrew formula
run: pnpm exec bun apps/cli/scripts/update-homebrew.ts --version ${{ inputs.version }} --name ${{ inputs.brew_name }}
run: pnpm exec bun apps/cli/scripts/update-homebrew.ts --version "${VERSION}" --name "${BREW_NAME}"
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}

publish-scoop:
needs: publish
if: ${{ !inputs.dry_run && inputs.publish_brew_scoop }}
runs-on: ubuntu-latest
env:
SCOOP_NAME: ${{ inputs.scoop_name }}
VERSION: ${{ inputs.version }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
Expand Down Expand Up @@ -323,6 +339,6 @@ jobs:
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"

- name: Update Scoop manifest
run: pnpm exec bun apps/cli/scripts/update-scoop.ts --version ${{ inputs.version }} --name ${{ inputs.scoop_name }}
run: pnpm exec bun apps/cli/scripts/update-scoop.ts --version "${VERSION}" --name "${SCOOP_NAME}"
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
63 changes: 63 additions & 0 deletions apps/cli-e2e/src/tests/config-toml.e2e.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { mkdirSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { describe, expect } from "vitest";
import { PROJECT_REF } from "./env.ts";
import { testBehaviour } from "./test-context.ts";

// CLI-1489: v2.99.0 introduced a TypeScript config loader in the Bun shell
// that strictly decoded supabase/config.toml through an Effect schema. Any
// non-string field written as env(VAR) — e.g. a port — was rejected before
// env-resolution could run, crashing the CLI at boot with
// ProjectConfigParseError. This test runs against every CLI_HARNESS_TARGET
// (go, ts-legacy, ts-next) so the regression cannot return on any shell.
//
// A 401 is injected so the test does not need a real API fixture: pre-fix the
// TS shells crashed before any API call, post-fix they reach the (faked) API
// and get the injected error. Either way we only assert that the CLI got
// past config decode.

function writeConfigWithEnvPorts(dir: string): void {
mkdirSync(join(dir, "supabase"), { recursive: true });
writeFileSync(
join(dir, "supabase", "config.toml"),
[
'project_id = "with-env-ports"',
"",
"[api]",
'port = "env(SUPABASE_API_PORT)"',
"",
"[db]",
'port = "env(SUPABASE_DB_PORT)"',
"",
"[analytics]",
'port = "env(SUPABASE_ANALYTICS_PORT)"',
"",
].join("\n"),
);
}

const ENV_PORTS = {
SUPABASE_API_PORT: "54321",
SUPABASE_DB_PORT: "54322",
SUPABASE_ANALYTICS_PORT: "54327",
};

describe("env-in-config-toml", () => {
testBehaviour("does not crash on numeric fields", async ({ run, workspace, apiUrl }) => {
writeConfigWithEnvPorts(workspace.path);

await fetch(`${apiUrl}/_ctrl/error-all`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ status: 401, body: { message: "Invalid token" } }),
});

const result = await run(["secrets", "list", "--project-ref", PROJECT_REF], {
env: ENV_PORTS,
});

const output = `${result.stdout}\n${result.stderr}`;
expect(output).not.toContain("ProjectConfigParseError");
expect(output).not.toMatch(/Expected number.*env\(SUPABASE_/);
});
});
1 change: 1 addition & 0 deletions apps/cli-go/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*.so
*.dylib
/cli
/supabase-go

# Test binary, built with `go test -c`
*.test
Expand Down
12 changes: 8 additions & 4 deletions apps/cli-go/pkg/api/types.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions apps/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ This workspace currently contains the next/V3 CLI shell and the scaffolding for

For current migration/parity status, see:

- [`docs/go-cli-porting-status.md`](/Users/jgoux/Code/supabase/dx-labs/apps/cli/docs/go-cli-porting-status.md)
- [`docs/go-cli-porting-status.md`](./docs/go-cli-porting-status.md)

For the generated command/reference docs, see:

- [`docs/go-cli-reference.md`](/Users/jgoux/Code/supabase/dx-labs/apps/cli/docs/go-cli-reference.md)
- [`docs/supabase-home.md`](/Users/jgoux/Code/supabase/dx-labs/apps/cli/docs/supabase-home.md)
- [`../../packages/stack/docs/service-versioning.md`](/Users/jgoux/Code/supabase/dx-labs/packages/stack/docs/service-versioning.md)
- [`docs/go-cli-reference.md`](./docs/go-cli-reference.md)
- [`docs/supabase-home.md`](./docs/supabase-home.md)
- [`../../packages/stack/docs/service-versioning.md`](../../packages/stack/docs/service-versioning.md)

The README is intentionally brief. Command details should live in the generated docs and the parity tracker above.

Expand Down Expand Up @@ -127,9 +127,9 @@ can surface `Downloading` before normal runtime states.

Useful companion docs:

- [`../../packages/stack/docs/architecture.md`](/Users/jgoux/Code/supabase/dx-labs/packages/stack/docs/architecture.md)
- [`../../packages/stack/docs/detach-mode.md`](/Users/jgoux/Code/supabase/dx-labs/packages/stack/docs/detach-mode.md)
- [`docs/ui.md`](/Users/jgoux/Code/supabase/dx-labs/apps/cli/docs/ui.md)
- [`../../packages/stack/docs/architecture.md`](../../packages/stack/docs/architecture.md)
- [`../../packages/stack/docs/detach-mode.md`](../../packages/stack/docs/detach-mode.md)
- [`docs/ui.md`](./docs/ui.md)

## Development

Expand Down
6 changes: 3 additions & 3 deletions apps/cli/docs/supabase-home.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,6 @@ When deciding where something belongs, use this rule of thumb:

## Related Docs

- [CLI Code Structure](/Users/jgoux/Code/supabase/dx-labs/apps/cli/docs/code-structure.md)
- [Service Versioning](/Users/jgoux/Code/supabase/dx-labs/packages/stack/docs/service-versioning.md)
- [Project Config Loading](/Users/jgoux/Code/supabase/dx-labs/packages/config/docs/project-config-loading.md)
- [CLI Code Structure](./code-structure.md)
- [Service Versioning](../../../packages/stack/docs/service-versioning.md)
- [Project Config Loading](../../../packages/config/docs/project-config-loading.md)
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Argument, Command, Flag } from "effect/unstable/cli";
import { withHidden } from "../../../../shared/cli/hidden-flag.ts";
import { withHidden, withHiddenFromConfig } from "../../../../shared/cli/hidden-flag.ts";
import { legacyFunctionsDeploy } from "./deploy.handler.ts";

const config = {
Expand Down Expand Up @@ -42,6 +42,7 @@ const config = {
export const legacyFunctionsDeployCommand = Command.make("deploy", config).pipe(
Command.withDescription("Deploy a Function to the linked Supabase project."),
Command.withShortDescription("Deploy a Function to Supabase"),
withHiddenFromConfig(config),
Command.withHandler((flags) =>
legacyFunctionsDeploy({
functionNames: flags.functionNames.map(String),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Argument, Command, Flag } from "effect/unstable/cli";
import type * as CliCommand from "effect/unstable/cli/Command";
import { withHidden } from "../../../../shared/cli/hidden-flag.ts";
import { withHidden, withHiddenFromConfig } from "../../../../shared/cli/hidden-flag.ts";
import { legacyFunctionsDownload } from "./download.handler.ts";

const config = {
Expand Down Expand Up @@ -32,5 +32,6 @@ export const legacyFunctionsDownloadCommand = Command.make("download", config).p
"Download the source code for a Function from the linked Supabase project. If no function name is provided, downloads all functions.",
),
Command.withShortDescription("Download a Function from Supabase"),
withHiddenFromConfig(config),
Command.withHandler((flags) => legacyFunctionsDownload(flags)),
);
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Command, Flag } from "effect/unstable/cli";
import type * as CliCommand from "effect/unstable/cli/Command";
import { withHidden } from "../../../../shared/cli/hidden-flag.ts";
import { withHidden, withHiddenFromConfig } from "../../../../shared/cli/hidden-flag.ts";
import { legacyFunctionsServe } from "./serve.handler.ts";

const INSPECT_MODES = ["run", "brk", "wait"] as const;
Expand Down Expand Up @@ -35,5 +35,6 @@ export type LegacyFunctionsServeFlags = CliCommand.Command.Config.Infer<typeof c
export const legacyFunctionsServeCommand = Command.make("serve", config).pipe(
Command.withDescription("Serve all Functions locally."),
Command.withShortDescription("Serve all Functions locally"),
withHiddenFromConfig(config),
Command.withHandler((flags) => legacyFunctionsServe(flags)),
);
18 changes: 12 additions & 6 deletions apps/cli/src/legacy/commands/init/init.command.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Command, Flag } from "effect/unstable/cli";
import type * as CliCommand from "effect/unstable/cli/Command";
import { withHidden, withHiddenFromConfig } from "../../../shared/cli/hidden-flag.ts";
import { legacyInit } from "./init.handler.ts";

const config = {
Expand All @@ -13,14 +14,18 @@ const config = {
force: Flag.boolean("force").pipe(
Flag.withDescription("Overwrite existing supabase/config.toml."),
),
withVscodeWorkspace: Flag.boolean("with-vscode-workspace").pipe(
Flag.withDescription("Generate VS Code workspace."),
withVscodeWorkspace: withHidden(
Flag.boolean("with-vscode-workspace").pipe(Flag.withDescription("Generate VS Code workspace.")),
),
withVscodeSettings: Flag.boolean("with-vscode-settings").pipe(
Flag.withDescription("Generate VS Code settings for Deno."),
withVscodeSettings: withHidden(
Flag.boolean("with-vscode-settings").pipe(
Flag.withDescription("Generate VS Code settings for Deno."),
),
),
withIntellijSettings: Flag.boolean("with-intellij-settings").pipe(
Flag.withDescription("Generate IntelliJ IDEA settings for Deno."),
withIntellijSettings: withHidden(
Flag.boolean("with-intellij-settings").pipe(
Flag.withDescription("Generate IntelliJ IDEA settings for Deno."),
),
),
} as const;

Expand All @@ -29,5 +34,6 @@ export type LegacyInitFlags = CliCommand.Command.Config.Infer<typeof config>;
export const legacyInitCommand = Command.make("init", config).pipe(
Command.withDescription("Initialize a local project."),
Command.withShortDescription("Initialize a local project"),
withHiddenFromConfig(config),
Command.withHandler((flags) => legacyInit(flags)),
);
Loading
Loading