Migrations not applying on Windows - "applied 0 migrations" message
Environment
- Umzug version: ^3.8.0
- Node.js version: v20.13.1
- OS: Windows 11
- Database: PostgreSQL
- Sequelize version: ^6.37.3
Description
I'm encountering an issue on Windows where running migrations with Umzug results in the message "applied 0 migrations." without actually applying any migrations. The same setup works as expected on macOS and Ubuntu.
Steps to Reproduce
- Set up Umzug with SequelizeStorage and given code.
- Run migrations on Windows.
Expected Behavior
Migrations should be applied, and the database should be updated accordingly.
Actual Behavior
The output is { event: 'up', message: 'applied 0 migrations.' } and no migrations are applied to the database.
Code Snippet
import { Umzug, SequelizeStorage } from "umzug";
import { Sequelize, DataTypes } from "sequelize";
import * as path from "path";
import "dotenv/config";
const sequelize = new Sequelize({
dialect: "postgres",
host: process.env.DB_HOST,
port: Number(process.env.DB_PORT),
username: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
logging: process.env.SEQUELIZE_LOG === "true",
});
export const migrator = new Umzug({
migrations: {
glob: [
"migrations/*.{js,cjs,mjs}",
{ cwd: path.dirname(import.meta.url.replace("file://", "")) },
],
},
context: { sequelize, DataTypes },
storage: new SequelizeStorage({
sequelize,
}),
logger: console,
});
migrator.runAsCLI();
Additional Context
My package.json has "type": "module".
This issue occurs only on Windows; the migrations work as expected on macOS and Ubuntu.
This will be tricky to debug because I don't have a windows machine. I suspect it's something to do with fast-glob not finding files. Try finding the compiled version of this line in your node_modules and adding some logging around it:
const paths = await glob(globString, {...globOptions, ignore, absolute: true})
If that's returning an empty array, there's your problem. You can then play around with the glob options to see what needs changing.
Thanks for the suggestion, @mmkal. Indeed, it returns an empty array on Windows. The issue seems to stem from how path.dirname(import.meta.url.replace("file://", "")) behaves on Windows, yielding a path like /D:/dev/. When I manually specify the cwd option, I encounter the following error:
failed: Original error: Only URLs with a scheme in: file, data, and node are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'd:'
This leads me to believe that the package might need to incorporate OS-specific handling to address this discrepancy.
I have this exact same issue with umzug. I found some insights from stackoverflow:
Quoting the site: import() function only works with file:// and data:// URLs, but path.resolve() only returns an absolute path (not a URL), which on Windows environment usually starts with the name of the local disk (e.g., C:).
So if i'm correct, the right url should be: file:///D:/Dev taken from previous post, note the triple /
example:
import { pathToFileURL } from 'url';
const file = pathToFileURL(process.cwd()).href;
I'm also seeing this issue, even when I hardcode the path i.e. file:///C:/code/project/sequelize/migrations/*.js it returns no migrations.
I've narrowed it down to fastglob not returning anything in the Umzug.getMigrationsResolver function
I'm still not totally clear on what the problem is, but I am sure that fast-glob can support windows, given the right inputs. A PR would to fix by someone using windows would be welcome.
I have tried to set it up on Windows to identify the issue, but encountered some challenges. The setup includes rm -rf commands in the package.json scripts and sh commands in the tests, which are not natively supported on Windows. After addressing these, I ran the tests, and most example snapshot tests failed along with some CLI tests.
I'm working on a PR to address the current issue mentioned in this GitHub issue.