Fix upgrade commands discovery outside of cli (#19671)
# Introduction We were allowing the sequence to be empty in the worker context that was facing an edge case importing the UpgradeModule through the WorkspaceModule god module, no commands were discovered and it was throwing as the sequence must have at least one workspace commands to allow a workspace creation Though the issue was also applicable to the twenty-server `AppModule` too that was not discovering any commands ## Integration tests were passing The integration test were importing the `CommandModule` at the nest testing app creating leading to asymmetric testing context It was a requirement for a legacy commands import and global assignation ## Fix The `UpgradeModule` now import both `WorkspaceCommandsProviderModule` and `InstanceCommandProviderModule` which ships the commands directly in the module We could consider moving the commands into the `engine/upgrade` folder ## Concern Bootstrap could become more and more long to load at both server and worker start When this becomes a problem we will have to only import the latest workspace command or whatever For the moment this is not worth it the risk to import not the latest workspace command
This commit is contained in:
+7
-17
@@ -157,24 +157,14 @@ describe('UpgradeCommandRegistryService', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should return empty array for version with no commands', async () => {
|
||||
const service = await buildRegistryService([]);
|
||||
|
||||
const bundleB = service.getBundleForVersion(VERSION_B);
|
||||
const bundleA = service.getBundleForVersion(VERSION_A);
|
||||
|
||||
expect(bundleB.fastInstanceCommands).toStrictEqual([]);
|
||||
expect(bundleA.fastInstanceCommands).toStrictEqual([]);
|
||||
expect(bundleB.workspaceCommands).toStrictEqual([]);
|
||||
expect(bundleA.workspaceCommands).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it('should not throw when no commands are discovered (empty bundle)', async () => {
|
||||
await expect(buildRegistryService([])).resolves.toBeDefined();
|
||||
it('should throw when no workspace commands are discovered', async () => {
|
||||
await expect(buildRegistryService([])).rejects.toThrow(
|
||||
'Upgrade sequence must contain at least one workspace command',
|
||||
);
|
||||
});
|
||||
|
||||
it('should return empty array for unsupported version', async () => {
|
||||
const service = await buildRegistryService([]);
|
||||
const service = await buildRegistryService([new WorkspaceCommandA()]);
|
||||
|
||||
expect(
|
||||
service.getBundleForVersion('99.0.0' as typeof VERSION_A)
|
||||
@@ -284,8 +274,8 @@ describe('UpgradeCommandRegistryService', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should return empty array from getCrossUpgradeSupportedFastInstanceCommands when no commands registered', async () => {
|
||||
const service = await buildRegistryService([]);
|
||||
it('should return empty array from getCrossUpgradeSupportedFastInstanceCommands when no instance commands registered', async () => {
|
||||
const service = await buildRegistryService([new WorkspaceCommandA()]);
|
||||
|
||||
expect(
|
||||
service.getCrossUpgradeSupportedFastInstanceCommands(),
|
||||
|
||||
-17
@@ -247,33 +247,16 @@ export class UpgradeCommandRegistryService implements OnModuleInit {
|
||||
}
|
||||
|
||||
private validateAtLeastOneVersionBundleHasWorkspaceCommands(): void {
|
||||
let totalCommandCount = 0;
|
||||
let hasWorkspaceCommands = false;
|
||||
|
||||
for (const version of TWENTY_CROSS_UPGRADE_SUPPORTED_VERSIONS) {
|
||||
const bundle = this.getBundleForVersion(version);
|
||||
|
||||
totalCommandCount +=
|
||||
bundle.fastInstanceCommands.length +
|
||||
bundle.slowInstanceCommands.length +
|
||||
bundle.workspaceCommands.length;
|
||||
|
||||
if (bundle.workspaceCommands.length > 0) {
|
||||
hasWorkspaceCommands = true;
|
||||
}
|
||||
}
|
||||
|
||||
// UpgradeModule is loaded in the worker transitively via WorkspaceModule,
|
||||
// but no command modules are imported — zero providers are discovered.
|
||||
// TODO: split WorkspaceModule so the worker doesn't pull in UpgradeModule
|
||||
if (totalCommandCount === 0) {
|
||||
this.logger.warn(
|
||||
'No upgrade commands discovered — skipping workspace command validation',
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasWorkspaceCommands) {
|
||||
throw new Error(
|
||||
'Upgrade sequence must contain at least one workspace command',
|
||||
|
||||
@@ -3,6 +3,8 @@ import { DiscoveryModule } from '@nestjs/core';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { WorkspaceIteratorModule } from 'src/database/commands/command-runners/workspace-iterator.module';
|
||||
import { InstanceCommandProviderModule } from 'src/database/commands/upgrade-version-command/instance-command-provider.module';
|
||||
import { WorkspaceCommandProviderModule } from 'src/database/commands/upgrade-version-command/workspace-command-provider.module';
|
||||
import { InstanceCommandRunnerService } from 'src/engine/core-modules/upgrade/services/instance-command-runner.service';
|
||||
import { UpgradeCommandRegistryService } from 'src/engine/core-modules/upgrade/services/upgrade-command-registry.service';
|
||||
import { UpgradeMigrationService } from 'src/engine/core-modules/upgrade/services/upgrade-migration.service';
|
||||
@@ -16,6 +18,8 @@ import { WorkspaceVersionModule } from 'src/engine/workspace-manager/workspace-v
|
||||
@Module({
|
||||
imports: [
|
||||
DiscoveryModule,
|
||||
InstanceCommandProviderModule,
|
||||
WorkspaceCommandProviderModule,
|
||||
WorkspaceIteratorModule,
|
||||
WorkspaceVersionModule,
|
||||
TypeOrmModule.forFeature([UpgradeMigrationEntity, WorkspaceEntity]),
|
||||
|
||||
Reference in New Issue
Block a user