Skip to content

Commit 419d095

Browse files
committed
feat: local and ci cli-smoke and image tests
1 parent 38d047c commit 419d095

8 files changed

Lines changed: 701 additions & 84 deletions

File tree

.github/workflows/cli-smoke-test.yml

Lines changed: 7 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -74,81 +74,20 @@ jobs:
7474
run: |
7575
DOCKERFILE="Dockerfile-${{ matrix.pg_version }}"
7676
echo "Building $DOCKERFILE..."
77-
docker build -f "$DOCKERFILE" -t "supabase/postgres:${{ matrix.pg_version }}" .
77+
# Tag with ECR prefix since CLI uses public.ecr.aws/supabase/postgres as base
78+
docker build -f "$DOCKERFILE" -t "public.ecr.aws/supabase/postgres:${{ matrix.pg_version }}" .
7879
79-
- name: Setup Supabase CLI
80-
uses: supabase/setup-cli@b60b5899c73b63a2d2d651b1e90db8d4c9392f51 # v1.6.0
81-
with:
82-
version: latest
83-
84-
- name: Get component versions from ansible/vars.yml
85-
id: versions
86-
run: |
87-
REST_VERSION=$(nix run nixpkgs#yq -- -r '.postgrest_release' ansible/vars.yml)
88-
AUTH_VERSION=$(nix run nixpkgs#yq -- -r '.gotrue_release' ansible/vars.yml)
89-
PG_VERSION=$(nix run nixpkgs#yq -- -r '.postgres_release["postgres${{ matrix.pg_version }}"]' ansible/vars.yml)
90-
91-
echo "rest=$REST_VERSION" >> "$GITHUB_OUTPUT"
92-
echo "auth=$AUTH_VERSION" >> "$GITHUB_OUTPUT"
93-
echo "pg=$PG_VERSION" >> "$GITHUB_OUTPUT"
94-
95-
- name: Prepare Supabase CLI config
96-
run: |
97-
mkdir -p supabase/.temp
98-
99-
# Set version files for CLI
100-
echo "v${{ steps.versions.outputs.rest }}" > supabase/.temp/rest-version
101-
echo "v${{ steps.versions.outputs.auth }}" > supabase/.temp/gotrue-version
102-
echo "${{ steps.versions.outputs.pg }}" > supabase/.temp/postgres-version
103-
104-
# Create minimal config.toml
105-
cat > supabase/config.toml << EOF
106-
[db]
107-
major_version = ${{ matrix.pg_version }}
108-
109-
[db.settings]
110-
# Use our locally built image
111-
image = "supabase/postgres:${{ matrix.pg_version }}"
112-
EOF
113-
114-
- name: Run supabase start
80+
- name: Run CLI smoke test
11581
run: |
116-
echo "Starting Supabase with PostgreSQL ${{ matrix.pg_version }}..."
117-
supabase start --debug
82+
echo "Running CLI smoke test for PostgreSQL ${{ matrix.pg_version }}..."
83+
nix run --accept-flake-config .#cli-smoke-test -- --no-build ${{ matrix.pg_version }}
11884
timeout-minutes: 10
11985

120-
- name: Verify database is accessible
121-
run: |
122-
echo "Verifying database connection..."
123-
supabase db reset --debug || true
124-
125-
# Basic connectivity check
126-
PGPASSWORD=postgres psql -h localhost -p 54322 -U postgres -d postgres -c "SELECT version();"
127-
128-
- name: Run basic health checks
129-
run: |
130-
echo "Running health checks..."
131-
132-
# Check that key extensions are available
133-
PGPASSWORD=postgres psql -h localhost -p 54322 -U postgres -d postgres << 'EOF'
134-
-- Check PostgREST schema exists
135-
SELECT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname = 'extensions');
136-
137-
-- Check some key extensions
138-
SELECT extname, extversion FROM pg_extension WHERE extname IN ('uuid-ossp', 'pgcrypto', 'pgjwt') ORDER BY extname;
139-
140-
-- Basic table creation test
141-
CREATE TABLE IF NOT EXISTS smoke_test (id serial primary key, created_at timestamptz default now());
142-
INSERT INTO smoke_test DEFAULT VALUES;
143-
SELECT * FROM smoke_test;
144-
DROP TABLE smoke_test;
145-
EOF
146-
14786
- name: Show logs on failure
14887
if: failure()
14988
run: |
15089
echo "=== Supabase Status ==="
151-
supabase status || true
90+
nix run --accept-flake-config .#supabase-cli -- status || true
15291
15392
echo "=== Docker containers ==="
15493
docker ps -a
@@ -159,7 +98,7 @@ jobs:
15998
- name: Cleanup
16099
if: always()
161100
run: |
162-
supabase stop --no-backup || true
101+
nix run --accept-flake-config .#supabase-cli -- stop --no-backup || true
163102
164103
skip-notification:
165104
name: CLI Smoke Test (Skipped)

.github/workflows/docker-image-test.yml

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -87,27 +87,23 @@ jobs:
8787
- name: Build Docker image
8888
run: |
8989
echo "Building ${{ matrix.dockerfile }}..."
90-
docker build -f ${{ matrix.dockerfile }} -t supabase-postgres:${{ matrix.dockerfile }}-test .
90+
VERSION="${{ matrix.dockerfile }}"
91+
VERSION="${VERSION#Dockerfile-}"
92+
# Build with tags expected by both tools
93+
docker build -f ${{ matrix.dockerfile }} \
94+
-t "pg-docker-test:${VERSION}" \
95+
-t "supabase-postgres:${VERSION}-analyze" \
96+
.
9197
9298
- name: Run image size analysis
9399
run: |
94100
echo "=== Image Size Analysis for ${{ matrix.dockerfile }} ==="
95-
# Build the analyzer tag expected by the tool
96-
VERSION="${{ matrix.dockerfile }}"
97-
VERSION="${VERSION#Dockerfile-}"
98-
docker tag supabase-postgres:${{ matrix.dockerfile }}-test "supabase-postgres:${VERSION}-analyze"
99-
100101
nix run --accept-flake-config .#image-size-analyzer -- --image ${{ matrix.dockerfile }} --no-build
101102
102103
- name: Run Docker image tests
103104
run: |
104105
echo "=== Running tests for ${{ matrix.dockerfile }} ==="
105-
# Tag with the expected name for test-docker-image.sh
106-
VERSION="${{ matrix.dockerfile }}"
107-
VERSION="${VERSION#Dockerfile-}"
108-
docker tag supabase-postgres:${{ matrix.dockerfile }}-test "pg-docker-test:${VERSION}"
109-
110-
./test-docker-image.sh --no-build ${{ matrix.dockerfile }}
106+
nix run --accept-flake-config .#docker-image-test -- --no-build ${{ matrix.dockerfile }}
111107
112108
- name: Show container logs on failure
113109
if: failure()
@@ -128,9 +124,8 @@ jobs:
128124
# Remove test containers
129125
docker ps -a --filter "name=pg-test-${VERSION}" -q | xargs -r docker rm -f || true
130126
# Remove test images
131-
docker rmi "supabase-postgres:${{ matrix.dockerfile }}-test" || true
132-
docker rmi "supabase-postgres:${VERSION}-analyze" || true
133127
docker rmi "pg-docker-test:${VERSION}" || true
128+
docker rmi "supabase-postgres:${VERSION}-analyze" || true
134129
135130
skip-notification:
136131
name: Docker Image Test (Skipped)

nix/apps.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
trigger-nix-build = mkApp "trigger-nix-build";
3131
supascan = mkApp "supascan";
3232
pg-startup-profiler = mkApp "pg-startup-profiler";
33+
docker-image-test = mkApp "docker-image-test";
34+
cli-smoke-test = mkApp "cli-smoke-test";
3335
};
3436
};
3537
}

nix/checks.nix

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -467,10 +467,16 @@
467467
)
468468
);
469469
inherit (self'.packages)
470-
wal-g-2
471-
pg_regress
470+
cli-smoke-test
471+
docker-image-inputs
472+
docker-image-test
472473
goss
474+
image-size-analyzer
475+
pg_regress
476+
pg-startup-profiler
477+
supabase-cli
473478
supascan
479+
wal-g-2
474480
;
475481
devShell = self'.devShells.default;
476482
}

nix/packages/cli-smoke-test.nix

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
{
2+
writeShellApplication,
3+
coreutils,
4+
gnused,
5+
supabase-cli,
6+
yq,
7+
postgresql_15,
8+
}:
9+
writeShellApplication {
10+
name = "cli-smoke-test";
11+
runtimeInputs = [
12+
coreutils
13+
gnused
14+
supabase-cli
15+
yq
16+
postgresql_15
17+
];
18+
text = ''
19+
# CLI Smoke Test - Tests Supabase CLI with locally built Docker images
20+
#
21+
# Usage:
22+
# nix run .#cli-smoke-test -- 17
23+
# nix run .#cli-smoke-test -- --no-build 15
24+
# nix run .#cli-smoke-test -- --debug 17 # Full debug output (local only)
25+
26+
set -euo pipefail
27+
28+
REPO_ROOT="$(pwd)"
29+
PG_VERSION=""
30+
SKIP_BUILD=false
31+
DEBUG_MODE=false
32+
WORK_DIR=""
33+
34+
RED='\033[0;31m'
35+
GREEN='\033[0;32m'
36+
YELLOW='\033[1;33m'
37+
NC='\033[0m'
38+
39+
log_info() { echo -e "''${GREEN}[INFO]''${NC} $1"; }
40+
log_warn() { echo -e "''${YELLOW}[WARN]''${NC} $1"; }
41+
log_error() { echo -e "''${RED}[ERROR]''${NC} $1"; }
42+
43+
print_help() {
44+
cat << 'EOF'
45+
Usage: nix run .#cli-smoke-test -- [OPTIONS] PG_VERSION
46+
47+
Run Supabase CLI smoke tests with a locally built PostgreSQL Docker image.
48+
49+
Arguments:
50+
PG_VERSION PostgreSQL version to test (15 or 17)
51+
52+
Options:
53+
-h, --help Show this help message
54+
--no-build Skip building the image (use existing supabase/postgres:<version>)
55+
--debug Enable debug output (includes credentials - local use only!)
56+
57+
Examples:
58+
nix run .#cli-smoke-test -- 17
59+
nix run .#cli-smoke-test -- 15
60+
nix run .#cli-smoke-test -- --no-build 17
61+
nix run .#cli-smoke-test -- --debug 17
62+
EOF
63+
}
64+
65+
cleanup() {
66+
local exit_code=$?
67+
log_info "Cleaning up..."
68+
supabase stop --no-backup 2>/dev/null || true
69+
if [[ -n "$WORK_DIR" ]] && [[ -d "$WORK_DIR" ]]; then
70+
rm -rf "$WORK_DIR"
71+
fi
72+
exit $exit_code
73+
}
74+
75+
trap cleanup EXIT
76+
77+
main() {
78+
while [[ $# -gt 0 ]]; do
79+
case "$1" in
80+
-h|--help) print_help; exit 0 ;;
81+
--no-build) SKIP_BUILD=true; shift ;;
82+
--debug) DEBUG_MODE=true; shift ;;
83+
-*) log_error "Unknown option: $1"; print_help; exit 1 ;;
84+
*) PG_VERSION="$1"; shift ;;
85+
esac
86+
done
87+
88+
if [[ -z "$PG_VERSION" ]]; then
89+
log_error "PostgreSQL version required (15 or 17)"
90+
print_help
91+
exit 1
92+
fi
93+
94+
if [[ "$PG_VERSION" != "15" && "$PG_VERSION" != "17" ]]; then
95+
log_error "Invalid PostgreSQL version: $PG_VERSION (must be 15 or 17)"
96+
exit 1
97+
fi
98+
99+
DOCKERFILE="Dockerfile-$PG_VERSION"
100+
# CLI uses public.ecr.aws/supabase/postgres as base image
101+
IMAGE_NAME="public.ecr.aws/supabase/postgres:$PG_VERSION"
102+
103+
if [[ ! -f "$REPO_ROOT/$DOCKERFILE" ]]; then
104+
log_error "Dockerfile not found: $REPO_ROOT/$DOCKERFILE"
105+
log_error "Make sure you're running from the postgres repository root"
106+
exit 1
107+
fi
108+
109+
if [[ ! -f "$REPO_ROOT/ansible/vars.yml" ]]; then
110+
log_error "ansible/vars.yml not found"
111+
log_error "Make sure you're running from the postgres repository root"
112+
exit 1
113+
fi
114+
115+
log_info "CLI Smoke Test for PostgreSQL $PG_VERSION"
116+
117+
# Build Docker image
118+
if [[ "$SKIP_BUILD" != "true" ]]; then
119+
log_info "Building Docker image from $DOCKERFILE..."
120+
if ! docker build -f "$REPO_ROOT/$DOCKERFILE" -t "$IMAGE_NAME" "$REPO_ROOT"; then
121+
log_error "Failed to build Docker image"
122+
exit 1
123+
fi
124+
else
125+
log_info "Skipping build (--no-build)"
126+
if ! docker image inspect "$IMAGE_NAME" &>/dev/null; then
127+
log_error "Image $IMAGE_NAME not found. Run without --no-build first."
128+
exit 1
129+
fi
130+
fi
131+
132+
# Get component versions from ansible/vars.yml
133+
log_info "Reading component versions from ansible/vars.yml..."
134+
REST_VERSION=$(yq -r '.postgrest_release' "$REPO_ROOT/ansible/vars.yml")
135+
AUTH_VERSION=$(yq -r '.gotrue_release' "$REPO_ROOT/ansible/vars.yml")
136+
PG_RELEASE=$(yq -r ".postgres_release[\"postgres$PG_VERSION\"]" "$REPO_ROOT/ansible/vars.yml")
137+
138+
log_info " PostgREST: $REST_VERSION"
139+
log_info " GoTrue: $AUTH_VERSION"
140+
log_info " Postgres: $PG_RELEASE"
141+
142+
# Create working directory
143+
WORK_DIR=$(mktemp -d)
144+
log_info "Working directory: $WORK_DIR"
145+
cd "$WORK_DIR"
146+
147+
# Prepare Supabase CLI config
148+
mkdir -p supabase/.temp
149+
150+
# Set component versions - CLI reads these to determine which images to use
151+
echo "v$REST_VERSION" > supabase/.temp/rest-version
152+
echo "v$AUTH_VERSION" > supabase/.temp/gotrue-version
153+
# Use major version so CLI constructs supabase/postgres:$PG_VERSION (our local build)
154+
echo "$PG_VERSION" > supabase/.temp/postgres-version
155+
156+
cat > supabase/config.toml << EOF
157+
[db]
158+
major_version = $PG_VERSION
159+
EOF
160+
161+
log_info "Starting Supabase..."
162+
if [[ "$DEBUG_MODE" == "true" ]]; then
163+
# Debug mode: full output including credentials (local use only)
164+
if ! supabase start --debug; then
165+
log_error "Failed to start Supabase"
166+
exit 1
167+
fi
168+
else
169+
# CI mode: redact credentials from output
170+
SUPABASE_OUTPUT=$(mktemp)
171+
SUPABASE_EXIT=0
172+
supabase start > "$SUPABASE_OUTPUT" 2>&1 || SUPABASE_EXIT=$?
173+
174+
# Redact sensitive information before displaying
175+
sed -E \
176+
-e 's/(Secret[[:space:]]*\│[[:space:]]*)[^│]*/\1[REDACTED]/g' \
177+
-e 's/(Publishable[[:space:]]*\│[[:space:]]*)[^│]*/\1[REDACTED]/g' \
178+
-e 's/(Access Key[[:space:]]*\│[[:space:]]*)[^│]*/\1[REDACTED]/g' \
179+
-e 's/(Secret Key[[:space:]]*\│[[:space:]]*)[^│]*/\1[REDACTED]/g' \
180+
-e 's/postgres:postgres@/postgres:[REDACTED]@/g' \
181+
-e 's/sb_secret_[A-Za-z0-9_-]*/sb_secret_[REDACTED]/g' \
182+
-e 's/sb_publishable_[A-Za-z0-9_-]*/sb_publishable_[REDACTED]/g' \
183+
-e 's/"Data":"[^"]*"/"Data":"[REDACTED]"/g' \
184+
-e 's/"SecretKey":[0-9]*/"SecretKey":[REDACTED]/g' \
185+
-e 's/[a-f0-9]{32,64}/[REDACTED]/g' \
186+
"$SUPABASE_OUTPUT"
187+
188+
rm -f "$SUPABASE_OUTPUT"
189+
190+
if [[ $SUPABASE_EXIT -ne 0 ]]; then
191+
log_error "Failed to start Supabase"
192+
exit 1
193+
fi
194+
fi
195+
196+
log_info "Verifying database connection..."
197+
if ! PGPASSWORD=postgres psql -h localhost -p 54322 -U postgres -d postgres -c "SELECT version();" ; then
198+
log_error "Failed to connect to database"
199+
exit 1
200+
fi
201+
202+
log_info "Running health checks..."
203+
PGPASSWORD=postgres psql -h localhost -p 54322 -U postgres -d postgres << 'EOSQL'
204+
-- Check extensions schema exists
205+
SELECT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname = 'extensions');
206+
207+
-- Check some key extensions
208+
SELECT extname, extversion FROM pg_extension WHERE extname IN ('uuid-ossp', 'pgcrypto', 'pgjwt') ORDER BY extname;
209+
210+
-- Basic table creation test
211+
CREATE TABLE IF NOT EXISTS smoke_test (id serial primary key, created_at timestamptz default now());
212+
INSERT INTO smoke_test DEFAULT VALUES;
213+
SELECT * FROM smoke_test;
214+
DROP TABLE smoke_test;
215+
EOSQL
216+
217+
log_info "''${GREEN}CLI Smoke Test PASSED for PostgreSQL $PG_VERSION''${NC}"
218+
}
219+
220+
main "$@"
221+
'';
222+
}

0 commit comments

Comments
 (0)