Skip to content

Commit a515a4f

Browse files
authored
chore: Change the local setup to use docker only for supabase (#5851)
It was disappearing after played on builder
1 parent de5c99c commit a515a4f

16 files changed

Lines changed: 280 additions & 277 deletions

.github/workflows/main.yml

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -172,14 +172,7 @@ jobs:
172172
name: development
173173

174174
env:
175-
AUTH_SECRET: test
176-
DATABASE_URL: postgresql://user:pass@localhost:55432/webstudio
177-
DIRECT_URL: postgresql://user:pass@localhost:55432/webstudio
178-
E2E_PGPORT: 55432
179-
E2E_POSTGREST_PORT: 55433
180-
POSTGREST_API_KEY: ""
181-
POSTGREST_URL: http://127.0.0.1:55433
182-
TRPC_SERVER_API_TOKEN: e2e-service-token
175+
BUILDER_E2E_COMPOSE_ARGS: "--env-file apps/builder/.env -f apps/builder/docker-compose.yaml -f apps/builder/docker-compose.e2e.yaml"
183176

184177
steps:
185178
- uses: actions/checkout@v4
@@ -217,15 +210,15 @@ jobs:
217210
fi
218211
219212
echo "::warning::Builder e2e failed on the first attempt. Restarting services and retrying once."
220-
docker compose -f apps/builder/docker-compose.e2e.yaml logs || true
221-
docker compose -f apps/builder/docker-compose.e2e.yaml down --volumes --remove-orphans || true
213+
docker compose $BUILDER_E2E_COMPOSE_ARGS logs || true
214+
docker compose $BUILDER_E2E_COMPOSE_ARGS down --volumes --remove-orphans || true
222215
223216
E2E_SKIP_CLEANUP=true E2E_TEST_COMMAND_TIMEOUT_SECONDS=900 pnpm e2e:builder
224217
225218
- name: Print e2e service logs
226219
if: failure()
227-
run: docker compose -f apps/builder/docker-compose.e2e.yaml logs
220+
run: docker compose $BUILDER_E2E_COMPOSE_ARGS logs
228221

229222
- name: Stop e2e services
230223
if: always()
231-
run: docker compose -f apps/builder/docker-compose.e2e.yaml down --volumes --remove-orphans
224+
run: docker compose $BUILDER_E2E_COMPOSE_ARGS down --volumes --remove-orphans

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ yarn-error.log*
3939

4040
# data
4141
/data
42+
.webstudio
4243
*.db
4344
*.db-journal
4445

apps/builder/.env

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
# To override environment variables, add a .env.development file in the same directory.
22
# For more details, visit: https://vitejs.dev/guide/env-and-mode#env-files
3-
DATABASE_URL=postgresql://postgres:pass@localhost/webstudio?pgbouncer=true
4-
DIRECT_URL=postgresql://postgres:pass@localhost/webstudio
3+
DATABASE_URL=postgresql://postgres:pass@localhost:55432/webstudio?pgbouncer=true
4+
DIRECT_URL=postgresql://postgres:pass@localhost:55432/webstudio
5+
PGPORT=55432
6+
POSTGRES_DB=webstudio
7+
POSTGRES_USER=postgres
8+
POSTGRES_PASSWORD=pass
59

610
AUTH_SECRET=0000
11+
PORT=5176
712

813
# GH_CLIENT_SECRET=
914
# GH_CLIENT_ID=
1015
DEV_LOGIN=true
1116

12-
POSTGREST_URL=http://localhost:3000
13-
# JWT token, decode using jwt.io. Encoded with PGRST_JWT_SECRET from docker-compose.yml
14-
POSTGREST_API_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImttZHBpeHpvcWlpcmJtcGRpcHB5Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2NjYzMzY0MjgsImV4cCI6MTk4MTkxMjQyOH0.jjeYvTDrWP9pV7dfZr6fptualNQ3aR13kuPhvT25Sso"
17+
POSTGREST_URL=http://localhost:55433
18+
POSTGREST_PORT=55433
19+
# Empty for the local PostgREST container.
20+
POSTGREST_API_KEY=
1521

1622
# Optional max upload size in Mb
1723
# MAX_UPLOAD_SIZE=10
@@ -84,6 +90,4 @@ PLANS='[
8490

8591
# TRCP server url and API token. If empty local TRPC server is used
8692
# TRPC_SERVER_URL=
87-
# TRPC_SERVER_API_TOKEN=
88-
89-
93+
TRPC_SERVER_API_TOKEN=e2e-service-token

apps/builder/dev/backend.sh

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#!/usr/bin/env bash
2+
3+
builder_backend_init() {
4+
ROOT_DIR="${ROOT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)}"
5+
SCHEMA_SNAPSHOT="${SCHEMA_SNAPSHOT:-$ROOT_DIR/apps/builder/e2e/schema/current.sql}"
6+
COMPOSE_ENV=(
7+
--env-file "$ROOT_DIR/apps/builder/.env"
8+
)
9+
if [ -f "$ROOT_DIR/apps/builder/.env.development" ]; then
10+
COMPOSE_ENV+=(--env-file "$ROOT_DIR/apps/builder/.env.development")
11+
fi
12+
COMPOSE_FILES=(
13+
-f "$ROOT_DIR/apps/builder/docker-compose.yaml"
14+
-f "$COMPOSE_OVERRIDE_FILE"
15+
)
16+
}
17+
18+
builder_compose() {
19+
docker compose "${COMPOSE_ENV[@]}" "${COMPOSE_FILES[@]}" "$@"
20+
}
21+
22+
builder_backend_down() {
23+
builder_compose down "$@"
24+
}
25+
26+
builder_backend_start_db() {
27+
builder_compose up -d db
28+
}
29+
30+
builder_backend_start_postgrest() {
31+
builder_compose up -d postgrest
32+
}
33+
34+
builder_backend_wait_for_db() {
35+
local timeout_seconds="${1:-60}"
36+
local timeout_at
37+
timeout_at="$(($(date +%s) + timeout_seconds))"
38+
39+
until builder_compose exec -T db \
40+
sh -c 'psql -q -U "$POSTGRES_USER" -d "$POSTGRES_DB" -v ON_ERROR_STOP=1 -c "SELECT 1"' \
41+
>/dev/null 2>&1; do
42+
if [ "$(date +%s)" -ge "$timeout_at" ]; then
43+
echo "Timed out waiting for database" >&2
44+
return 1
45+
fi
46+
sleep 0.2
47+
done
48+
}
49+
50+
builder_backend_schema_exists() {
51+
[ "$(
52+
builder_compose exec -T db \
53+
sh -c 'psql -q -U "$POSTGRES_USER" -d "$POSTGRES_DB" -tAc "SELECT to_regclass('\''public.\"Project\"'\'') IS NOT NULL"'
54+
)" = "t" ]
55+
}
56+
57+
builder_backend_bootstrap_schema_snapshot() {
58+
if [ ! -f "$SCHEMA_SNAPSHOT" ]; then
59+
return 1
60+
fi
61+
62+
builder_compose exec -T db \
63+
sh -c 'psql -q -U "$POSTGRES_USER" -d "$POSTGRES_DB" -v ON_ERROR_STOP=1' \
64+
<"$SCHEMA_SNAPSHOT" >/dev/null
65+
}
66+
67+
builder_backend_migrate() {
68+
pnpm --dir "$ROOT_DIR" --filter=./packages/prisma-client migrations migrate --dev --cwd ../../apps/builder
69+
}
70+
71+
builder_backend_bootstrap() {
72+
case "${1:-auto}" in
73+
schema)
74+
builder_backend_bootstrap_schema_snapshot
75+
;;
76+
migrations)
77+
builder_backend_migrate
78+
;;
79+
auto)
80+
if [ -f "$SCHEMA_SNAPSHOT" ]; then
81+
builder_backend_bootstrap_schema_snapshot
82+
echo "Bootstrapped database from $SCHEMA_SNAPSHOT"
83+
else
84+
echo "No schema snapshot found at $SCHEMA_SNAPSHOT; falling back to migrations"
85+
builder_backend_migrate
86+
fi
87+
;;
88+
*)
89+
echo "Unknown database bootstrap mode: $1" >&2
90+
exit 1
91+
;;
92+
esac
93+
}
94+
95+
builder_backend_bootstrap_if_empty() {
96+
if builder_backend_schema_exists; then
97+
echo "Database schema already exists; skipping bootstrap"
98+
else
99+
builder_backend_bootstrap auto
100+
fi
101+
}
102+
103+
builder_backend_write_schema_snapshot() {
104+
mkdir -p "$(dirname "$SCHEMA_SNAPSHOT")"
105+
builder_compose exec -T db \
106+
sh -c 'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" --schema-only --no-owner --no-privileges' \
107+
>"$SCHEMA_SNAPSHOT"
108+
echo "Wrote $SCHEMA_SNAPSHOT"
109+
}
110+
111+
builder_prisma_client_exists() {
112+
[ -f "$ROOT_DIR/packages/prisma-client/src/__generated__/index.js" ]
113+
}
114+
115+
builder_generate_prisma_client() {
116+
case "${1:-auto}" in
117+
true)
118+
pnpm --dir "$ROOT_DIR" --filter=@webstudio-is/prisma-client generate
119+
;;
120+
false)
121+
echo "Skipping Prisma client generation"
122+
;;
123+
auto)
124+
if builder_prisma_client_exists; then
125+
echo "Skipping Prisma client generation; generated client already exists"
126+
else
127+
pnpm --dir "$ROOT_DIR" --filter=@webstudio-is/prisma-client generate
128+
fi
129+
;;
130+
*)
131+
echo "Unknown Prisma generation mode: $1" >&2
132+
exit 1
133+
;;
134+
esac
135+
}

apps/builder/dev/run-local.sh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
5+
COMPOSE_OVERRIDE_FILE="$ROOT_DIR/apps/builder/docker-compose.local.yaml"
6+
source "$ROOT_DIR/apps/builder/dev/backend.sh"
7+
builder_backend_init
8+
9+
cleanup() {
10+
if [ "${LOCAL_DEV_CLEANUP:-false}" != "true" ]; then
11+
return
12+
fi
13+
14+
local down_args=(--remove-orphans)
15+
if [ "${LOCAL_DEV_CLEANUP_VOLUMES:-false}" = "true" ]; then
16+
down_args+=(--volumes)
17+
fi
18+
builder_backend_down "${down_args[@]}"
19+
}
20+
21+
trap cleanup EXIT
22+
23+
if [ "${LOCAL_DEV_RESET_DB:-false}" = "true" ]; then
24+
builder_backend_down --volumes --remove-orphans
25+
fi
26+
27+
builder_backend_start_db
28+
builder_backend_wait_for_db
29+
builder_backend_bootstrap_if_empty
30+
builder_generate_prisma_client auto
31+
builder_backend_start_postgrest
32+
33+
if [ "${LOCAL_DEV_START_BUILDER:-true}" = "true" ]; then
34+
exec pnpm --dir "$ROOT_DIR" dev
35+
fi
Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,4 @@
11
services:
22
db:
3-
image: postgres:16
4-
environment:
5-
POSTGRES_DB: webstudio
6-
POSTGRES_USER: user
7-
POSTGRES_PASSWORD: pass
8-
ports:
9-
- "${E2E_PGPORT:-55432}:5432"
103
tmpfs:
114
- /var/lib/postgresql/data
12-
healthcheck:
13-
test: ["CMD-SHELL", "pg_isready -U user -d webstudio"]
14-
interval: 2s
15-
timeout: 2s
16-
retries: 30
17-
18-
postgrest:
19-
image: postgrest/postgrest:v12.2.12
20-
depends_on:
21-
db:
22-
condition: service_healthy
23-
environment:
24-
PGRST_DB_URI: postgres://user:pass@db:5432/webstudio
25-
PGRST_DB_SCHEMAS: public
26-
PGRST_DB_ANON_ROLE: user
27-
PGRST_SERVER_PORT: 3000
28-
ports:
29-
- "${E2E_POSTGREST_PORT:-55433}:3000"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
services:
2+
db:
3+
volumes:
4+
- db:/var/lib/postgresql/data
5+
6+
volumes:
7+
db:

apps/builder/docker-compose.yaml

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
1-
version: "3.1"
2-
3-
volumes:
4-
db:
5-
61
services:
72
db:
8-
image: postgres
9-
# Uncomment to log all queries
10-
command: ["postgres", "-c", "log_statement=all"]
11-
restart: always
3+
image: postgres:16
4+
environment:
5+
POSTGRES_DB: ${POSTGRES_DB:?}
6+
POSTGRES_USER: ${POSTGRES_USER:?}
7+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
8+
ports:
9+
- "${PGPORT:?}:5432"
10+
healthcheck:
11+
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
12+
interval: 2s
13+
timeout: 2s
14+
retries: 30
15+
16+
postgrest:
17+
image: postgrest/postgrest:v12.2.12
18+
depends_on:
19+
db:
20+
condition: service_healthy
1221
environment:
13-
# postgresql://user:pass@localhost:5432/webstudio
14-
POSTGRES_PASSWORD: pass
15-
POSTGRES_DB: webstudio
16-
POSTGRES_USER: user
17-
volumes:
18-
- db:/var/lib/postgresql/data
22+
PGRST_DB_URI: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
23+
PGRST_DB_SCHEMAS: public
24+
PGRST_DB_ANON_ROLE: ${POSTGRES_USER}
25+
PGRST_SERVER_PORT: 3000
1926
ports:
20-
- ${PGPORT:-5432}:5432
27+
- "${POSTGREST_PORT:?}:3000"

apps/builder/e2e/db.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@ import {
55
createClient,
66
type Database,
77
} from "@webstudio-is/postgrest/index.server";
8+
import env from "../app/env/env.server";
89

910
const execFileAsync = promisify(execFile);
1011

11-
const postgrestUrl = process.env.POSTGREST_URL ?? "http://127.0.0.1:55433";
12-
const postgrestApiKey = process.env.POSTGREST_API_KEY ?? "";
12+
const composeBaseFile = fileURLToPath(
13+
new URL("../docker-compose.yaml", import.meta.url)
14+
);
1315
const composeFile = fileURLToPath(
1416
new URL("../docker-compose.e2e.yaml", import.meta.url)
1517
);
1618

17-
const postgrest = createClient(postgrestUrl, postgrestApiKey);
19+
const postgrest = createClient(env.POSTGREST_URL, env.POSTGREST_API_KEY);
1820

1921
const throwIfError = <Data>({
2022
error,
@@ -55,18 +57,16 @@ export const resetDatabase = async () => {
5557
[
5658
"compose",
5759
"-f",
60+
composeBaseFile,
61+
"-f",
5862
composeFile,
5963
"exec",
6064
"-T",
6165
"db",
62-
"psql",
63-
"-U",
64-
"user",
65-
"-d",
66-
"webstudio",
67-
"-v",
68-
"ON_ERROR_STOP=1",
66+
"sh",
6967
"-c",
68+
'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -v ON_ERROR_STOP=1 -c "$1"',
69+
"sh",
7070
sql,
7171
],
7272
{ maxBuffer: 1024 * 1024 }

apps/builder/e2e/flows/dashboard.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { dashboardUrl, getProjectIdFromBuilderUrl } from "../harness";
22
import type { Page } from "playwright";
3+
import env from "../../app/env/env.server";
34

45
const loginReadyTimeout = 30_000;
56

@@ -48,7 +49,10 @@ export const loginWithSecret = async ({
4849
return;
4950
}
5051
await loginWithSecretButton.click();
51-
await page.getByPlaceholder("Auth secret").fill("test");
52+
if (env.AUTH_SECRET === undefined) {
53+
throw new Error("AUTH_SECRET must be set for e2e dev login");
54+
}
55+
await page.getByPlaceholder("Auth secret").fill(env.AUTH_SECRET);
5256
await page.getByPlaceholder("Email (optional)").fill(email);
5357
if (devPlan !== undefined) {
5458
await page.locator('select[name="devPlan"]').selectOption(devPlan);

0 commit comments

Comments
 (0)