Skip to content

feat(cli): add migration generate, run, status & undo#18193

Merged
WikiRik merged 30 commits intomainfrom
alyx/run-migrations
Apr 12, 2026
Merged

feat(cli): add migration generate, run, status & undo#18193
WikiRik merged 30 commits intomainfrom
alyx/run-migrations

Conversation

@ephys
Copy link
Copy Markdown
Member

@ephys ephys commented Apr 5, 2026

Pull Request Checklist

  • Have you added new tests to prevent regressions?
  • If a documentation update is necessary, have you opened a PR to the documentation repository?
  • Did you update the typescript typings accordingly (if applicable)?
  • Does the description below contain a link to an existing issue (Closes #[issue]) or a description of the issue you are solving?
  • Does the name of your PR follow our conventions?

Description of Changes

This PR implements sub-commands for sequelize migration: run, status, and undo

image

run

➜  sequelize git:(alyx/run-migrations) npx sequelize migration run --help
Runs pending database migrations

USAGE
  $ sequelize migration run [--json] [-i] [--to <value>] [--step <value>]

FLAGS
  -i, --[no-]interactive  Run command in interactive mode
      --step=<value>      Run only this many pending migrations
      --to=<value>        Run migrations up to and including this migration name

GLOBAL FLAGS
  --json  Format output as json.

EXAMPLES
  $ sequelize migration run

  $ sequelize migration run --to=20240101000000-create-users

  $ sequelize migration run --step=1

Like the others, supports JSON & plain text:

➜  cli git:(alyx/run-migrations) ✗ ./bin/run.js migration run
event=migrating name=2024-01-01-create-users
event=migrated name=2024-01-01-create-users durationSeconds=0.022
event=migrating name=2024-01-02-create-posts
event=migrated name=2024-01-02-create-posts durationSeconds=0.019
event=migrating name=2024-01-03-create-comments
event=migrated name=2024-01-03-create-comments durationSeconds=0.033
Successfully ran 3 migration(s).
  ✔ 2024-01-01-create-users
  ✔ 2024-01-02-create-posts
  ✔ 2024-01-03-create-comments
➜  cli git:(alyx/run-migrations) ✗ ./bin/run.js migration run --json
{
  "migrated": [
    "2024-01-01-create-users",
    "2024-01-02-create-posts",
    "2024-01-03-create-comments"
  ]
}

Status

➜  sequelize git:(alyx/run-migrations) npx sequelize migration status --help
Shows the status of all database migrations

USAGE
  $ sequelize migration status [--json] [-i]

FLAGS
  -i, --[no-]interactive  Run command in interactive mode

GLOBAL FLAGS
  --json  Format output as json.

EXAMPLES
  $ sequelize migration status

  $ sequelize migration status --json

Undo

➜  sequelize git:(alyx/run-migrations) npx sequelize migration undo --status
 ›   Error: Nonexistent flag: --status
 ›   See more help with --help

USAGE
  $ sequelize migration undo [--json] [-i] [--all] [--to <value> | --step <value>]

FLAGS
  -i, --[no-]interactive  Run command in interactive mode
      --all               Revert all executed migrations
      --step=<value>      [default: 1] Number of migrations to revert (default: 1)
      --to=<value>        Revert migrations down to and including this migration name. Implies --all when specified.

GLOBAL FLAGS
  --json  Format output as json.

Other changes

The "dialect" option in the config file does not accept dialect names anymore. Instead it must be either a dialect class (e.g., PostgresDialect), or a path to a dialect class (e.g., '@sequelize/postgres#PostgresDialect', for when using a JSON config file)

The interactive mode does not prompt for optional flags anymore

Importing @sequelize/cli does not return oclif anymore, but the API files

List of Breaking Changes

  • The database.dialect option is now either a Dialect class (e.g. PostgresDialect) or a path to a dialect class (e.g. '@sequelize/postgres#PostgresDialect')
  • Importing @sequelize/cli now exposes the JavaScript functions used in the CLI instead of the oclif run function

TODO

  • Document new CLI in website

Summary by CodeRabbit

  • New Features

    • Added CLI migration commands: run, status, undo with JSON output; supports --to/--step and --all flags; runs SQL and JS/TS migrations and reports executed vs pending.
  • Tests

    • Added end-to-end CLI tests covering run, status, undo, partial/targeted runs, and helpers to manage deterministic migration fixtures.
  • Chores

    • Ignored test-artifacts, updated CLI build/config and CI Windows runner.
  • Style

    • Relaxed ESLint rules for test files to reduce noisy warnings.

@ephys ephys requested a review from a team as a code owner April 5, 2026 08:26
@ephys ephys requested review from WikiRik and sdepold April 5, 2026 08:26
@sequelize-bot sequelize-bot bot added the conflicted This PR has merge conflicts and will not be present in the list of PRs to review label Apr 5, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 5, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a Sequelize+Umzug migration subsystem to the CLI: dynamic dialect resolution, stricter config types, migration discovery/execution APIs (run/undo/status), oclif commands with JSON output, test fixtures/helpers, and supporting packaging/configuration changes.

Changes

Cohort / File(s) Summary
ESLint & Gitignore
\.eslintrc.js, packages/cli/.gitignore
Broadened test override glob to **/*.test.{ts,js} and added test-specific rule exceptions (func-names, @typescript-eslint/no-invalid-this); ignored packages/cli/test-artifacts.
Package & Sequelize config
packages/cli/package.json, packages/cli/sequelize.config.mjs
Added Sequelize/Umzug dependencies and adjusted oclif build settings; added deterministic SQLite config storing DB at test-artifacts/test.sqlite3.
Config internals & types
packages/cli/src/_internal/config.ts, packages/cli/src/config.ts
Introduced DialectClass and generic Config types, stricter zod schema, and resolveDialectClass() to normalize database.dialect to a dialect constructor at runtime.
Umzug core API
packages/cli/src/api/get-umzug.ts, packages/cli/src/api/run-migrations.ts, packages/cli/src/api/undo-migrations.ts, packages/cli/src/api/get-migration-status.ts
Added Umzug creation with SequelizeStorage, migration discovery/resolution (SQL files, JS/TS modules, SQL dirs), and exported run/undo/status functions that manage Sequelize lifecycle and optional logging.
CLI command layer
packages/cli/src/_commands/migration/run.ts, packages/cli/src/_commands/migration/status.ts, packages/cli/src/_commands/migration/undo.ts, packages/cli/src/index.ts
New oclif commands (run/status/undo) with flags (--to,--step,--all) and JSON output; package entry re-exports migration APIs.
Command runtime helpers & tests
packages/cli/src/_internal/sequelize-command.ts, packages/cli/src/_internal/test-helpers.ts, packages/cli/src/_commands/migration/*.test.ts
Added makeUmzugLogger, adjusted interactive prompting to only prompt required flags, test fixture reset helper, and integration tests for run/status/undo flows.
Export sync tool
dev/sync-exports.mjs
Tightened export-filter rules to exclude any underscore-prefixed path segment when generating barrel exports.
Misc & CI
packages/core/test/support.ts, .github/workflows/ci.yml
Removed some inline ESLint no-invalid-this disables in test support; changed Windows runner image from windows-latest to windows-2022.

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI as CLI Command
    participant API as Migration API
    participant Umzug
    participant Sequelize
    participant DB as SQLite DB
    participant FS as File System

    User->>CLI: migration:run (--step=2)
    CLI->>API: runMigrations(options)
    API->>API: createUmzug()
    API->>Sequelize: new Sequelize(config)
    Sequelize->>DB: connect()
    API->>FS: scan migrationFolder
    FS-->>API: [migration files/dirs]
    API->>Umzug: register migrations (SQL / JS modules / dirs)
    Umzug->>Sequelize: use SequelizeStorage
    API->>Umzug: umzug.up({step: 2})
    Umzug->>FS: read up.sql / import module
    FS-->>Umzug: SQL / JS migration
    Umzug->>Sequelize: execute migration SQL / call up()
    Sequelize->>DB: run SQL
    DB-->>Sequelize: success
    Umzug->>Sequelize: update migrations table
    Umzug-->>API: [executed migrations]
    API->>Sequelize: close()
    API-->>CLI: MigrationMeta[]
    CLI-->>User: formatted output (JSON or human)
Loading
sequenceDiagram
    participant User
    participant CLI as CLI Command
    participant API as Migration API
    participant Umzug
    participant Sequelize
    participant DB as SQLite DB
    participant FS as File System

    User->>CLI: migration:undo (--all)
    CLI->>API: undoMigrations({to:0})
    API->>API: createUmzug()
    API->>Sequelize: new Sequelize(config)
    Sequelize->>DB: connect()
    API->>Umzug: umzug.down({to:0})
    loop for each migration (newest → oldest)
      Umzug->>FS: read down.sql / import module
      FS-->>Umzug: SQL / JS migration down
      Umzug->>Sequelize: execute down
      Sequelize->>DB: run SQL
      DB-->>Sequelize: success
      Umzug->>Sequelize: remove migration record
    end
    Umzug-->>API: [reverted migrations]
    API->>Sequelize: close()
    API-->>CLI: MigrationMeta[]
    CLI-->>User: formatted output (JSON or human)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰 I hopped through code and SQL track,

Umzug and Sequelize kept things on track.
Fixtures tucked, commands proclaim,
Run, status, undo — every name.
A tiny rabbit cheers the migration pack!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically describes the main addition: migration sub-commands (generate, run, status, undo) for the CLI, matching the primary focus of the changeset.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch alyx/run-migrations

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot]

This comment was marked as resolved.

@ephys ephys marked this pull request as draft April 5, 2026 08:36
coderabbitai[bot]

This comment was marked as resolved.

@ephys ephys marked this pull request as ready for review April 5, 2026 09:10
@sequelize-bot sequelize-bot bot removed the conflicted This PR has merge conflicts and will not be present in the list of PRs to review label Apr 5, 2026
coderabbitai[bot]

This comment was marked as resolved.

@WikiRik
Copy link
Copy Markdown
Member

WikiRik commented Apr 5, 2026

sqlite3 is going back to the upstream in #18189 so maybe the Windows issue doesn't occur anymore after it?

@ephys
Copy link
Copy Markdown
Member Author

ephys commented Apr 5, 2026

I'll revert the pin if it passes on your branch :)

@sequelize-bot sequelize-bot bot added the conflicted This PR has merge conflicts and will not be present in the list of PRs to review label Apr 5, 2026
@sequelize-bot sequelize-bot bot removed the conflicted This PR has merge conflicts and will not be present in the list of PRs to review label Apr 5, 2026
@ephys ephys marked this pull request as draft April 6, 2026 17:38
@ephys ephys marked this pull request as ready for review April 6, 2026 18:52
Copy link
Copy Markdown
Member

@WikiRik WikiRik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ran some parts through AI. I am missing some tests for JS/TS migration files and if there's only an up.sql

If you want I can commit the changes I let AI make to another PR (or to this PR directly)

Comment thread packages/core/test/unit/query-interface/debug-random.ts Outdated
Comment thread packages/cli/src/api/get-umzug.ts Outdated
Comment thread packages/cli/src/api/get-umzug.ts Outdated
Comment thread packages/cli/src/api/get-umzug.ts Outdated
Comment thread packages/cli/src/api/get-umzug.ts
@ephys ephys requested a review from WikiRik April 12, 2026 13:38
@WikiRik WikiRik enabled auto-merge (squash) April 12, 2026 15:05
@WikiRik WikiRik merged commit d6b884d into main Apr 12, 2026
146 of 147 checks passed
@WikiRik WikiRik deleted the alyx/run-migrations branch April 12, 2026 16:36
@github-project-automation github-project-automation bot moved this from Waiting for merge to To document in PRs & Issues to document on website Apr 12, 2026
@ephys ephys moved this from To document to Documenting in PRs & Issues to document on website Apr 12, 2026
papandreou added a commit to papandreou/sequelize that referenced this pull request Apr 15, 2026
* main: (200 commits)
  meta: update actions/upload-artifact action to v7.0.1 (sequelize#18212)
  meta: update sequelize AUTHORS (sequelize#18208)
  feat(cli): add migration generate, run, status & undo (sequelize#18193)
  feat(core): Drop the ability to specify the dialect as a string (sequelize#18204)
  feat: update some dialect adapters (sequelize#18189)
  feat(postgres): replace pg-hstore with inline hstore parser (sequelize#18151)
  feat(core): add `sql.random`, improve `Order` typing (sequelize#18203)
  meta: use Sequelize Bot for drafting PRs (sequelize#18201)
  meta: automatically mark unfinished PRs as draft (sequelize#18197)
  meta: update dependency @oclif/test to v4.1.18 (sequelize#18198)
  fix(core): replace @typeparam with @template in JSDoc (sequelize#18094)
  feat(core): Add support for UUID v7 (sequelize#17832)
  meta: update sequelize AUTHORS (sequelize#18190)
  meta: update dependency @oclif/plugin-help to ^6.2.43 (sequelize#18195)
  meta: update dependency esbuild to v0.28.0 (sequelize#18192)
  meta: update dependency @oclif/plugin-help to ^6.2.42 (sequelize#18191)
  meta: update dependency @oclif/core to ^4.10.5 (sequelize#18187)
  meta: update sequelize AUTHORS (sequelize#18158)
  feat: add Node 24 support, drop Node 18 (sequelize#18185)
  feat(core): add support for readonly attribute arrays (sequelize#18186)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Documenting

Development

Successfully merging this pull request may close these issues.

2 participants