110 lines
5.4 KiB
Markdown
110 lines
5.4 KiB
Markdown
# Database CI runbook
|
|
|
|
## Purpose
|
|
|
|
The database CI gate verifies that the repository can reach its configured database and that Prisma reports migration status through the package-owned database boundary. The root command `pnpm run verify:db-migrate-status` shells through `pnpm --filter @hivegrid/db prisma:migrate:status`, so CI and local checks use the same `@hivegrid/db` command surface instead of invoking Prisma directly.
|
|
|
|
This is a non-E2E gate. Auto-Mode does not run browser, Playwright, Cypress, or other E2E checks for this task, and the database job must not include browser automation commands.
|
|
|
|
## Required secret
|
|
|
|
Configure a CI secret named `DATABASE_URL` for the database status check. The secret must be scoped to the migrate-status step, not the whole job, so unrelated CI steps do not receive database credentials.
|
|
|
|
Use placeholder names in documentation and CI examples only:
|
|
|
|
- secret name: `DATABASE_URL`
|
|
- command: `pnpm run verify:db-migrate-status`
|
|
|
|
Do not paste connection strings, credentials, usernames, passwords, hosts, or database names into docs, issues, comments, or logs.
|
|
|
|
## Local dry run
|
|
|
|
To run the same status verifier locally, set `DATABASE_URL` in your shell environment using your normal secret-management workflow and run:
|
|
|
|
```sh
|
|
pnpm run verify:db-migrate-status
|
|
```
|
|
|
|
The verifier fails before spawning Prisma when `DATABASE_URL` is absent. It does not print the secret value.
|
|
|
|
## CI job order
|
|
|
|
The Gitea workflow includes a `database` job that depends on `quality`. The job installs dependencies with the pinned pnpm setup, generates the database client through `@hivegrid/db`, and then runs the non-E2E status verifier.
|
|
|
|
The database job generates the Prisma client, verifies the generated
|
|
tenant-policy contract and migration/schema parity, runs the ephemeral
|
|
live-RLS gate, checks migration status outside pull requests, and executes the
|
|
database package tests. It must not run `migrate deploy`, seed commands,
|
|
browser automation, or browser E2E checks.
|
|
|
|
## Live-RLS-Gate
|
|
|
|
Der getrennte Gate-Befehl
|
|
|
|
```sh
|
|
pnpm run verify:rls-live
|
|
```
|
|
|
|
startet eine wegwerfbare PostgreSQL-16-Instanz und beweist den vollständigen
|
|
Rollenvertrag. Er provisioniert `hivegrid_migrator`, `hivegrid_app`,
|
|
`hivegrid_portal`, `hivegrid_worker`, `hivegrid_authentik_jit` und
|
|
`hivegrid_rls_definer`, entzieht dem Migrator in einer
|
|
separaten Negativ-Datenbank absichtlich die Definer-Mitgliedschaft und erwartet
|
|
dort einen harten Migrationsfehler. Anschließend provisioniert er den korrekten
|
|
Vertrag erneut, spielt die gesamte Migration-Historie als nicht privilegierter
|
|
`hivegrid_migrator` auf eine frische Datenbank und führt die echten
|
|
App-/Portal-/Worker-Isolationstests aus.
|
|
|
|
Damit prüft das Gate ausdrücklich nicht nur RLS zur Laufzeit, sondern auch,
|
|
dass Migrationen keinen Superuser und kein `BYPASSRLS` auf dem Migrator
|
|
benötigen. Die Testpasswörter sind nur lokale, kurzlebige Fixtures und werden
|
|
nicht ausgegeben. Produktions-Secrets dürfen diesem Gate niemals übergeben
|
|
werden.
|
|
|
|
Das statische Gegenstück ist:
|
|
|
|
```sh
|
|
pnpm run verify:tenant-policy-contract
|
|
pnpm run verify:rls-release-readiness
|
|
```
|
|
|
|
Der erste Befehl verhindert Drift zwischen Scope-Manifest, fachlichem
|
|
Policy-Vertrag, generiertem SQL-Artefakt und Cutover-Migration. Der zweite
|
|
prüft, ob jedes laut Manifest RLS-pflichtige Modell in den auslieferbaren
|
|
Migrationen `ENABLE`, `FORCE` und eine kanonische Policy besitzt. Ein grüner
|
|
statischer Check ersetzt den Live-Test nicht; der Live-Test ersetzt wiederum
|
|
keinen Staging-/Produktions-Cutover mit den echten Rollen, Secrets,
|
|
Bestandsdaten und PgBouncer-/Coolify-Einstellungen.
|
|
|
|
Der aktuelle Implementierungs- und Operations-Handoff steht in
|
|
[`security/RLS-HARDENING-2026-07-13.md`](security/RLS-HARDENING-2026-07-13.md).
|
|
Dort ist der Produktions-Rollout ausdrücklich als noch nicht nachgewiesen
|
|
markiert.
|
|
|
|
## Status outcomes
|
|
|
|
`pnpm run verify:db-migrate-status` reports diagnostic fields intended for CI logs and local troubleshooting:
|
|
|
|
- `phase`: where the verifier is running or failing, such as preflight, spawn, or completion
|
|
- command: the package-bound command being executed
|
|
- exit code: the process exit code when Prisma finishes
|
|
- status outcome: success or failure classification
|
|
- sanitized stdout/stderr excerpt: a bounded output excerpt with secrets redacted
|
|
|
|
A success means Prisma migration status completed through the `@hivegrid/db` boundary. It does not apply migrations, seed data, or prove browser-facing behavior.
|
|
|
|
## Failure diagnostics
|
|
|
|
Common failures and first checks:
|
|
|
|
- Missing `DATABASE_URL`: confirm the CI secret exists and is scoped to the migrate-status step.
|
|
- Spawn failure: confirm pnpm dependencies are installed and the `@hivegrid/db` package scripts are available.
|
|
- Non-zero Prisma exit: inspect the sanitized stdout/stderr excerpt and the Prisma status message in CI logs.
|
|
- Workflow contract failure: run `pnpm run verify:gitea-ci-workflow` and fix the database job shape before changing the database verifier.
|
|
|
|
The primary inspection surfaces are CI job logs, `pnpm run verify:db-migrate-status`, `pnpm run verify:gitea-ci-workflow`, and this runbook.
|
|
|
|
## Redaction expectations
|
|
|
|
Diagnostics must never print `DATABASE_URL` or embedded credentials. The verifier redacts the literal configured value and credential-like URL components before showing output excerpts. If a failure report includes secret material, treat it as a security incident: remove the exposed value from the report, rotate the credential, and fix the redaction path before sharing more logs.
|