Skip to content

Added Ghost-specific Knex adapter tests for Better Auth - #32615

Merged
acburdine merged 1 commit into
mainfrom
claude/knex-adapter-mysql-ci-601859
Nov 6, 2026
Merged

acburdine merged 1 commit into
mainfrom
claude/knex-adapter-mysql-ci-601859

Conversation

@acburdine

Copy link
Copy Markdown
Member

ref https://linear.app/ghost/issue/PLA-597/get-the-knex-adapter-suite-green-on-mysql-in-ci

Better Auth's adapter suite already runs on MySQL in the integration lane, but it can't cover behaviour that only exists because of Ghost's schema. This adds test/integration/auth/knex-adapter-ghost.test.ts, which runs against Ghost's real test database:

  • Virtual email_verified: reads true for every user, filters on the expression, and writes of either value are dropped without error.
  • Virtual two_factor_enabled: true only with a verified user_two_factors row. No row, or only an unverified one, reads false. Writes are dropped. Fields come from ghostTwoFactorSchema.
  • createDefaults: a user created through Better Auth gets slug set to its id and password set to !, and @tryghost/security's compare rejects that hash.
  • Dates: user_sessions, user_accounts and verifications keep their milliseconds through the adapter and in the stored row.

user_two_factors becomes an in-development table in schema.js, so it only exists in development and testing databases and has no migration. That way the test checks two_factor_enabled against the table definition the twoFactor plugin will use, rather than one the test builds for itself. The table holds TOTP secrets and backup codes, so it's added to the exporter's BACKUP_TABLES and stays out of exports by default, like the other auth tables.

For reviewers:

  • Every existing suite skip still has its cause documented in the README. The virtual columns behave as the issue specifies, so plan §10's fallback (real users columns) isn't needed.
  • user_two_factors has no unique key on user_id and no index on secret (the plugin marks secret as indexed, but it's a text column).
  • To check the new tests catch regressions, I broke the virtual columns and the default password locally: 5 of the 11 tests failed.

Run locally on MySQL 8, all passing: the auth integration tests (482 passed, the suite's usual 15 skips), the exporter and migration integration tests, and the schema and exporter unit tests.

  • I've read and followed the Contributor Guide
  • I've explained my change
  • I've written an automated test to prove my change works

🤖 Generated with Claude Code

ref https://linear.app/ghost/issue/PLA-597/get-the-knex-adapter-suite-green-on-mysql-in-ci

Better Auth's adapter suite can't cover the parts of the adapter that only
exist because of Ghost's schema: the virtual email_verified and
two_factor_enabled columns, the users create defaults, and millisecond dates
on the new tables. These tests pin that behaviour against Ghost's real test
database, so the virtual columns are proven before plan §10 open decision 1
is settled.

user_two_factors becomes an in-development table rather than something the
test builds itself, so two_factor_enabled is tested against the definition
the twoFactor plugin will use. It holds TOTP secrets and backup codes, so it
is left out of exports by default like the other auth tables.
@coderabbitai

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The schema adds user_two_factors with a user reference, secret and backup-code fields, verification and failure-count defaults, and a nullable lock timestamp. The table is marked in development and added to the optional backup table list. Exporter tests check its table key and its absence from exported data. A database-backed integration suite tests Ghost-specific adapter behavior, including virtual values, creation defaults, and millisecond date round-tripping.

Possibly related PRs

  • TryGhost/Ghost#32609: Changes adapter ID generation, which the new adapter tests configure when creating rows.
  • TryGhost/Ghost#32583: Adds the Knex adapter, virtual columns, and user creation defaults that this PR tests against Ghost's database.
  • TryGhost/Ghost#32584: Adds in-development auth tables and millisecond date support covered by this PR's date round-trip tests.

Suggested reviewers: allouis

Merge Risk: Minimal · up to c6c04

No actionable issue remains from this review; the change is mergeable after normal checks.

Pre-merge checks: Passed 7

Check name Status Explanation
Title check Passed The title clearly identifies the main change: Ghost-specific Knex adapter tests for Better Auth.
Description check Passed The description covers the adapter tests, the in-development table, and the exporter change.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Type-Safe Boundaries Passed The production TypeScript change adds a table name to a list. It adds no boundary-data consumption or typing bypass. The other code changes are in tests or existing JavaScript files, which this check …
New Files Are Typescript Passed The PR adds one TypeScript test file. It adds no JavaScript files. The JavaScript files in the diff already exist.
Tooling Ownership Passed The PR changes Core schema and exporter code, documentation, and integration tests. The new adapter test is beside the existing auth integration tests. No tooling entrypoints, scripts, or shared confi…
Full details: Type-Safe Boundaries

Explanation

The production TypeScript change adds a table name to a list. It adds no boundary-data consumption or typing bypass. The other code changes are in tests or existing JavaScript files, which this check excludes.

Full details: Tooling Ownership

Explanation

The PR changes Core schema and exporter code, documentation, and integration tests. The new adapter test is beside the existing auth integration tests. No tooling entrypoints, scripts, or shared configurations move or change.

Finishing Touches

Generate docstrings

  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between a34a57d and c6c0491.

Files selected for processing: 6

  • ghost/core/server/auth/better-auth/README.md
  • ghost/core/server/data/exporter/table-lists.js
  • ghost/core/server/data/schema/in-development.ts
  • ghost/core/server/data/schema/schema.js
  • ghost/test/integration/auth/knex-adapter-ghost.test.ts
  • ghost/test/integration/exporter/exporter.test.js

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Recent review details

Additional context used

Code guidelines: 5

docs/practices/database-migrations.md — configured
docs/contributing/testing.md — configured
docs/practices/error-handling.md — configured
tools/README.md — configured
docs/codebase/monorepo-structure.md — configured
Path-based instructions: 10

Review migration safety beyond lint: schema and migration parity, existing-data shape and volume, deploy/rollback compatibility, transaction and locking risk, idempotency, export/integrity updates, and preservation of constraints/defaults.

CodeRabbit configuration file

Files:

  • ghost/core/server/data/schema/in-development.ts
  • ghost/core/server/data/schema/schema.js
Review whether tests prove changed behaviour, meaningful error/edge paths, and externally observable contracts without coupling to implementation details.

CodeRabbit configuration file

Files:

  • ghost/test/integration/exporter/exporter.test.js
  • ghost/test/integration/auth/knex-adapter-ghost.test.ts
New source files must be TypeScript: flag new JS files as a required change unless exempt (DB migrations, tool/config files, tools/scripts/, docker/, generated code).

CodeRabbit configuration file

Files:

  • ghost/test/integration/exporter/exporter.test.js
  • ghost/core/server/data/schema/schema.js
  • ghost/core/server/data/exporter/table-lists.js
Review lens: "where does this data become trusted?" Boundary data (HTTP input, external API/SDK responses, env/config, DB/filesystem reads, queue/webhook/event payloads) is `unknown` until validated — Zod by default.

CodeRabbit configuration file

Files:

  • ghost/core/server/data/schema/in-development.ts
  • ghost/test/integration/auth/knex-adapter-ghost.test.ts
Prioritise concrete correctness, security, data-integrity, compatibility, and regression risks.

CodeRabbit configuration file

Files:

  • ghost/test/integration/exporter/exporter.test.js
  • ghost/core/server/data/schema/in-development.ts
  • ghost/core/server/auth/better-auth/README.md
  • ghost/core/server/data/schema/schema.js
  • ghost/core/server/data/exporter/table-lists.js
  • ghost/test/integration/auth/knex-adapter-ghost.test.ts
Source excerpt: The slug must be kebab-case, for example `add-column-to-posts`.

CodeRabbit inference engine (docs/practices/database-migrations.md)

Files:

  • ghost/core/server/data/schema/in-development.ts
  • ghost/core/server/data/schema/schema.js
Applicability reference: AGENTS.md: # AGENTS.md Start with: [Testing](docs/contributing/testing.md) Source excerpt: Put tests as close as possible to the code and behavior under test: **Unit tests** cover a function, compo...

CodeRabbit inference engine (docs/contributing/testing.md)

Files:

  • ghost/test/integration/exporter/exporter.test.js
  • ghost/test/integration/auth/knex-adapter-ghost.test.ts
Source excerpt: Use that fallback when there is no safe, useful message.

CodeRabbit inference engine (docs/practices/error-handling.md)

Files:

  • ghost/core/server/data/schema/in-development.ts
  • ghost/core/server/auth/better-auth/README.md
  • ghost/core/server/data/schema/schema.js
  • ghost/core/server/data/exporter/table-lists.js
Applicability reference: AGENTS.md: # AGENTS.md **Repository tooling:** read the [tooling ownership guide](tools/README.md) Source excerpt: Use `tools/` for shared configuration, repository automation and contributor comma...

CodeRabbit inference engine (tools/README.md)

Files:

  • ghost/test/integration/exporter/exporter.test.js
  • ghost/core/server/data/schema/in-development.ts
  • ghost/core/server/auth/better-auth/README.md
  • ghost/core/server/data/schema/schema.js
  • ghost/core/server/data/exporter/table-lists.js
  • ghost/test/integration/auth/knex-adapter-ghost.test.ts
Applicability reference: AGENTS.md: # AGENTS.md Start with: [Monorepo structure](docs/codebase/monorepo-structure.md) AGENTS.md: # AGENTS.md **Ghost Core:** use the [server map](docs/codebase/monorepo-structure.md#ghost-co...

CodeRabbit inference engine (docs/codebase/monorepo-structure.md)

Files:

  • ghost/test/integration/exporter/exporter.test.js
  • ghost/core/server/data/schema/in-development.ts
  • ghost/core/server/auth/better-auth/README.md
  • ghost/core/server/data/schema/schema.js
  • ghost/core/server/data/exporter/table-lists.js
  • ghost/test/integration/auth/knex-adapter-ghost.test.ts
Learnings: 1

Common learnings

Learnt from: CR
Repo: TryGhost/Ghost

Timestamp: 2026-11-06T00:06:59.901Z
Learning: Applicability reference:
AGENTS.md: # AGENTS.md
Start with:

- [Contribution workflow](docs/contributing/workflow.md)

Source excerpt:
# Contribution workflow

## Formatting

Source formatting is owned by [Oxfmt](https://oxc.rs/docs/guide/usage/formatter),
configured in the root `.oxfmtrc.json`: Oxfmt defaults plus single quotes, with
embedded-language formatting disabled so string contents are never rewritten.
CI rejects unformatted code, and the pre-commit hook formats staged files
automatically, so there is usually nothing to do. To format manually:

```bash
pnpm format path/to/file.ts
```
Learnt from: CR
Repo: TryGhost/Ghost

Timestamp: 2026-11-06T00:07:00.011Z
Learning: Applicability reference:
AGENTS.md: # AGENTS.md
Agent-specific execution guidance for the Ghost monorepo. Human-readable setup,
workflow, architecture, and practice guidance lives in the
[codebase documentation](docs/README.md) and nearby package READMEs.

Source excerpt:
# Ghost Codebase Documentation

## Guides

### Testing

Use `pnpm check` as the default one-stop command for formatting checks, linting,
and testing. Add tests at the closest layer to the behavior you changed. Browser
end-to-end tests run separately from `pnpm check`.
Learnt from: CR
Repo: TryGhost/Ghost

Timestamp: 2026-11-06T00:06:59.901Z
Learning: Applicability reference:
AGENTS.md: # AGENTS.md
Start with:

- [Contribution workflow](docs/contributing/workflow.md)

Source excerpt:
# Contribution workflow

## Make and validate the change

Add or update automated tests when behavior changes. Run the most focused checks
for the code you touched, following the README beside that workspace. Before
handing off a change, use the repository's one-stop formatting, lint, and test
command:

```bash
pnpm check
```
Additional comments: 6

ghost/core/server/data/schema/schema.js: 1

582-598: LGTM!

ghost/core/server/data/schema/in-development.ts: 1

25-30: LGTM!

ghost/core/server/data/exporter/table-lists.js: 1

30-30: LGTM!

ghost/test/integration/exporter/exporter.test.js: 1

126-126: LGTM!

Also applies to: 153-153

ghost/core/server/auth/better-auth/README.md: 1

62-64: LGTM!

Also applies to: 117-129

ghost/test/integration/auth/knex-adapter-ghost.test.ts: 1

1-270: LGTM!

@github-actions github-actions Bot added the migration [pull request] Includes migration for review label Nov 5, 2026
@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

It looks like this PR contains a migration 👀
Here's the checklist for reviewing migrations:

General requirements

  • ⚠️ Tested performance on staging database servers, as performance on local machines is not comparable to a production environment
  • Satisfies idempotency requirement (both up() and down())
  • Does not reference models
  • Filename is in the correct format (and correctly ordered)
  • Targets the next minor version
  • All code paths have appropriate log messages
  • Uses the correct utils
  • Contains a minimal changeset
  • Does not mix DDL/DML operations

Schema changes

  • Both schema change and related migration have been implemented
  • For index changes: has been performance tested for large tables
  • For new tables/columns: fields use the appropriate predefined field lengths
  • For new tables/columns: field names follow the appropriate conventions
  • Does not drop a non-alpha table outside of a major version

Data changes

  • Mass updates/inserts are batched appropriately
  • Does not loop over large tables/datasets
  • Defends against missing or invalid data
  • For settings updates: follows the appropriate guidelines

@nx-cloud

nx-cloud Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

🤖 Nx Cloud AI Fix

Ensure the fix-ci command is configured to always run in your CI pipeline to get automatic fixes in future runs. For more information, please see https://nx.dev/ci/features/self-healing-ci


View your CI Pipeline Execution ↗ for commit c6c0491

Command Status Duration Result
nx run ghost:test:ci:integration ✅ Succeeded 2m 55s View ↗
nx run ghost:test:integration ✅ Succeeded 2m 16s View ↗
nx run ghost:test:bullmq:scenarios ✅ Succeeded 59s View ↗
nx run ghost:test:bullmq ✅ Succeeded 52s View ↗
nx run ghost:test:ci:e2e ✅ Succeeded 5m 52s View ↗
nx run ghost:test:e2e ✅ Succeeded 4m 1s View ↗
nx run ghost:test:ci:unit ✅ Succeeded 1m 32s View ↗
nx run ghost:test:legacy ✅ Succeeded 1m 38s View ↗
Additional runs (8) ✅ Succeeded ... View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-11-05 22:04:18 UTC

@codecov

codecov Bot commented Nov 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.93%. Comparing base (a34a57d) to head (c6c0491).

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #32615      +/-   ##
==========================================
+ Coverage   85.77%   85.93%   +0.15%     
==========================================
  Files        1416     1416              
  Lines       53885    53885              
  Branches     9304     9304              
==========================================
+ Hits        46219    46304      +85     
+ Misses       6514     6434      -80     
+ Partials     1152     1147       -5     
Flag Coverage Δ
e2e-tests 73.38% <100.00%> (+0.03%) ⬆️
unit-tests 68.80% <ø> (+0.17%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@acburdine
acburdine marked this pull request as ready for review November 6, 2026 00:05
@acburdine
acburdine merged commit fa4d5e8 into main Nov 6, 2026
62 checks passed
@acburdine
acburdine deleted the claude/knex-adapter-mysql-ci-601859 branch November 6, 2026 00:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

migration [pull request] Includes migration for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant