diff --git a/.changeset/heavy-lobsters-attack.md b/.changeset/heavy-lobsters-attack.md new file mode 100644 index 0000000..204aa3b --- /dev/null +++ b/.changeset/heavy-lobsters-attack.md @@ -0,0 +1,5 @@ +--- +'@emigrate/cli': patch +--- + +Ignore migration history entries not belonging to the current migration directory when considering what to list or execute. This way a project can have multiple folders with different kind of migration sets or multiple projects can share the same migration history without any of them conflicting or blocking each other in case of failed migrations. diff --git a/README.md b/README.md index 7a7c877..82ace5e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,8 @@ It's effectively a successor of [klei-migrate](https://www.npmjs.com/package/kle - Database agnostic - Emigrate can migrate any database - Works at any scale - - Supports any database as storage so multiple instances can share the same migration history + - Supports any database as storage so multiple instances of the same app can share the same migration history + - Supports multiple projects/apps doing migrations on the same database without interfering with each other - Uses smart locking to ensure only one instance migrates a certain migration at a time - Thanks to the smart locking it's safe to run migrations in parallel - Can be run inside containers diff --git a/packages/cli/src/commands/list.ts b/packages/cli/src/commands/list.ts index 10664e6..5cbdd47 100644 --- a/packages/cli/src/commands/list.ts +++ b/packages/cli/src/commands/list.ts @@ -40,6 +40,13 @@ export default async function listCommand({ directory, reporter: reporterConfig, const finishedMigrations: MigrationMetadataFinished[] = []; for await (const migrationHistoryEntry of storage.getHistory()) { + const index = migrationFiles.findIndex((migrationFile) => migrationFile.name === migrationHistoryEntry.name); + + if (index === -1) { + // Only care about entries that exists in the current migration directory + continue; + } + const filePath = path.resolve(cwd, directory, migrationHistoryEntry.name); const finishedMigration: MigrationMetadataFinished = { name: migrationHistoryEntry.name, @@ -65,11 +72,7 @@ export default async function listCommand({ directory, reporter: reporterConfig, finishedMigrations.push(finishedMigration); - const index = migrationFiles.findIndex((migrationFile) => migrationFile.name === migrationHistoryEntry.name); - - if (index !== -1) { - migrationFiles.splice(index, 1); - } + migrationFiles.splice(index, 1); } for await (const migration of migrationFiles) { diff --git a/packages/cli/src/commands/up.ts b/packages/cli/src/commands/up.ts index 914689b..757c1da 100644 --- a/packages/cli/src/commands/up.ts +++ b/packages/cli/src/commands/up.ts @@ -67,6 +67,11 @@ export default async function upCommand({ for await (const migrationHistoryEntry of storage.getHistory()) { const index = migrationFiles.findIndex((migrationFile) => migrationFile.name === migrationHistoryEntry.name); + if (index === -1) { + // Only care about entries that exists in the current migration directory + continue; + } + if (migrationHistoryEntry.status === 'failed') { const filePath = path.resolve(cwd, directory, migrationHistoryEntry.name); const finishedMigration: MigrationMetadataFinished = { @@ -86,9 +91,7 @@ export default async function upCommand({ failedEntries.push(finishedMigration); } - if (index !== -1) { - migrationFiles.splice(index, 1); - } + migrationFiles.splice(index, 1); } const migrationFileExtensions = new Set(migrationFiles.map((migration) => migration.extension));