feat(planner): add bridge target version strategy for auto-stamping ledger to app versions
This commit is contained in:
@@ -23,6 +23,7 @@ const DEFAULT_LOCK_WAIT_MS = 60_000;
|
||||
const DEFAULT_LOCK_TTL_MS = 600_000;
|
||||
const LOCK_POLL_INTERVAL_MS = 500;
|
||||
const MIN_LOCK_HEARTBEAT_MS = 1;
|
||||
const AUTO_BRIDGE_STEP_ID_PREFIX = 'smartmigration-auto-bridge-to';
|
||||
|
||||
interface IResolvedLedgerState {
|
||||
currentVersionBefore: string | null;
|
||||
@@ -120,6 +121,18 @@ export class SmartMigration {
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
options.targetVersionStrategy !== undefined &&
|
||||
options.targetVersionStrategy !== 'strict' &&
|
||||
options.targetVersionStrategy !== 'bridge'
|
||||
) {
|
||||
throw new SmartMigrationError(
|
||||
'INVALID_TARGET_VERSION_STRATEGY',
|
||||
'targetVersionStrategy must be "strict" or "bridge" when provided.',
|
||||
{ targetVersionStrategy: options.targetVersionStrategy },
|
||||
);
|
||||
}
|
||||
|
||||
this.settings = {
|
||||
targetVersion: options.targetVersion,
|
||||
db: options.db,
|
||||
@@ -130,6 +143,7 @@ export class SmartMigration {
|
||||
lockWaitMs: options.lockWaitMs ?? DEFAULT_LOCK_WAIT_MS,
|
||||
lockTtlMs: options.lockTtlMs ?? DEFAULT_LOCK_TTL_MS,
|
||||
dryRun: options.dryRun ?? false,
|
||||
targetVersionStrategy: options.targetVersionStrategy ?? 'strict',
|
||||
logger: options.logger,
|
||||
};
|
||||
|
||||
@@ -443,13 +457,14 @@ export class SmartMigration {
|
||||
effectiveCurrentVersion = data.currentVersion;
|
||||
}
|
||||
|
||||
const planningSteps = this.getPlanningSteps(effectiveCurrentVersion);
|
||||
const plannedSteps = VersionResolver.equals(
|
||||
effectiveCurrentVersion,
|
||||
this.settings.targetVersion,
|
||||
)
|
||||
? []
|
||||
: VersionResolver.computePlan(
|
||||
this.steps,
|
||||
planningSteps,
|
||||
effectiveCurrentVersion,
|
||||
this.settings.targetVersion,
|
||||
);
|
||||
@@ -468,6 +483,41 @@ export class SmartMigration {
|
||||
};
|
||||
}
|
||||
|
||||
private getPlanningSteps(effectiveCurrentVersion: string): IMigrationStepDefinition[] {
|
||||
if (this.settings.targetVersionStrategy === 'strict') {
|
||||
return this.steps;
|
||||
}
|
||||
|
||||
const targetVersion = this.settings.targetVersion;
|
||||
if (this.steps.length === 0) {
|
||||
return VersionResolver.lessThan(effectiveCurrentVersion, targetVersion)
|
||||
? [this.createAutoBridgeStep(effectiveCurrentVersion, targetVersion)]
|
||||
: [];
|
||||
}
|
||||
|
||||
const lastStep = this.steps[this.steps.length - 1];
|
||||
if (!VersionResolver.lessThan(lastStep.toVersion, targetVersion)) {
|
||||
return this.steps;
|
||||
}
|
||||
|
||||
return [
|
||||
...this.steps,
|
||||
this.createAutoBridgeStep(lastStep.toVersion, targetVersion),
|
||||
];
|
||||
}
|
||||
|
||||
private createAutoBridgeStep(fromVersion: string, toVersion: string): IMigrationStepDefinition {
|
||||
return {
|
||||
id: `${AUTO_BRIDGE_STEP_ID_PREFIX}-${toVersion}`,
|
||||
fromVersion,
|
||||
toVersion,
|
||||
description: `Auto bridge migration ledger to target version ${toVersion}`,
|
||||
isResumable: false,
|
||||
isVirtual: true,
|
||||
handler: async () => {},
|
||||
};
|
||||
}
|
||||
|
||||
private async ensureLedger(): Promise<Ledger> {
|
||||
if (this.ledger) return this.ledger;
|
||||
const ledgerName = this.settings.ledgerName;
|
||||
|
||||
Reference in New Issue
Block a user