fix(history): don't let different migration directories interfere with each other even though they share storage

This commit is contained in:
Joakim Carlstein 2023-11-24 11:10:01 +01:00
parent cf17e48f25
commit 9447d28ad8
4 changed files with 21 additions and 9 deletions

View file

@ -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.

View file

@ -9,7 +9,8 @@ It's effectively a successor of [klei-migrate](https://www.npmjs.com/package/kle
- Database agnostic - Database agnostic
- Emigrate can migrate any database - Emigrate can migrate any database
- Works at any scale - 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 - 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 - Thanks to the smart locking it's safe to run migrations in parallel
- Can be run inside containers - Can be run inside containers

View file

@ -40,6 +40,13 @@ export default async function listCommand({ directory, reporter: reporterConfig,
const finishedMigrations: MigrationMetadataFinished[] = []; const finishedMigrations: MigrationMetadataFinished[] = [];
for await (const migrationHistoryEntry of storage.getHistory()) { 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 filePath = path.resolve(cwd, directory, migrationHistoryEntry.name);
const finishedMigration: MigrationMetadataFinished = { const finishedMigration: MigrationMetadataFinished = {
name: migrationHistoryEntry.name, name: migrationHistoryEntry.name,
@ -65,12 +72,8 @@ export default async function listCommand({ directory, reporter: reporterConfig,
finishedMigrations.push(finishedMigration); 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) { for await (const migration of migrationFiles) {
const finishedMigration: MigrationMetadataFinished = { ...migration, status: 'pending', duration: 0 }; const finishedMigration: MigrationMetadataFinished = { ...migration, status: 'pending', duration: 0 };

View file

@ -67,6 +67,11 @@ export default async function upCommand({
for await (const migrationHistoryEntry of storage.getHistory()) { for await (const migrationHistoryEntry of storage.getHistory()) {
const index = migrationFiles.findIndex((migrationFile) => migrationFile.name === migrationHistoryEntry.name); 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') { if (migrationHistoryEntry.status === 'failed') {
const filePath = path.resolve(cwd, directory, migrationHistoryEntry.name); const filePath = path.resolve(cwd, directory, migrationHistoryEntry.name);
const finishedMigration: MigrationMetadataFinished = { const finishedMigration: MigrationMetadataFinished = {
@ -86,10 +91,8 @@ export default async function upCommand({
failedEntries.push(finishedMigration); failedEntries.push(finishedMigration);
} }
if (index !== -1) {
migrationFiles.splice(index, 1); migrationFiles.splice(index, 1);
} }
}
const migrationFileExtensions = new Set(migrationFiles.map((migration) => migration.extension)); const migrationFileExtensions = new Set(migrationFiles.map((migration) => migration.extension));
const loaderPlugins = await getOrLoadPlugins('loader', [lazyPluginLoaderJs, ...plugins]); const loaderPlugins = await getOrLoadPlugins('loader', [lazyPluginLoaderJs, ...plugins]);