Skip to content

v3.0.0-beta.6

Pre-release
Pre-release
Compare
Choose a tag to compare
@papb papb released this 12 Oct 00:24
· 151 commits to master since this release

We're close to v3!

This new beta version brings a lot more power and simplicity to the API. A minimal usage example is now:

const { Umzug } = require('umzug');

const umzug = new Umzug({
  migrations: {
    glob: 'path/to/migrations/*.js'
  },
  logger: console,
});

Breaking changes

  • The Umzug constructor now receives a migrations.glob parameter, which is more flexible than the previous path, pattern and traverseDirectories options (which were removed). This parameter can be a glob string (such as '**/*.migration.js') or have the form ['**/*.migration.js', { cwd: 'some/path', ignore: '**/some-ignore-glob/**/*' }].

  • The Umzug constructor now receives a migrations.resolve parameter, which is more flexible than the previous customResolver, wrap and nameFormatter options (which were removed). This parameter must be a function that receives an object with { path, name, context } and must return an object with up and down functions.

    • path is a string with the absolute path of the migration file
    • name is a string with the migration name
    • context is what will be provided to the migration functions, so they can run, such as queryInterface from Sequelize, for example
  • The signature for the up and down migration functions has changed. Previously, they would receive a single parameter of your choice (such as queryInterface from Sequelize, for example). That parameter is now called the migration context. Now, the up and down functions receive an object of the form { name, path, context } instead of just receiving context, so you can also act based on the migration name and file path, if needed. One way to upgrade is to modify each of your migrations to change the function signature. Another way is to use the new migrations.resolve parameter from the Umzug constructor, so that you automatically wrap your already existing up and down functions with the new syntax. Both solutions are shown below:

    • Slightly modifying each migration file:

       // my-migration-12345679.js
      
       // Before:
       async up(queryInterface) {
       	await queryInterface.foobar();
       }
      
       // After:
       async up({ context: queryInterface }) {
       	await queryInterface.foobar();
       }
    • Using the new migrations.resolve option:

       const umzug = new Umzug({
       	migrations: {
       		glob: 'migrations/umzug-v2-format/*.js',
       		resolve({ path }) {
       			// Get the `up` and `down` functions in the v2-style
       			const { up, down } = require(path);
      
       			// Return modified versions
       			return {
       				up: ({ context }) => up(context),
       				down: ({ context }) => down(context)
       			}
       		}
       	},
       	context: sequelize.getQueryInterface(),
       });
  • The logging option was replaced with the new logger option. Instead of passing a single logging function, you can now pass a "complete" logger, which provides not only log but also warn and error functions, for example. The default is undefined.

     // Before
     new Umzug({ logging: console.log });
     new Umzug({ logging: false });
    
     // After
     new Umzug({ logger: console });
     new Umzug({ logger: undefined });
  • The Umzug#execute method was removed. Use Umzug#up or Umzug#down instead.

  • The options for Umguz#up and Umzug#down have changed:

    • umzug.up({ to: 'some-name' }) and umzug.down({ to: 'some-name' }) are still valid.
    • umzug.up({ from: '...' }) and umzug.down({ from: '...' }) are no longer supported. To run migrations out-of-order (which is not generally recommended), you can explicitly use umzug.up({ migrations: ['...'] }) and umzug.down({ migrations: ['...'] }).
    • name matches must be exact. umzug.up({ to: 'some-n' }) will no longer match a migration called some-name.
    • umzug.down({ to: 0 }) is still valid but umzug.up({ to: 0 }) is not.
    • umzug.up({ migrations: ['m1', 'm2'] }) is still valid but the shorthand umzug.up(['m1', 'm2']) has been removed.
    • umzug.down({ migrations: ['m1', 'm2'] }) is still valid but the shorthand umzug.down(['m1', 'm2']) has been removed.
    • umzug.up({ migrations: ['m1', 'already-run'] }) will throw an error, if already-run is not found in the list of pending migrations.
    • umzug.down({ migrations: ['m1', 'has-not-been-run'] }) will throw an error, if has-not-been-run is not found in the list of executed migrations.
    • umzug.up({ migrations: ['m1', 'm2'], force: true }) will re-apply migrations m1 and m2 even if they've already been run.
    • umzug.down({ migrations: ['m1', 'm2'], force: true }) will "revert" migrations m1 and m2 even if they've never been run.
    • umzug.up({ migrations: ['m1', 'does-not-exist', 'm2'] }) will throw an error if the migration name is not found. Note that the error will be thrown and no migrations run unless all migration names are found - whether or not force: true is added.
  • The return value of Umzug#executed() and Umzug#pending() has changed. It now returns an object with a name property and, if applicable, a path property (this field will not be returned if the migration is not bound to a file on the filesystem). It no longer returns an object with a file property.

  • The migrationSorting option was removed. The behavior can be replaced with the new (and much more powerful) Umzug#extend function, which creates a new Umzug instance based on your direct manipulation of the list of migrations. For example, to define a custom sorting for your migration files:

     const umzug =
     	new Umzug({
     		migrations: { glob: 'migrations/**/*.js' },
     		context: sequelize.getQueryInterface(),
     	})
     	.extend(migrations => migrations.sort((a, b) => b.path.localeCompare(a.path)));
  • Calling umzug.down({ to: undefined }) is now interpreted as equivalent to umzug.down(). Previously, it would be equivalent to umzug.down({ to: 0 }) instead.

Features

  • Added Umzug#extend, which creates a new Umzug instance based on your direct manipulation of the list of migrations.

  • Added the rerun option to Umzug#up and Umzug#down, which can be one of 'THROW', 'ALLOW', 'SKIP'. This lets you customize what umzug does when it is told to execute a migration that was already executed (or revert one that was not executed yet). The default is 'THROW', which matches previous behavior, so this is not a breaking change.

Commits

v3.0.0-beta.5...v3.0.0-beta.6