Skip to content

Commit 06df347

Browse files
calvinbrewerclaude
andcommitted
test(prisma-next): test-kit family integration suite + CI job
Implement makePrismaNextAdapter() behind the shared @cipherstash/test-kit IntegrationAdapter seam and run runFamilySuite over every family — the same derived capability matrix, plaintext oracle, single-vs-bulk insert crossover, ordering assertions, and absent/null handling that pin the Drizzle and Supabase adapters (PR #655 review, item 4). Queries lower through the real v3 operator registry + postgres adapter + bulk-encrypt middleware; inserts run one-row vs multi-row INSERT statements, prisma-next's two batching shapes. New CI workflow mirrors the Drizzle job on both database variants. 582 tests green against real ZeroKMS + live Postgres. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 69a2ef1 commit 06df347

6 files changed

Lines changed: 492 additions & 3 deletions

File tree

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
name: Integration — prisma-next (EQL v3)
2+
3+
# Real ZeroKMS ciphertext against a real Postgres, on BOTH database variants —
4+
# the prisma-next leg of the shared test-kit family driver (the same catalog,
5+
# oracle, and single-vs-bulk crossover as the Drizzle and Supabase jobs).
6+
#
7+
# The prisma-next adapter talks straight to the database, so it does not need
8+
# PostgREST — but it does need to work on managed Postgres, where the `postgres`
9+
# role is not a superuser, the EQL install takes its self-skipping path, and the
10+
# ORE domains cannot hold data. The Supabase compose file brings up PostgREST
11+
# too; this job simply ignores it.
12+
#
13+
# Separate from `tests.yml` on purpose: these suites need CipherStash credentials
14+
# and a database, and they THROW rather than skip when unconfigured. Keeping them
15+
# out of the unit job is what lets `pnpm test` stay runnable with neither.
16+
17+
on:
18+
push:
19+
branches: [main]
20+
paths:
21+
- 'packages/stack/src/eql/v3/**'
22+
- 'packages/prisma-next/**'
23+
# Source layers the adapter's encoding/round-trip rests on: a break here
24+
# (not just under src/eql/v3) can produce wrong rows, so trigger the live
25+
# suite that would catch it.
26+
- 'packages/stack/src/encryption/**'
27+
- 'packages/stack/src/schema/**'
28+
- 'packages/schema/**'
29+
- 'packages/test-kit/**'
30+
- 'packages/cli/src/installer/**'
31+
- 'local/docker-compose.postgres.yml'
32+
- 'local/docker-compose.supabase.yml'
33+
- 'local/supabase-init.sql'
34+
- '.github/workflows/integration-prisma-next.yml'
35+
- '.github/actions/integration-setup/**'
36+
pull_request:
37+
branches: ['**']
38+
# Repeated verbatim: GitHub Actions does not support YAML anchors/aliases.
39+
paths:
40+
- 'packages/stack/src/eql/v3/**'
41+
- 'packages/prisma-next/**'
42+
# Source layers the adapter's encoding/round-trip rests on: a break here
43+
# (not just under src/eql/v3) can produce wrong rows, so trigger the live
44+
# suite that would catch it.
45+
- 'packages/stack/src/encryption/**'
46+
- 'packages/stack/src/schema/**'
47+
- 'packages/schema/**'
48+
- 'packages/test-kit/**'
49+
- 'packages/cli/src/installer/**'
50+
- 'local/docker-compose.postgres.yml'
51+
- 'local/docker-compose.supabase.yml'
52+
- 'local/supabase-init.sql'
53+
- '.github/workflows/integration-prisma-next.yml'
54+
- '.github/actions/integration-setup/**'
55+
56+
jobs:
57+
integration:
58+
name: prisma-next v3 integration (db=${{ matrix.db }})
59+
runs-on: blacksmith-4vcpu-ubuntu-2404
60+
# Serialize every job that brings up the SAME docker-compose stack — same
61+
# rationale and keys as the Drizzle/Supabase workflows, so the jobs queue
62+
# on a shared runner rather than collide on the fixed host ports.
63+
concurrency:
64+
group: integration-live-db-${{ matrix.db }}
65+
cancel-in-progress: false
66+
# Fork PRs have no secrets. Skip cleanly rather than fail on something the
67+
# contributor cannot fix — `tests.yml` still gives them a green signal.
68+
if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }}
69+
70+
strategy:
71+
fail-fast: false
72+
# prisma-next talks straight to Postgres, so it runs against BOTH
73+
# databases. The Supabase variant is not a formality: its `postgres` role
74+
# is not a superuser, so the EQL install takes its self-skipping path. A
75+
# suite that passes on a superuser database can still fail there.
76+
matrix:
77+
include:
78+
- db: postgres
79+
database-url: postgres://cipherstash:password@localhost:55432/cipherstash
80+
pgrest-url: ''
81+
- db: supabase
82+
database-url: postgres://postgres:password@localhost:55433/postgres
83+
pgrest-url: http://localhost:55430
84+
85+
env:
86+
CS_WORKSPACE_CRN: ${{ vars.CS_WORKSPACE_CRN }}
87+
CS_CLIENT_ID: ${{ vars.CS_CLIENT_ID }}
88+
CS_CLIENT_KEY: ${{ secrets.CS_CLIENT_KEY }}
89+
CS_CLIENT_ACCESS_KEY: ${{ secrets.CS_CLIENT_ACCESS_KEY }}
90+
# Job-level env, not a `.env` file: `dotenv/config` does not override an
91+
# already-set `process.env`, so these win and no secret is written to disk.
92+
DATABASE_URL: ${{ matrix.database-url }}
93+
PGRST_URL: ${{ matrix.pgrest-url }}
94+
# EXPLICIT, never inferred — same rationale as the Drizzle workflow.
95+
CS_IT_DB_VARIANT: ${{ matrix.db }}
96+
97+
steps:
98+
- uses: actions/checkout@v6
99+
- uses: ./.github/actions/integration-setup
100+
101+
# Fast pre-flight: fail in seconds if a secret was rotated or cleared,
102+
# before the docker pull. The in-test `requireIntegrationEnv` is the
103+
# correctness guarantee; this is the cheap one.
104+
- name: Require CipherStash secrets
105+
uses: ./.github/actions/require-cs-secrets
106+
with:
107+
workspace-crn: ${{ vars.CS_WORKSPACE_CRN }}
108+
client-id: ${{ vars.CS_CLIENT_ID }}
109+
client-key: ${{ secrets.CS_CLIENT_KEY }}
110+
client-access-key: ${{ secrets.CS_CLIENT_ACCESS_KEY }}
111+
112+
# Belt-and-braces for the concurrency guard: a run that was hard-killed
113+
# can skip its `down` and leak a container holding the host port onto a
114+
# REUSED runner. `|| true` so a clean runner is not an error.
115+
- name: Clear any leaked containers from a prior run
116+
run: docker compose -f local/docker-compose.${{ matrix.db }}.yml down -v --remove-orphans || true
117+
118+
- name: Start ${{ matrix.db }}
119+
run: docker compose -f local/docker-compose.${{ matrix.db }}.yml up -d --wait
120+
121+
# `globalSetup` installs EQL v3 by shelling out to the real
122+
# `stash eql install --eql-version 3`, so an installer regression fails
123+
# here rather than hiding behind a test-only SQL apply.
124+
- name: prisma-next v3 family suites
125+
run: pnpm --filter @cipherstash/prisma-next run test:integration
126+
127+
- name: Stop ${{ matrix.db }}
128+
if: always()
129+
run: docker compose -f local/docker-compose.${{ matrix.db }}.yml down -v

0 commit comments

Comments
 (0)