feat: add dry-run option to sync-metadata command (#3758)

* feat: add dry-run option to sync-metadata command

* feat: save metadata logs in dry-run mode
This commit is contained in:
Jérémy M
2024-02-01 16:35:32 +01:00
committed by GitHub
parent cdc51add7d
commit 3c89a97a9f
7 changed files with 131 additions and 17 deletions

4
.gitignore vendored
View File

@@ -17,4 +17,6 @@
!.yarn/sdks
!.yarn/versions
coverage
.vercel
.vercel
**/**/logs/**

View File

@@ -6,6 +6,7 @@ import { WorkspaceSyncMetadataService } from 'src/workspace/workspace-sync-metad
// TODO: implement dry-run
interface RunWorkspaceMigrationsOptions {
workspaceId: string;
dryRun?: boolean;
}
@Command({
@@ -35,6 +36,7 @@ export class SyncWorkspaceMetadataCommand extends CommandRunner {
workspaceId: options.workspaceId,
dataSourceId: dataSourceMetadata.id,
},
{ dryRun: options.dryRun },
);
}
@@ -46,4 +48,13 @@ export class SyncWorkspaceMetadataCommand extends CommandRunner {
parseWorkspaceId(value: string): string {
return value;
}
@Option({
flags: '-d, --dry-run',
description: 'Dry run without applying changes',
required: false,
})
dryRun(): boolean {
return true;
}
}

View File

@@ -0,0 +1,70 @@
import { Injectable } from '@nestjs/common';
import fs from 'fs/promises';
import { WorkspaceSyncStorage } from 'src/workspace/workspace-sync-metadata/storage/workspace-sync.storage';
import { WorkspaceMigrationEntity } from 'src/metadata/workspace-migration/workspace-migration.entity';
@Injectable()
export class WorkspaceLogsService {
constructor() {}
async saveLogs(
storage: WorkspaceSyncStorage,
workspaceMigrations: WorkspaceMigrationEntity[],
) {
// Save workspace migrations
await fs.writeFile(
'./logs/workspace-migrations.json',
JSON.stringify(workspaceMigrations, null, 2),
);
// Save object metadata create collection
await fs.writeFile(
'./logs/object-metadata-create-collection.json',
JSON.stringify(storage.objectMetadataCreateCollection, null, 2),
);
// Save object metadata update collection
await fs.writeFile(
'./logs/object-metadata-update-collection.json',
JSON.stringify(storage.objectMetadataUpdateCollection, null, 2),
);
// Save object metadata delete collection
await fs.writeFile(
'./logs/object-metadata-delete-collection.json',
JSON.stringify(storage.objectMetadataDeleteCollection, null, 2),
);
// Save field metadata create collection
await fs.writeFile(
'./logs/field-metadata-create-collection.json',
JSON.stringify(storage.fieldMetadataCreateCollection, null, 2),
);
// Save field metadata update collection
await fs.writeFile(
'./logs/field-metadata-update-collection.json',
JSON.stringify(storage.fieldMetadataUpdateCollection, null, 2),
);
// Save field metadata delete collection
await fs.writeFile(
'./logs/field-metadata-delete-collection.json',
JSON.stringify(storage.fieldMetadataDeleteCollection, null, 2),
);
// Save relation metadata create collection
await fs.writeFile(
'./logs/relation-metadata-create-collection.json',
JSON.stringify(storage.relationMetadataCreateCollection, null, 2),
);
// Save relation metadata delete collection
await fs.writeFile(
'./logs/relation-metadata-delete-collection.json',
JSON.stringify(storage.relationMetadataDeleteCollection, null, 2),
);
}
}

View File

@@ -33,7 +33,7 @@ export class WorkspaceSyncObjectMetadataService {
manager: EntityManager,
storage: WorkspaceSyncStorage,
workspaceFeatureFlagsMap: FeatureFlagMap,
): Promise<void> {
): Promise<WorkspaceMigrationEntity[]> {
const objectMetadataRepository =
manager.getRepository(ObjectMetadataEntity);
const workspaceMigrationRepository = manager.getRepository(
@@ -153,6 +153,10 @@ export class WorkspaceSyncObjectMetadataService {
this.logger.log('Saving migrations');
// Save migrations into DB
await workspaceMigrationRepository.save(workspaceObjectMigrations);
const workspaceMigrations = await workspaceMigrationRepository.save(
workspaceObjectMigrations,
);
return workspaceMigrations;
}
}

View File

@@ -34,7 +34,7 @@ export class WorkspaceSyncRelationMetadataService {
manager: EntityManager,
storage: WorkspaceSyncStorage,
workspaceFeatureFlagsMap: FeatureFlagMap,
): Promise<void> {
): Promise<WorkspaceMigrationEntity[]> {
const objectMetadataRepository =
manager.getRepository(ObjectMetadataEntity);
const workspaceMigrationRepository = manager.getRepository(
@@ -106,6 +106,10 @@ export class WorkspaceSyncRelationMetadataService {
);
// Save migrations into DB
await workspaceMigrationRepository.save(workspaceRelationMigrations);
const workspaceMigrations = await workspaceMigrationRepository.save(
workspaceRelationMigrations,
);
return workspaceMigrations;
}
}

View File

@@ -14,6 +14,7 @@ import { workspaceSyncMetadataComparators } from 'src/workspace/workspace-sync-m
import { WorkspaceMetadataUpdaterService } from 'src/workspace/workspace-sync-metadata/services/workspace-metadata-updater.service';
import { WorkspaceSyncObjectMetadataService } from 'src/workspace/workspace-sync-metadata/services/workspace-sync-object-metadata.service';
import { WorkspaceSyncRelationMetadataService } from 'src/workspace/workspace-sync-metadata/services/workspace-sync-relation-metadata.service';
import { WorkspaceLogsService } from 'src/workspace/workspace-sync-metadata/services/workspace-logs.service';
@Module({
imports: [
@@ -37,6 +38,7 @@ import { WorkspaceSyncRelationMetadataService } from 'src/workspace/workspace-sy
WorkspaceSyncObjectMetadataService,
WorkspaceSyncRelationMetadataService,
WorkspaceSyncMetadataService,
WorkspaceLogsService,
],
exports: [WorkspaceSyncMetadataService],
})

View File

@@ -10,6 +10,7 @@ import { FeatureFlagFactory } from 'src/workspace/workspace-sync-metadata/factor
import { WorkspaceSyncObjectMetadataService } from 'src/workspace/workspace-sync-metadata/services/workspace-sync-object-metadata.service';
import { WorkspaceSyncRelationMetadataService } from 'src/workspace/workspace-sync-metadata/services/workspace-sync-relation-metadata.service';
import { WorkspaceSyncStorage } from 'src/workspace/workspace-sync-metadata/storage/workspace-sync.storage';
import { WorkspaceLogsService } from 'src/workspace/workspace-sync-metadata/services/workspace-logs.service';
@Injectable()
export class WorkspaceSyncMetadataService {
@@ -22,6 +23,7 @@ export class WorkspaceSyncMetadataService {
private readonly workspaceMigrationRunnerService: WorkspaceMigrationRunnerService,
private readonly workspaceSyncObjectMetadataService: WorkspaceSyncObjectMetadataService,
private readonly workspaceSyncRelationMetadataService: WorkspaceSyncRelationMetadataService,
private readonly workspaceLogsService: WorkspaceLogsService,
) {}
/**
@@ -34,6 +36,7 @@ export class WorkspaceSyncMetadataService {
*/
public async syncStandardObjectsAndFieldsMetadata(
context: WorkspaceSyncContext,
options?: { dryRun?: boolean },
) {
this.logger.log('Syncing standard objects and fields metadata');
const queryRunner = this.metadataDataSource.createQueryRunner();
@@ -52,19 +55,37 @@ export class WorkspaceSyncMetadataService {
this.logger.log('Syncing standard objects and fields metadata');
await this.workspaceSyncObjectMetadataService.synchronize(
context,
manager,
storage,
workspaceFeatureFlagsMap,
);
const workspaceObjectMigrations =
await this.workspaceSyncObjectMetadataService.synchronize(
context,
manager,
storage,
workspaceFeatureFlagsMap,
);
await this.workspaceSyncRelationMetadataService.synchronize(
context,
manager,
storage,
workspaceFeatureFlagsMap,
);
const workspaceRelationMigrations =
await this.workspaceSyncRelationMetadataService.synchronize(
context,
manager,
storage,
workspaceFeatureFlagsMap,
);
// If we're running a dry run, rollback the transaction and do not execute migrations
if (options?.dryRun) {
const workspaceMigrations = [
...workspaceObjectMigrations,
...workspaceRelationMigrations,
];
this.logger.log('Running in dry run mode, rolling back transaction');
await queryRunner.rollbackTransaction();
await this.workspaceLogsService.saveLogs(storage, workspaceMigrations);
return;
}
await queryRunner.commitTransaction();