Docs / Deployment / CI checks
CI checks
The pipeline lives in .github/workflows/ci.yml. It runs two jobs, test and e2e, both against a real Postgres, so a fork gets the same guarantees Keel is built with. Here's what runs and what a buyer needs to make it pass.
What triggers it
The workflow runs on every push to master or main and on every pull request. Both jobs run in parallel on ubuntu-latest.
Shared setup
Both jobs spin up a postgres:17 service container (user/password/db all keel, on port 5432) with a pg_isready healthcheck, so steps don't start until the database is actually up. The connection details are set once at the workflow level:
DATABASE_URL,postgresql://keel:keel@localhost:5432/keel, pointing at that service.BETTER_AUTH_SECRET, a throwaway placeholder value (fine, CI never handles real sessions).BETTER_AUTH_URL,http://localhost:3000.
A placeholder connection string won't do here: the lib/**/*.test.ts specs added alongside the money-path race fixes exercise real DB constraints, unique indexes, CHECK constraints, and transactions, that only a live Postgres enforces.
The test job
After actions/checkout, Node 22 setup, and oven-sh/setup-bun, it runs:
bun install --frozen-lockfile, clean install frombun.lock, failing if the lockfile is out of date.bun run typecheck,tsc --noEmit.bun run lint, ESLint.bun run db:migrate, applies migrations to the service Postgres so the schema exists before tests query it.bun run test, the Vitest suite (vitest run).
The e2e job
Same checkout, Node, Bun, and Postgres setup, then:
bun install --frozen-lockfilebun run db:migratebunx playwright install --with-deps chromium, installs the browser.bun run test:e2e, the Playwright suite.- On failure only, it uploads the
playwright-report/directory as an artifact (14-day retention) so you can inspect what broke.
If you fork this
The pipeline needs no repository secrets to pass. Every value it depends on (DATABASE_URL, the auth vars) is hardcoded in the workflow and points at the ephemeral Postgres service, and Postgres comes from GitHub's own service containers. Clone, push, and both jobs run green without touching Actions settings.
Keep bun.lock committed
CI installs with --frozen-lockfile, so adding a dependency without committing the updated bun.lock fails the run. That's on purpose: CI and your local bun run test install exactly the same versions.