Releases: migration-script-runner/msr-core
Release list
v0.8.4 - TConfig Generic Support in CLI
π― TConfig Generic Support in CLI
Minor release adding TConfig generic parameter to createCLI for type-safe custom configuration types.
β¨ New Feature
#152: TConfig Generic Parameter in createCLI
Added third generic parameter TConfig extends Config = Config to CLIOptions and createCLI for full type safety with custom configuration types.
Problem Solved:
Firebase adapter team identified that createCLI lacked custom config type support. The extendFlags and createExecutor callbacks received base Config type, forcing type casts to access custom properties like databaseUrl and applicationCredentials.
Solution:
// Before v0.8.4 (required casting)
const program = createCLI({
extendFlags: (config, flags) => {
(config as FirebaseConfig).databaseUrl = flags.databaseUrl; // β
}
});
// After v0.8.4 (fully typed)
const program = createCLI<IFirebaseDB, FirebaseAdapter, FirebaseConfig>({
extendFlags: (config, flags) => {
config.databaseUrl = flags.databaseUrl; // β
Full type safety!
}
});Benefits:
- β
No type casting needed in
extendFlagsandcreateExecutor - β Full IntelliSense for custom config properties
- β
Consistent with
THandler(#138) and executorTConfig(#144) - β
Fully backward compatible with default
TConfig = Config
π Quality Metrics
- Tests: 1572 passing (+4 new tests)
- Coverage: 100% maintained (2815/1450/581/2713)
- Build: TypeScript compiles without errors
- Backward Compatibility: β No breaking changes
π Documentation
Updated docs/guides/cli-adapter-development.md with:
- Complete Firebase example using TConfig generic
- Before/after comparison highlighting type safety improvements
- Integration with
addCustomOptionsandextendFlags(v0.8.3)
π Related
- #138: THandler generic for type-safe handler access (v0.8.0)
- #144: TConfig generic in executor interfaces (v0.8.2)
- #151: addCustomOptions/extendFlags callbacks (v0.8.3)
This release completes the type safety story from v0.8.0 through v0.8.4.
π¦ Installation
npm install @migration-script-runner/core@0.8.4π Usage Example
interface FirebaseConfig extends Config {
databaseUrl: string;
applicationCredentials: string;
connectionTimeout?: number;
}
const program = createCLI<IFirebaseDB, FirebaseAdapter, FirebaseConfig>({
name: 'msr-firebase',
addCustomOptions: (program) => {
program
.option('--database-url <url>', 'Firebase Database URL')
.option('--credentials <path>', 'Service account key');
},
extendFlags: (config, flags) => {
// β
config is typed as FirebaseConfig!
config.databaseUrl = flags.databaseUrl as string;
config.applicationCredentials = flags.credentials as string;
},
createExecutor: async (config) => {
// β
config.databaseUrl has full IntelliSense!
return FirebaseAdapter.getInstance({ config });
}
});π Migration Guide
No migration required - fully backward compatible.
Existing code without the third generic parameter continues to work:
// Still works - defaults to base Config type
createCLI({ createExecutor: (config) => ... });To adopt type safety for custom configs, add the third generic:
// Enhanced with type safety
createCLI<IDB, Adapter, CustomConfig>({ ... });v0.8.3 - Adapter-Specific CLI Flags
π What's New
Adapter-Specific CLI Flags (#151)
Adapters can now add their own database-specific command-line flags that integrate seamlessly with MSR's configuration system.
New Callbacks:
addCustomOptions(program)- Register custom CLI flags during setupextendFlags(config, flags)- Map flag values to config at execution
Benefits:
- β Single-command execution without environment variables
- β Highest priority in config waterfall
- β Perfect for CI/CD pipelines
- β
Appears in
--helpoutput automatically - β Fully backward compatible (callbacks optional)
π¦ Example Usage
Firebase Adapter
const program = createCLI({
name: 'msr-firebase',
addCustomOptions: (program) => {
program
.option('--database-url <url>', 'Firebase Database URL')
.option('--credentials <path>', 'Service account key');
},
extendFlags: (config, flags) => {
if (flags.databaseUrl) config.databaseUrl = flags.databaseUrl;
if (flags.credentials) config.credentials = flags.credentials;
},
createExecutor: async (config) => FirebaseAdapter.getInstance({ config })
});CLI Usage:
npx msr-firebase migrate \
--database-url https://my-project.firebaseio.com \
--credentials ./serviceAccountKey.jsonMongoDB Adapter
npx msr-mongodb migrate \
--mongo-uri mongodb://localhost:27017/mydb \
--auth-source admin \
--sslπ Quality Metrics
- Tests: 1568 passing (+8 new tests)
- Coverage: 100% maintained (2815/1450/581/2713)
- Documentation: 120+ lines with Firebase & MongoDB examples
- Build: TypeScript compiles without errors
π Config Waterfall Priority
Custom CLI flags have the highest priority:
- Built-in defaults (lowest)
- Config file (if
--config-fileprovided) - Environment variables (MSR_*)
options.config(if provided)- Standard CLI flags (
--folder,--table-name, etc.) - Custom CLI flags via extendFlags (highest)
π Documentation
See the complete guide in CLI Adapter Development
π§ Installation
npm install @migration-script-runner/core@0.8.3β¬οΈ Migration from v0.8.2
No breaking changes. Existing adapters continue to work without modification.
To opt-in:
- Add
addCustomOptionscallback to register your custom flags - Add
extendFlagscallback to map flag values to config - Update your adapter's config type if needed
π― Use Cases
Perfect for:
- Database Connections: URLs, hosts, ports, credentials
- Authentication: Service account keys, tokens, API keys
- Performance: Connection pools, timeouts, retry settings
- Feature Flags: Enable/disable specific functionality
- CI/CD Pipelines: Single-command execution without env setup
v0.8.2 - Developer Experience Improvements
MSR Core v0.8.2 - Developer Experience Improvements
Release Date: December 20, 2025
π― Overview
MSR Core v0.8.2 focuses on developer experience improvements for adapter development, making it easier and faster to create database adapters with better type safety, reduced boilerplate, and clearer error messages.
β¨ What's New
#144: Generic Config Type Support
Added TConfig generic parameter enabling full type safety for database-specific configuration properties.
// Before v0.8.2: Required wrapper interfaces
interface IFirebaseOptions extends IExecutorOptions<IDB> {
config: FirebaseConfig; // Override base Config
}
// v0.8.2: Native generic support
interface IFirebaseOptions extends IExecutorOptions<IDB, FirebaseConfig> {
// config is automatically typed as FirebaseConfig!
}Benefits:
- β Type-safe custom config properties
- β Zero type assertions needed
- β Fully backward compatible
#145: Async Executor Support in CLI
CLI now supports Promise<Executor> return type from createExecutor.
// v0.8.2: Async executor creation
const program = createCLI({
createExecutor: async (config) => {
return MyAdapter.getInstance({ config }); // β
Async!
}
});Benefits:
- β Async database connections supported
- β No more unsafe type casts
- β Fully backward compatible
#146: Better Documentation and Error Messages
Enhanced API documentation and runtime validation with helpful error messages.
Improvements:
- π PUBLIC/INTERNAL API markers in JSDoc
- π Comprehensive troubleshooting guide (185 lines)
- β Helpful runtime errors with solutions
- π Interface comparison tables
Error Example:
TypeError: Handler is required in IMigrationExecutorDependencies.
Common causes:
1. Using IExecutorOptions in constructor instead of IMigrationExecutorDependencies
2. Forgetting to create handler before passing to super()
Solutions:
β’ For async initialization: Use a factory method pattern:
static async getInstance(options: IExecutorOptions<DB>): Promise<MyExecutor> {
const handler = await MyHandler.connect(options.config);
return new MyExecutor({ handler, ...options });
}
#147: createInstance Factory Pattern
Added standardized factory method for async adapter initialization.
// Before v0.8.2: Manual pattern (~10 lines)
static async getInstance(options: IOptions): Promise<MyAdapter> {
const handler = await MyHandler.getInstance(options.config);
return new MyAdapter({ handler, ...options });
}
// v0.8.2: createInstance helper (3 lines)
static async getInstance(options: IOptions): Promise<MyAdapter> {
return MigrationScriptExecutor.createInstance(
MyAdapter, options, (config) => MyHandler.getInstance(config)
);
}Benefits:
- β Standardized pattern across ecosystem
- β Reduces boilerplate by 70%
- β Type-safe with full generic support
- β Documentation now async-first (9/10 adapters are async)
π Key Metrics
- Tests: 1560 passing (+11 from v0.8.1)
- Coverage: 100% on all metrics (2811/1448/581/2709)
- Breaking Changes: None (fully backward compatible)
- Documentation: 4 major files updated
π Documentation Updates
Major Updates:
- getting-started.md: Restructured to show async pattern first
- cli-adapter-development.md: New Quick Start, Complete Example, Troubleshooting section (185 lines)
- api/core-classes.md: Added createInstance() documentation
- design-patterns.md: Added async adapter factory pattern section
New Sections:
- Troubleshooting guide with 6 common issues
- IExecutorOptions vs IMigrationExecutorDependencies comparison
- Async adapter initialization guide (210 lines)
- Custom config types guide (247 lines, added in v0.8.1)
π§ Migration Guide
No breaking changes. All changes are backward compatible.
Recommended Updates:
- Use
createInstancefor async adapters:
static async getInstance(options: IOptions): Promise<MyAdapter> {
return MigrationScriptExecutor.createInstance(
MyAdapter, options, async (config) => MyHandler.connect(config)
);
}- Add generic config type:
// Define custom config
class AppConfig extends Config {
databaseUrl?: string;
}
// Use TConfig generic
class MyAdapter extends MigrationScriptExecutor<IDB, MyHandler, AppConfig> {
// this.config is now typed as AppConfig!
}- Update CLI for async:
const program = createCLI({
createExecutor: async (config) => MyAdapter.getInstance({ config })
});π Installation
npm install @migration-script-runner/core@0.8.2π Full Changelog
Features
- #144: Generic config type support with
TConfigparameter - #145: CLI async executor support with
Promise<Executor> - #146: Enhanced documentation with PUBLIC/INTERNAL markers
- #147:
createInstancefactory pattern for async adapters
Documentation
- Added comprehensive troubleshooting guide
- Restructured to show async-first approach
- Added interface comparison tables
- Enhanced JSDoc with clear examples
Tests
- Added 11 new tests (runtime validation, async patterns)
- Maintained 100% coverage on all metrics
π Related Releases
- v0.8.1: Locking lifecycle, LockingOrchestrator, getHandler()
- v0.8.0: Locking mechanism, THandler generic, down migration fixes
π― Next Steps
- v1.0.0 (planned): Make MigrationScriptExecutor abstract class (#150)
- Focus on ecosystem growth with improved adapter DX
π₯ Contributors
Full Milestone: https://github.com/migration-script-runner/msr-core/milestone/14
v0.8.1 - Locking Enhancements
Migration Script Runner v0.8.1
Release Date: December 19, 2025
Minor enhancements and improvements to v0.8.0 locking features, including a breaking change for ILockingService implementations.
π What's New
Handler Access API (#142)
Added getHandler() public method to MigrationScriptExecutor for direct handler access.
Benefits:
- Direct handler access for CLI custom commands
- Removes adapter-specific workarounds (e.g.,
FirebaseRunner.getHandler()) - Full type safety through
THandlergeneric parameter - Simplifies CLI development for database-specific operations
Example:
// CLI custom command
const handler = executor.getHandler();
console.log('Handler version:', handler.getVersion());
// Type-safe access with THandler generic
class MyAdapter extends MigrationScriptExecutor<IDB, PostgresHandler> {
getConnectionInfo() {
return this.getHandler().pool.idleCount; // Fully typed\!
}
}Locking Service Lifecycle (#140) β οΈ BREAKING CHANGE
Added required initialization methods to ILockingService interface for explicit lifecycle management.
New Required Methods:
interface ILockingService<DB extends IDB> {
// Existing methods...
// NEW in v0.8.1 - REQUIRED
initLockStorage(): Promise<void>;
ensureLockStorageAccessible(): Promise<boolean>;
}Benefits:
- β Fail-fast: Setup errors occur at initialization, not first lock acquisition
- β Explicit lifecycle: Clear when lock storage is created
- β Pre-flight validation: Detect configuration/permission issues early
- β Improved testability: Setup tested separately from lock operations
Implementation Example:
// PostgreSQL
async initLockStorage() {
await this.db.query(`
CREATE TABLE IF NOT EXISTS migration_locks (
executor_id VARCHAR(255) PRIMARY KEY,
locked_at TIMESTAMP NOT NULL,
expires_at TIMESTAMP NOT NULL
)
`);
}
async ensureLockStorageAccessible() {
try {
await this.db.query('SELECT 1');
return true;
} catch {
return false;
}
}Lock Orchestration Service (#141)
Added LockingOrchestrator service using decorator pattern for centralized lock management.
What Was Added:
- LockingOrchestrator Service: Wraps
ILockingServiceimplementations - ILockingHooks Interface: 9 optional hook methods for observability
- Integration: Seamless integration into
MigrationWorkflowOrchestrator
Features:
- Retry logic with configurable attempts/delays
- Two-phase locking (acquire β verify ownership)
- Lifecycle hooks for metrics, alerts, and audit logging
- Comprehensive error handling with context preservation
Hook Methods:
interface ILockingHooks {
onBeforeAcquireLock?(executorId: string, timeout: number): Promise<void>;
onLockAcquired?(executorId: string, status: ILockStatus): Promise<void>;
onLockAcquisitionFailed?(executorId: string, currentOwner: string): Promise<void>;
onAcquireRetry?(executorId: string, attempt: number, currentOwner: string): Promise<void>;
onOwnershipVerificationFailed?(executorId: string): Promise<void>;
onBeforeReleaseLock?(executorId: string): Promise<void>;
onLockReleased?(executorId: string): Promise<void>;
onForceReleaseLock?(status: ILockStatus | null): Promise<void>;
onLockError?(operation: string, error: Error, executorId?: string): Promise<void>;
}Benefits:
- Consistent lock orchestration across all database adapters
- Centralized observability through hooks
- Adapters stay focused on database-specific operations only
π Statistics
- Issues Closed: 3 (#140, #141, #142)
- Tests Added: 45 new unit/integration tests
- Total Tests: 1547 passing (up from 1497 in v0.8.0)
- Coverage: 100% on all metrics (statements, branches, functions, lines)
- Breaking Changes: 1 (#140 - required methods in ILockingService)
β οΈ Breaking Changes
ILockingService Interface (#140)
All ILockingService implementations must now implement two required methods:
initLockStorage(): Promise<void>ensureLockStorageAccessible(): Promise<boolean>
Migration Steps:
- Add both methods to your
ILockingServiceimplementation - Call
initLockStorage()during handler initialization - Optionally call
ensureLockStorageAccessible()for pre-flight checks
Example Update:
class MyLockingService implements ILockingService<IDB> {
// Existing methods...
// ADD THESE:
async initLockStorage(): Promise<void> {
// Create lock storage structures (tables, indexes, paths)
}
async ensureLockStorageAccessible(): Promise<boolean> {
// Verify storage is accessible
return true;
}
}π¦ Installation
npm install @migration-script-runner/core@0.8.1π Links
π Acknowledgments
Special thanks to the Firebase adapter (#67) for identifying the need for lifecycle management methods in the locking interface.
v0.8.0 - Production-Ready Locking & Enhanced Type Safety
π What's New in v0.8.0
Production-ready release with migration locking, enhanced type safety, and critical bug fixes. 100% backwards compatible with v0.7.x - all features are opt-in.
β¨ Features
π Migration Locking (#85, #120)
Prevent concurrent migrations with database-level locking mechanism for multi-instance deployments.
Why you need it:
- Prevents race conditions in Kubernetes/Docker deployments
- Avoids corrupted migration state in CI/CD pipelines
- Essential for multi-instance production environments
Implementation:
import { ILockingService } from '@migration-script-runner/core';
class MyDatabaseLockingService implements ILockingService<MyDB> {
async acquireLock(executorId: string, timeout: number): Promise<boolean> {
// Database-specific lock acquisition
}
async verifyLockOwnership(executorId: string): Promise<boolean> {
// Two-phase verification prevents race conditions
}
async releaseLock(executorId: string): Promise<void> {
// Release lock after migration
}
// ... other methods
}
// Add to handler
handler.lockingService = new MyDatabaseLockingService(db);Configuration (optional):
config.locking.enabled = true; // Default when service provided
config.locking.timeout = 600_000; // 10 minutes
config.locking.retryAttempts = 0; // Fail-fast (recommended)
config.locking.retryDelay = 1000; // 1 second between retriesCLI Commands:
# Check lock status
msr lock:status
# Force-release stuck lock
msr lock:release --force
# Disable locking for single run
msr migrate --no-lockπ Locking Configuration Docs | Lock Commands Guide
π§ Handler Generic Type Parameter (#138)
Type-safe handler access in adapters with optional second generic parameter - eliminates casting workarounds!
BEFORE (v0.7.x):
class MyAdapter extends MigrationScriptExecutor<IDB> {
private getHandler(): MyHandler {
return this['handler'] as MyHandler; // β Casting required
}
getConnectionInfo() {
const handler = this.getHandler();
return handler.config.host; // No IDE autocomplete
}
}AFTER (v0.8.0):
class MyAdapter extends MigrationScriptExecutor<IDB, MyHandler> {
getConnectionInfo() {
// β
Type-safe access - no casting needed\!
return this.handler.config.host; // Full IDE autocomplete
}
}Benefits:
- β Full IDE autocomplete support
- β Compile-time type checking
- β No casting or workarounds needed
- β Cleaner, more maintainable adapter code
π Bug Fixes
Down Migration TypeError (#139)
Issue: Calling executor.down(targetVersion) threw TypeError: s.init is not a function.
Root Cause: Migration records from database lacked filepath property needed for loading script files.
Fix: Added matchMigratedWithScripts() helper to match database records with filesystem scripts before rollback.
Impact: Down migrations now work correctly. No code changes needed - fix is automatic.
π¦ npm Provenance (#133)
Enhanced supply chain security with build provenance attestations. Published packages now include verifiable build information.
npm publish --provenanceπ Backwards Compatibility
β 100% backwards compatible with v0.7.x
- All existing code works without modifications
- Locking is disabled by default (opt-in via
lockingService) - Handler generic type has sensible default (
IDatabaseMigrationHandler<DB>) - Bug fixes are transparent
- No deprecated features
Migration Time: 5-10 minutes (optional feature adoption)
π Migration Guide
π Stats
- 8 Issues Closed
- 1,497 Tests Passing (100% coverage maintained)
- Zero Breaking Changes
π Contributors
Thanks to everyone who contributed to this release!
π Documentation
- Migration Guide: v0.7.x β v0.8.0
- Locking Configuration
- Lock CLI Commands
- Production Deployment
- Full Documentation
π Upgrade Instructions
npm install @migration-script-runner/core@^0.8.0Or with yarn:
yarn upgrade @migration-script-runner/core@^0.8.0That's it! Everything continues to work. Enable locking when ready for production.
Full Changelog: v0.7.3...v0.8.0
v0.7.4: Automated npm Publishing
π Automated npm Publishing (#133)
Implemented tag-based automated npm publishing workflow with cryptographic provenance.
What's Changed
New Publishing Workflow:
- β
Tag-based publishing: Push git tag (e.g.,
v0.8.0) to automatically trigger npm publish - β Provenance signing: Packages are cryptographically signed with GitHub Actions build information
- β
Automated workflow:
.github/workflows/npm-publish.ymlhandles build, test, and publish - β Security: Uses npm granular access tokens with bypass 2FA for CI/CD
Workflow Features:
- Triggers on
v*tags or manual dispatch - Runs
prepublishOnlyhook automatically (build + test) - Publishes with provenance via
id-token: writepermission - Uses
NPM_TOKENsecret (granular access token, 90-day expiration)
Technical Changes:
- Updated workflow to Node 20
- Simplified workflow (removed version check job)
- Fixed
package.jsonrepository URL format (git+https://prefix)
Usage:
# Create and push tag
git tag v0.8.0
git push origin v0.8.0
# Workflow automatically publishes to npmFull Changelog: v0.7.0...v0.7.4
v0.7.0 - CLI Factory, .env Support, and Improved Architecture
π What's New in v0.7.0
Enhanced architecture, adapter extensibility, and CLI factory for production-ready migration tooling.
β¨ New Features
π₯οΈ CLI Factory (#59)
- Create command-line interfaces with built-in commands (migrate, list, down, validate, backup)
- Factory pattern using Commander.js for type-safe CLI creation
- Extensible via
extendCLIcallback for custom database-specific commands - Full configuration waterfall support (defaults β file β env β CLI flags)
ποΈ .env File Support (#129)
- Load configuration from
.env,.env.production,.env.localfiles - Configurable priority control via
config.envFileSources - Integrated with auto-envparse v2.1.0
- Environment-specific config without manual dotenv setup
π¨ Facade Pattern (#62)
- Services grouped into 4 logical facades (core, execution, output, orchestration)
- Protected facades allow adapters to extend executor and access internal services
- Cleaner architecture with clear service boundaries
- 70% code reduction (1564 β 467 lines in MigrationScriptExecutor)
π Factory Pattern (#97)
- Dedicated
MigrationServicesFactoryfor service initialization - Constructor complexity reduced by 83% (142 β 23 lines)
- Improved maintainability and testability
β¨ Extensible Configuration (#123)
- New
IConfigLoaderinterface for custom environment variable handling - Generic
ConfigLoader<C>supports adapter-specific config types IExecutorOptions<DB>separates required from optional dependencies- Adapters can extend ConfigLoader to add custom env vars
π¨ Breaking Changes
Constructor Signature Change
// OLD (v0.6.0)
new MigrationScriptExecutor({ handler }, config)
// NEW (v0.7.0)
new MigrationScriptExecutor({ handler, config })Config moved from second parameter into dependencies object.
Service Properties Removed
Internal services no longer exposed as public properties. Use public API methods:
executor.backupServiceβexecutor.createBackup()executor.migrationScannerβexecutor.list()executor.validationServiceβexecutor.validate()
Or extend MigrationScriptExecutor to access protected facades.
Migration Time: 15-30 minutes
π Statistics
- 100% Test Coverage - 1400 tests passing (2549/2549 statements)
- Zero Quality Issues - All SonarCloud checks passing
- 83% Constructor Reduction - From 142 lines to 23 lines
- 70% Code Reduction - MigrationScriptExecutor: 1564 β 467 lines
π Documentation
- CLI Adapter Development Guide - Create CLIs for your adapters
- CLI vs API Usage - When to use each approach
- Migration Guide - Upgrade from v0.6.x
- Environment Variables - .env file support
π― Highlights
- Production-Ready CLI - Built-in commands with extensibility
- Better Encapsulation - Facade pattern with protected access
- Adapter Friendly - Extensible ConfigLoader and executor
- Reduced Complexity - 83% constructor reduction
- .env File Support - No manual dotenv setup needed
- 100% Backward Compatible API - Only constructor signature changed
π Related Issues
- #59 - CLI Factory implementation
- #62 - Facade Pattern refactoring
- #97 - GOD class decomposition
- #122 - Pre-commit hooks with Husky
- #123 - Interface segregation (IExecutorOptions)
- #124 - Code review and quality improvements
- #125 - Documentation review
- #126 - Auto-apply environment variables
- #128 - Integrate auto-envparse library
- #129 - Upgrade to auto-envparse v2.1.0
π¦ Installation
npm install @migration-script-runner/core@^0.7.0π Quick Start
import { createCLI, MigrationScriptExecutor } from '@migration-script-runner/core';
const program = createCLI({
name: 'my-db-migrate',
version: '1.0.0',
createExecutor: (config) => {
const handler = new MyDatabaseHandler();
return new MigrationScriptExecutor({ handler, config });
}
});
program.parse(process.argv);Full Changelog: v0.6.0...v0.7.0
v0.6.0 - Observability & Configuration Flexibility
π What's New in v0.6.0
Observability, configuration flexibility, and enhanced type safety
This release brings comprehensive metrics collection, flexible configuration formats, and significantly improved type safety through generic parameters. Note: Contains breaking changes - see migration guide below.
β οΈ Breaking Changes
1. Generic Type Parameters (REQUIRED)
All interfaces now require explicit type parameters:
// β v0.5.x - No type parameter
class MyHandler implements IDatabaseMigrationHandler {
// β
v0.6.0 - Type parameter required
class MyHandler implements IDatabaseMigrationHandler<IDB> {Affected interfaces: IDatabaseMigrationHandler, IRunnableScript, MigrationScript, ISchemaVersion, IBackup, ITransactionManager
Migration time: 10-30 minutes to add <IDB> to all implementations
2. Constructor Signature Change
// v0.5.x
const executor = new MigrationScriptExecutor(handler, config);
// v0.6.0
const executor = new MigrationScriptExecutor({ handler }, config);What changed: Handler now wrapped in dependency injection object { handler }
See Migration Guide for complete upgrade instructions.
β¨ Major Features
π Metrics & Observability (#80)
Complete metrics collection system for production monitoring:
- Metrics Collectors: JSON, CSV, and Logger-based collectors
- MetricsCollectorHook: Automatic lifecycle event tracking
- Performance Tracking: Migration duration, success rates, error tracking
- CI/CD Integration: Machine-readable JSON/CSV output for reporting
- Composite Support: Use multiple collectors simultaneously
import { JsonMetricsCollector, CsvMetricsCollector } from '@migration-script-runner/core';
const executor = new MigrationScriptExecutor({
handler,
metricsCollectors: [
new JsonMetricsCollector({
filePath: './metrics/migrations.json',
pretty: true
}),
new CsvMetricsCollector({
filePath: './metrics/history.csv'
})
]
}, config);Output: Structured metrics with timing, success/failure tracking, and rollback information for dashboards and alerts.
βοΈ Multi-Format Configuration (#98)
Support for YAML, TOML, and XML configuration files:
- YAML Support:
.yamland.ymlfiles (requiresjs-yaml) - TOML Support:
.tomlfiles (requires@iarna/toml) - XML Support:
.xmlfiles (requiresfast-xml-parser) - Automatic Detection: ConfigLoader picks the right format
- Extensible: Add custom loaders via IConfigFileLoader
# All formats now supported:
msr.config.js # JavaScript (built-in)
msr.config.json # JSON (built-in)
msr.config.yaml # YAML (optional)
msr.config.toml # TOML (optional)
msr.config.xml # XML (optional)𧬠Generic Type Parameters (#114)
Database-specific type safety throughout the API:
- Type-Safe Handlers:
IDatabaseMigrationHandler<YourDB> - Type-Safe Scripts:
MigrationScript<YourDB> - Type-Safe Hooks: All hooks now generic over database type
- Better IntelliSense: Full autocomplete for your database interface
- Compile-Time Safety: Catch type mismatches before runtime
interface MyDB extends IDB {
query(sql: string): Promise<ResultSet>;
execute(sql: string): Promise<void>;
}
// Full type safety:
const handler: IDatabaseMigrationHandler<MyDB> = { /* ... */ };
const executor = new MigrationScriptExecutor<MyDB>({ handler }, config);ποΈ Banner Control (#100)
Toggle ASCII banner display for clean CI/CD logs:
config.showBanner = false; // Disable banner
// Or via environment variable:
// MSR_SHOW_BANNER=falseπ Debug Logging (#115)
Granular log level control for troubleshooting:
config.logLevel = 'debug'; // 'error' | 'warn' | 'info' | 'debug'
// Or via environment variable:
// MSR_LOG_LEVEL=debugπ Documentation
Enhanced Content
- Origin Story (#104): Project history and design philosophy
- Getting Started Guide (#108): Local testing and development setup
- Migration Guide (#110): v0.5.x β v0.6.0 upgrade path
- SEO Improvements (#101): Sitemap.xml for better discoverability
- Google Analytics (#111, #112): Production site analytics
Quality Improvements
- Comprehensive API documentation
- Real-world code examples
- Configuration reference updates
- Better search and navigation
π§ Quality & Security
Code Quality (#109)
- 43 of 46 SonarCloud issues resolved (93% improvement)
- Zero
anytypes in production code - 100% test coverage maintained (1,224 tests passing)
- All BLOCKER and CRITICAL issues fixed
- Improved code consistency and readability
Security (#117)
- Fixed npm security vulnerabilities in dependencies
- Updated coveralls package to secure version
- All security audits passing
π Migration Guide
From v0.5.x: See v0.5.x β v0.6.0 Migration Guide
Required changes (10-30 minutes):
- Add type parameters to interfaces:
// Update all implementations
class MyHandler implements IDatabaseMigrationHandler<IDB> {
const migration: IRunnableScript<IDB> = { /* ... */ };- Update constructor calls:
// Change from:
new MigrationScriptExecutor(handler, config)
// To:
new MigrationScriptExecutor({ handler }, config)Optional enhancements:
// 1. Add metrics collection (optional)
import { JsonMetricsCollector } from '@migration-script-runner/core';
executor.metricsCollectors = [
new JsonMetricsCollector({ filePath: './metrics.json' })
];
// 2. Use YAML config (optional)
// Convert msr.config.js β msr.config.yaml
// npm install js-yaml
// 3. Enhance with database-specific types (optional but recommended)
const executor = new MigrationScriptExecutor<YourDB>({ handler }, config);π¦ Installation
npm install @migration-script-runner/core@0.6.0Optional peer dependencies:
# For YAML support:
npm install js-yaml
# For TOML support:
npm install @iarna/toml
# For XML support:
npm install fast-xml-parserπ Stats
- 13 issues closed
- 43 code quality improvements
- 100% test coverage (1,224 tests)
- 2 breaking changes (see migration guide)
Full Changelog: v0.5.0...v0.6.0
v0.5.0 - Transaction Management & Cloud-Native Configuration
π What's New in v0.5.0
Production-grade transaction management and cloud-native configuration
This release brings powerful new capabilities for production deployments while maintaining 100% backward compatibility with v0.4.x. All existing code continues to work without modifications.
β¨ Major Features
π Transaction Management (#76)
Complete transaction support with automatic retry logic and isolation control:
- Configurable Modes:
PER_MIGRATION,PER_BATCH, orNONE - Automatic Retry: Exponential backoff for transient failures (deadlocks, timeouts)
- Isolation Levels:
READ_UNCOMMITTED,READ_COMMITTED,REPEATABLE_READ,SERIALIZABLE - SQL Support:
ITransactionalDBinterface with begin/commit/rollback - NoSQL Support:
ICallbackTransactionalDBfor MongoDB, Firestore, DynamoDB - Transaction Hooks: Monitor lifecycle events for metrics and logging
const config = new Config();
config.transaction.mode = TransactionMode.PER_MIGRATION;
config.transaction.isolation = IsolationLevel.READ_COMMITTED;
config.transaction.retries = 5;
config.transaction.retryBackoff = true;βοΈ Environment Variables (#84)
Complete 12-factor app configuration for cloud-native deployments:
- 33 MSR_ Variables*: Full configuration through environment variables
- Organized Categories: Core, Validation, Logging, Backup, Rollback, Transaction
- Docker/Kubernetes Ready: Perfect for containerized deployments
- CI/CD Integration: Environment-based configuration for pipelines
- ConfigLoader: Automatic waterfall loading (env β file β defaults β overrides)
export MSR_FOLDER=./migrations
export MSR_TRANSACTION_MODE=PER_MIGRATION
export MSR_TRANSACTION_RETRIES=5
export MSR_VALIDATE_BEFORE_RUN=trueπ Enhanced Lifecycle Hooks
New transaction lifecycle hooks for monitoring and metrics:
beforeTransactionBegin- Before transaction startsafterCommit- After successful commitonCommitRetry- On retry attemptsbeforeRollback- Before rollback on failure
π Improvements
- Code Quality (#94): Comprehensive code review addressing 47 SonarQube findings
- Documentation (#95): Complete migration guide and updated docs for v0.5.0
- Type Safety: Enhanced interfaces with better TypeScript support
- Error Handling: Improved error messages and validation
π Documentation
- Migration Guide - Step-by-step upgrade instructions with examples
- Transaction Management Guide - Complete transaction configuration
- Environment Variables API - All 33 MSR_* variables documented
- Full Documentation - Updated for v0.5.0
π Migration from v0.4.x
Estimated Time: 5-15 minutes
Complexity: Low - No breaking changes
Quick Upgrade
npm install @migration-script-runner/core@^0.5.0Your existing v0.4.x code works without modifications. New features are opt-in.
β View complete migration guide
πͺ No Breaking Changes
v0.5.0 maintains 100% backward compatibility:
- β All v0.4.x APIs work unchanged
- β All existing migrations continue to work
- β New features are optional and opt-in
- β Zero code changes required
π¦ Installation
npm install @migration-script-runner/core@0.5.0Or with yarn:
yarn add @migration-script-runner/core@0.5.0π Credits
Special thanks to all contributors and community members who provided feedback and suggestions for this release.
π Issues & Support
- Documentation: https://migration-script-runner.github.io/msr-core/
- Issues: https://github.com/migration-script-runner/msr-core/issues
- Discussions: https://github.com/migration-script-runner/msr-core/discussions
Full Changelog: v0.4.0...v0.5.0
v0.4.0 - SQL Support, API Improvements & Enhanced Developer Experience
π Release Highlights
Version 0.4.0 is a major release introducing SQL migration files, simplified API, and comprehensive developer experience improvements.
β¨ New Features
SQL Migration Support (#58)
- First-class SQL file support - Use
.up.sqland.down.sqlfiles alongside TypeScript migrations - ISqlDB interface - Type-safe SQL execution with
query(sql: string)method - Loader architecture - Extensible system supporting multiple file types (TypeScriptLoader, SqlLoader)
- Hybrid projects - Mix TypeScript and SQL migrations in the same project
Example:
-- V202501280100_create_users.up.sql
CREATE TABLE users (
id INT PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE
);Simplified API (#81)
- Industry-standard method names -
up()anddown()replacemigrate(),migrateTo(),downTo() - Backward compatible -
migrate()still works as an alias toup() - Clearer semantics - More intuitive API aligned with migration tool conventions
Migration:
// Before (v0.3.x)
await executor.migrateTo(202501280005);
await executor.downTo(202501280002);
// After (v0.4.0)
await executor.up(202501280005);
await executor.down(202501280002);Developer Experience Enhancements
Dry Run Mode (#73)
- Preview migrations without execution
- Perfect for CI/CD validation
- See what would be executed before running
config.dryRun = true;
await executor.up(); // Shows plan, doesn't executeExecution Summary Logging (#72)
- Detailed migration logs with complete audit trail
- Automatic file rotation and retention
- JSON and text formats
- Success and failure logging
config.logging.enabled = true;
config.logging.folder = './logs';
config.logging.format = 'JSON';Connection Validation (#88)
- Early connection checking with
checkConnection() - Fail fast with clear error messages
- Required for all IDB implementations
class MyDB implements IDB {
async checkConnection(): Promise<void> {
await this.db.ping();
}
}Multi-pattern Support
filePatterns(array) replacesfilePattern(single)- Support multiple file types simultaneously
- Cleaner configuration for hybrid projects
config.filePatterns = [
/^V(\d{12})_.*\.ts$/,
/^V(\d{12})_.*\.up\.sql$/
];π§ Breaking Changes
1. filePattern β filePatterns (High Impact)
// Before
config.filePattern = /^V(\d{12})_.*\.ts$/;
// After
config.filePatterns = [/^V(\d{12})_.*\.ts$/];2. API Method Renames (High Impact)
migrateTo(version)βup(version)downTo(version)βdown(version)migrate()still works as alias toup()
3. IDB.checkConnection() Required (High Impact)
All database implementations must implement checkConnection() method.
4. Interface Property Renames (Medium Impact)
ISchemaVersion.migrationsβmigrationRecordsIMigrationScript.getAll()βgetAllExecuted()
5. Service Method Renames (Low Impact)
IMigrationService.readMigrationScripts()βfindMigrationScripts()IMigrationService.getBeforeMigrateScript()βfindBeforeMigrateScript()
6. IBackup Parameter Rename (Low Impact)
restore(data)βrestore(backupData)
π Documentation
New Guides
- SQL Migrations Guide - Complete SQL migration documentation
- v0.3.x β v0.4.0 Migration Guide - Comprehensive upgrade instructions
Updated Documentation
- All API documentation updated with new method names
- Configuration guides updated for new options
- All recipes and examples updated to v0.4.0 API
- Reorganized interface documentation for better navigation
π οΈ Architecture Improvements
- Extensible loader system -
IMigrationScriptLoaderandILoaderRegistryinterfaces - Enhanced type safety - Improved type definitions across all interfaces
- Better error handling - More descriptive error messages and validation
π¦ Installation
npm install @migration-script-runner/core@0.4.0π Upgrade Instructions
See the v0.3.x β v0.4.0 Migration Guide for detailed upgrade instructions with examples.
Quick checklist:
- Update
filePatterntofilePatterns(array) - Replace
migrateTo()withup(),downTo()withdown() - Add
checkConnection()method to your IDB implementation - Update interface property names if using custom implementations
- Test migrations in development environment
π Full Documentation
https://migration-script-runner.github.io/msr-core/
π Contributors
Thank you to everyone who contributed to this release through issues, discussions, and feedback!
Released: January 30, 2025
Milestone: v0.4.0