From 882007c69f3519a11a8cdbe26607786beaf738f9 Mon Sep 17 00:00:00 2001 From: virgilchiriac <17074330+virgilchiriac@users.noreply.github.com> Date: Wed, 21 Feb 2024 09:14:34 +0100 Subject: [PATCH] BC-6620 - add migration pending command (#4778) --- .github/workflows/migrations.yml | 2 +- .../management/database-management.service.spec.ts | 8 ++++++++ .../management/database-management.service.ts | 8 +++++++- .../console/database-management.console.spec.ts | 5 +++++ .../console/database-management.console.ts | 12 +++++++++++- .../management/uc/database-management.uc.spec.ts | 5 +++++ .../modules/management/uc/database-management.uc.ts | 5 +++++ package.json | 1 + 8 files changed, 43 insertions(+), 3 deletions(-) diff --git a/.github/workflows/migrations.yml b/.github/workflows/migrations.yml index f151a28893f..070974741cc 100644 --- a/.github/workflows/migrations.yml +++ b/.github/workflows/migrations.yml @@ -26,4 +26,4 @@ jobs: - run: npm ci - run: npm run setup:db:seed - name: check no pending migrations (migration is in db) - run: test $(npx mikro-orm migration:pending | grep -c "Migration") -eq 0 + run: test $(npm run migration:pending | grep -c "Migration") -eq 0 diff --git a/apps/server/src/infra/database/management/database-management.service.spec.ts b/apps/server/src/infra/database/management/database-management.service.spec.ts index 5c90a318808..1119f645886 100644 --- a/apps/server/src/infra/database/management/database-management.service.spec.ts +++ b/apps/server/src/infra/database/management/database-management.service.spec.ts @@ -156,4 +156,12 @@ describe('DatabaseManagementService', () => { expect(orm.getMigrator().down).toHaveBeenCalledWith({ migrations: [params.only] }); }); }); + + describe('When call migrationPending()', () => { + it('should call migrator.getPendingMigrations()', async () => { + const spy = jest.spyOn(orm.getMigrator(), 'getPendingMigrations'); + await service.migrationPending(); + expect(spy).toHaveBeenCalled(); + }); + }); }); diff --git a/apps/server/src/infra/database/management/database-management.service.ts b/apps/server/src/infra/database/management/database-management.service.ts index 7adc00f15e1..8370ccfa213 100644 --- a/apps/server/src/infra/database/management/database-management.service.ts +++ b/apps/server/src/infra/database/management/database-management.service.ts @@ -3,7 +3,7 @@ import { EntityManager } from '@mikro-orm/mongodb'; import { Injectable } from '@nestjs/common'; import { BaseEntity } from '@shared/domain/entity'; import { Collection, Db } from 'mongodb'; -import { MigrateOptions } from '@mikro-orm/migrations-mongodb'; +import { MigrateOptions, UmzugMigration } from '@mikro-orm/migrations-mongodb'; @Injectable() export class DatabaseManagementService { @@ -81,6 +81,12 @@ export class DatabaseManagementService { await migrator.down(params); } + async migrationPending(): Promise { + const migrator = this.orm.getMigrator(); + const pendingMigrations = await migrator.getPendingMigrations(); + return pendingMigrations; + } + private migrationParams(only?: string, from?: string, to?: string) { const params: MigrateOptions = {}; if (only) { diff --git a/apps/server/src/modules/management/console/database-management.console.spec.ts b/apps/server/src/modules/management/console/database-management.console.spec.ts index bc0397e5820..5e08af4edd5 100644 --- a/apps/server/src/modules/management/console/database-management.console.spec.ts +++ b/apps/server/src/modules/management/console/database-management.console.spec.ts @@ -105,6 +105,11 @@ describe('DatabaseManagementConsole', () => { expect(consoleInfoSpy).toHaveBeenCalledWith('migration down is completed'); expect(databaseManagementUc.migrationDown).toHaveBeenCalled(); }); + it('should check pending migrations', async () => { + await service.migration({ pending: true }); + expect(consoleInfoSpy).toHaveBeenCalledWith(expect.stringContaining('Pending:')); + expect(databaseManagementUc.migrationPending).toHaveBeenCalled(); + }); it('should no migrate if no param specified', async () => { await service.migration({}); expect(consoleErrorSpy).toHaveBeenCalledWith('no migration option was given'); diff --git a/apps/server/src/modules/management/console/database-management.console.ts b/apps/server/src/modules/management/console/database-management.console.ts index 383f8461a3c..1b14fb37bd5 100644 --- a/apps/server/src/modules/management/console/database-management.console.ts +++ b/apps/server/src/modules/management/console/database-management.console.ts @@ -14,6 +14,7 @@ interface MigrationOptions { from?: string; to?: string; only?: string; + pending?: boolean; } @Console({ command: 'database', description: 'database setup console' }) @@ -112,12 +113,17 @@ export class DatabaseManagementConsole { required: false, description: 'run a single migration', }, + { + flags: '--pending', + required: false, + description: 'list pending migrations', + }, ], description: 'Execute MikroOrm migration up/down', }) async migration(migrationOptions: MigrationOptions): Promise { let report = 'no migration option was given'; - if (!migrationOptions.up && !migrationOptions.down) { + if (!migrationOptions.up && !migrationOptions.down && !migrationOptions.pending) { this.consoleWriter.error(report); return report; } @@ -129,6 +135,10 @@ export class DatabaseManagementConsole { await this.databaseManagementUc.migrationDown(migrationOptions.from, migrationOptions.to, migrationOptions.only); report = 'migration down is completed'; } + if (migrationOptions.pending) { + const pendingMigrations = await this.databaseManagementUc.migrationPending(); + report = `Pending: ${JSON.stringify(pendingMigrations.map((migration) => migration.name))}`; + } this.consoleWriter.info(report); return report; diff --git a/apps/server/src/modules/management/uc/database-management.uc.spec.ts b/apps/server/src/modules/management/uc/database-management.uc.spec.ts index 876569d4d4a..57f73baece2 100644 --- a/apps/server/src/modules/management/uc/database-management.uc.spec.ts +++ b/apps/server/src/modules/management/uc/database-management.uc.spec.ts @@ -679,5 +679,10 @@ describe('DatabaseManagementService', () => { await uc.migrationDown('foo', 'bar', 'baz'); expect(dbService.migrationDown).toHaveBeenCalledWith('foo', 'bar', 'baz'); }); + it('should call migrationPending', async () => { + dbService.migrationDown = jest.fn(); + await uc.migrationPending(); + expect(dbService.migrationPending).toHaveBeenCalled(); + }); }); }); diff --git a/apps/server/src/modules/management/uc/database-management.uc.ts b/apps/server/src/modules/management/uc/database-management.uc.ts index 10cf3e722ec..8ec0dfcb436 100644 --- a/apps/server/src/modules/management/uc/database-management.uc.ts +++ b/apps/server/src/modules/management/uc/database-management.uc.ts @@ -8,6 +8,7 @@ import { ConfigService } from '@nestjs/config'; import { StorageProviderEntity, SystemEntity } from '@shared/domain/entity'; import { LegacyLogger } from '@src/core/logger'; import { orderBy } from 'lodash'; +import { UmzugMigration } from '@mikro-orm/migrations-mongodb'; import { BsonConverter } from '../converter/bson.converter'; import { generateSeedData } from '../seed-data/generateSeedData'; @@ -412,4 +413,8 @@ export class DatabaseManagementUc { public async migrationDown(from?: string, to?: string, only?: string): Promise { return this.databaseManagementService.migrationDown(from, to, only); } + + public async migrationPending(): Promise { + return this.databaseManagementService.migrationPending(); + } } diff --git a/package.json b/package.json index bcbea72be85..e6e66cfdc3a 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "mocha-metrics": "cross-env NODE_ENV=test mocha \"test/routes/*.metrics.js\" --exclude \"{test,src}/**/*.test.{js,ts}\" --no-timeout --exit", "migration:up": "npm run nest:start:console -- database migration --up", "migration:down": "npm run nest:start:console -- database migration --down", + "migration:pending": "npm run nest:start:console -- database migration --pending", "migration:persisted": "npm run nest:start:console -- database export --collection migrations --override", "nest:prebuild": "rimraf dist", "nest:build": "nest build",