Skip to content

feat: migration squashing#1152

Merged
thetutlage merged 8 commits into22.xfrom
feat/squashing
Mar 19, 2026
Merged

feat: migration squashing#1152
thetutlage merged 8 commits into22.xfrom
feat/squashing

Conversation

@Julien-R44
Copy link
Copy Markdown
Member

@Julien-R44 Julien-R44 commented Mar 7, 2026

AI-Generated PR Summary

This PR adds Laravel-style migration squashing to Lucid

It introduces a new schema:dump command that exports the current database schema to SQL, stores Lucid migration metadata alongside it, and allows future migration:* commands to bootstrap a fresh database from that dump instead of replaying the full migration history.

Support MySql, Postgres and Sqlite only

High-level flow

The feature is designed around a rolling schema baseline.

Typical flow:

  1. Run existing migrations as usual.
  2. Run schema:dump --prune.
  3. Commit the generated SQL dump and its .meta.json manifest.
  4. Delete the historical migration files from the configured migration paths.
  5. Create new migrations from that point forward.

On a fresh database, migration:run now:

  1. loads the stored SQL dump
  2. restores Lucid bookkeeping tables from that dump ( insert it into adonis_schema )
  3. runs only migrations created after the dump

The same cycle can be repeated multiple times:

  1. create a first dump and prune old migrations
  2. add new migrations over time
  3. run them normally
  4. create a new dump later
  5. prune again

Each new dump becomes the new baseline. The manifest is regenerated from the current contents of adonis_schema, so it naturally absorbs:

  • migrations already covered by previous dumps
  • migrations added after the previous dump

This means re-squashing is a first-class workflow, not a one-time operation.

What is included

  • New schema:dump command
  • Dialect-specific schema dump/load support for:
    • SQLite
    • MySQL
    • PostgreSQL
  • Automatic schema dump loading during migration:run when:
    • direction is up
    • dryRun is disabled
    • the target database has not run any migrations yet
    • a schema dump file exists
  • --schema-path support in migration:run and migration:fresh
  • --prune support in schema:dump
  • A sidecar .meta.json manifest stored next to the SQL dump
  • Squash-aware behavior for:
    • migration:status
    • migration:rollback
    • migration:reset
    • migration:refresh
    • DatabaseTestUtils

Why the manifest exists

Laravel is permissive when previously-ran migration files disappear from disk. Lucid has historically treated that as a corruption signal.

To preserve that stricter behavior while still supporting squashing, this PR adds a schema dump manifest that records the migrations intentionally absorbed into the dump.

That allows Lucid to distinguish between:

  • squashed: migration file was intentionally pruned after schema dump
  • corrupt: migration is missing unexpectedly

This keeps the current integrity signal useful instead of disabling it globally.

Command behavior

schema:dump

Generates:

  • database/schema/<connection>-schema.sql
  • database/schema/<connection>-schema.meta.json

The SQL dump includes:

  • the structural database schema
  • rows from adonis_schema
  • rows from adonis_schema_versions

With --prune, Lucid deletes the configured migration directories after the dump succeeds.

This assumes configured migration paths are dedicated migration directories.

migration:run

When the target database is fresh and a dump exists, Lucid now:

  1. loads the stored schema dump
  2. restores Lucid migration bookkeeping tables from that dump
  3. runs only migrations created after the dump

If no dump exists, Lucid falls back to the existing migration flow.

migration:status

Status output now includes a new squashed state for migrations that were previously run, are no longer on disk, and are listed in the dump manifest.

Missing migrations that are not part of the manifest remain corrupt.

migration:rollback / migration:reset

Rollback and reset now skip missing migrations that are marked as squashed, while continuing to fail for truly missing / corrupt migrations.

This mirrors Laravel's tolerance for pruned historical migrations, but keeps Lucid's stricter semantics for accidental history drift.

Test utilities

This PR also ensures Lucid's test helpers continue to work after squashing.

DatabaseTestUtils now behaves correctly with schema dumps and pruned migrations because the underlying migration commands are squash-aware.

@Julien-R44 Julien-R44 marked this pull request as ready for review March 7, 2026 16:05
Comment thread commands/migration/rollback.ts
Comment thread commands/schema_dump.ts Outdated
Comment thread src/migration/schema_dump/helpers/postgres_connection.ts Outdated
@thetutlage thetutlage merged commit 153a82f into 22.x Mar 19, 2026
25 of 27 checks passed
@thetutlage
Copy link
Copy Markdown
Member

Let's get it in. Great work @Julien-R44 👏

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.

2 participants