Skip to content

ci: run the suite and an upgrade check against real Postgres - #464

Merged
Bccorb merged 1 commit into
mainfrom
ci/postgres-suite-and-upgrade
Oct 21, 2026
Merged

Bccorb merged 1 commit into
mainfrom
ci/postgres-suite-and-upgrade

Conversation

@Bccorb

@Bccorb Bccorb commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Closes #436

Adds .github/workflows/postgres.yml, which runs on pull requests touching src/migrations, src/models, the database config, or the services and controllers that send their own SQL (plus its own files), nightly, and on workflow_dispatch.

Jobs

Suite on Postgres. TEST_DB=postgres npm run test:run against a postgres:18-alpine service. In that mode vitest.config.ts adds a postgres project next to the existing unit one. Its global setup drops and recreates the public schema (refusing any database whose name lacks test) and runs the real migration chain with sequelize-cli, then the specs under tests/postgres/ run with none of the shared mocks:

  • auditChain.spec.ts: concurrent inserts form one unbroken chain; UPDATE, DELETE and TRUNCATE are refused by the triggers; a tampered row is reported as hash_mismatch and verifies again once restored; retention archives a prefix and what remains still verifies from the archive's last hash.
  • rawSqlServices.spec.ts: seeds users, a credential, an organization and auth events in an isolated time window and checks exact figures from sign-in metrics, funnel metrics, the coverage report, enrollment, review account usage, the audit export, the schema guard and getDatabaseSize.

The old tests/setup/globalSetup.ts ran sequelize.sync({ force: true }) before any model was registered, so with TEST_DB=postgres it connected and tested nothing. It is removed. The default mock run is unchanged (138 files, same coverage).

Upgrade from the previous release. Resolves the newest v* tag not on HEAD (or the previous-ref dispatch input), checks it out in a worktree, runs its migrations on an empty database, then scripts/upgrade-check/seed.mjs writes realistic rows (users, credentials, TOTP, organizations and memberships, rotated and active sessions, a magic link, OAuth and external ids, an auth failure, admin-managed system_config, and twelve auth events chained by the previous release's trigger) and snapshots every table. After the current migrations, scripts/upgrade-check/verify.mjs fails on any seeded row, column or value that changed or disappeared, unless listed in its EXPECTED_CHANGES, and also checks that the schema guard sees no pending migrations, the audit chain verifies with every seeded event, bootstrapSystemConfig plus getSystemConfig succeed, every model can read its table, and a new event extends the chain.

No changeset: CI and test-only change.

Local verification

Against Postgres 18.6 in throwaway databases (all dropped afterwards):

  • npm run typecheck, npm run lint, npm run format:check: clean.
  • npm run test:run: 138 files, 1879 passed, 1 todo. npm run coverage: 98.93 / 95.41 / 99.28 / 99.16, thresholds met.
  • TEST_DB=postgres npm run test:run: 140 files, 1893 passed, 1 todo (the 14 new postgres specs pass; run twice).
  • Upgrade check from v0.19.1 (same migration set as HEAD today): passed, 15 tables compared.
  • Upgrade check from v0.16.0 (five migrations behind, including the one that chains existing audit rows): passed, chain verified with all 12 seeded events.
  • Negative check: a throwaway migration that reset a credential counter, deleted a revoked session and dropped totp_credentials.issuer failed with credentials.counter ...: 7 became 0, sessions ...: row is gone, totp_credentials.issuer: column is gone and TotpCredential: column "issuer" does not exist.

No test failed on real Postgres and no product bug was found; the only harness fix was the global setup above.

Adds a postgres workflow, run on PRs that touch migrations, models or the
services that send their own SQL, nightly, and on dispatch.

- suite: with TEST_DB=postgres the run migrates a real database and adds a
  postgres vitest project (tests/postgres) that exercises the audit hash
  chain triggers, retention and the raw SQL services without mocks. The old
  global setup synced no models and so tested nothing; it is removed.
- upgrade: migrates to the newest v* tag not on HEAD, seeds users,
  credentials, sessions, chained auth events, system_config and the rest,
  runs the current migrations, then compares every seeded row and checks the
  chain verifies, the schema guard is satisfied and every model can read.

Closes #436
@Bccorb
Bccorb merged commit d3408b1 into main Oct 21, 2026
9 checks passed
@Bccorb Bccorb mentioned this pull request Oct 21, 2026
5 of 35 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ci: run the suite and the migration chain against real Postgres

1 participant