Skip to content

05_17_09: Migration Tools - Automated Version Migration

Executive Summary

Automated version migration tools for handling breaking changes and upgrading AudioLab projects across major/minor versions.

Key Features: - Automated code transformations (regex + AST) - Pre-migration validation - Dry-run mode for safe preview - Automatic git backup - Migration guide generation - Manual step tracking - Rollback procedures


Tools

migrator.py

Automated migration CLI tool with transformation engine.

Usage:

# List available migration paths
python migrator.py list

# Validate pre-migration requirements
python migrator.py validate

# Preview changes (dry-run)
python migrator.py migrate --from 1.0.0 --to 2.0.0 --dry-run

# Apply migration
python migrator.py migrate --from 1.0.0 --to 2.0.0

# Use custom config
python migrator.py migrate --from 1.0.0 --to 2.0.0 --config custom_migration.yaml

Example Output:

======================================================================
AudioLab Migration: 1.0.0 → 2.0.0
======================================================================

Migration: Legacy to Modern API
Difficulty: moderate

Running pre-migration checks...
  Checking: Git status clean... ✓
  Checking: No uncommitted changes... ✓
  Checking: Tests passing... ✓

✓ Created backup tag: pre-migration-20250115_142345

Found 127 files to process

Processing: src/core/fft_processor.cpp
    3 × Add sample rate parameter to FFT calls
    1 × Replace raw buffer allocation
  ✓ Applied 4 changes

Processing: src/audio/processor.h
  ⊘ No changes needed

...

======================================================================
Migration Report
======================================================================

Files processed:  127
Files modified:   89
Total changes:    347
Errors:           0

======================================================================
Manual Steps Required
======================================================================

Step 1: Update CMakeLists.txt
  Action: Update minimum CMake version to 3.20+
  Verify: cmake --version shows 3.20+

Step 2: Rebuild dependencies
  Action: Run vcpkg install --recurse
  Verify: All dependencies installed

======================================================================

✓ Migration completed successfully

Next steps:
  1. Review changes: git diff
  2. Compile: cmake --build build
  3. Test: ctest
  4. Commit: git commit -am 'migrate: v1 to v2'


migration_guide.md (Template)

Template for generating version-specific migration guides.

Placeholders: - {from_version}, {to_version} - Version numbers - {release_date} - Release date - {difficulty} - Migration difficulty (trivial/easy/moderate/hard) - {breaking_changes_list} - List of breaking changes - {new_features_list} - New features - {manual_steps_list} - Manual migration steps - API change tables - Code examples (before/after) - Common issues and solutions

Generated Guide Example:

# AudioLab Migration Guide: 1.0.0 → 2.0.0

## Breaking Changes
- FFT interface now requires sample rate parameter
- Buffer allocation must be 16-byte aligned
- Deprecated `processLegacy()` removed

## Migration Steps

### Step 1: Prepare
git tag pre-migration-$(date +%Y%m%d)
python migrator.py validate

### Step 2: Automated Migration
python migrator.py migrate --from 1.0.0 --to 2.0.0

### Step 3: Manual Updates
Update CMakeLists.txt minimum CMake version to 3.20


Migration Workflow

Standard Workflow

┌─────────────────────────────────────────────────────────────┐
│  1. Pre-Migration Validation                                │
│     • Git status clean                                       │
│     • Tests passing                                          │
│     • Dependencies resolved                                  │
└─────────────────┬───────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│  2. Backup Creation                                          │
│     • Create git tag: pre-migration-YYYYMMDD_HHMMSS         │
│     • Optional: Create branch migration/vX-to-vY            │
└─────────────────┬───────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│  3. Dry Run (Optional but Recommended)                       │
│     • Preview all changes                                    │
│     • Review manual steps                                    │
│     • Estimate migration time                                │
└─────────────────┬───────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│  4. Automated Transformations                                │
│     • Regex-based pattern replacement                        │
│     • AST-based code refactoring                             │
│     • Configuration file updates                             │
└─────────────────┬───────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│  5. Manual Steps                                             │
│     • Follow generated migration guide                       │
│     • Update build configuration                             │
│     • Update dependencies                                    │
└─────────────────┬───────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│  6. Validation                                               │
│     • Compile without errors                                 │
│     • All tests pass                                         │
│     • No performance regression                              │
└─────────────────┬───────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│  7. Commit                                                   │
│     • git commit -am 'migrate: v1.0.0 to v2.0.0'            │
│     • Tag new version                                        │
└─────────────────────────────────────────────────────────────┘

Transformation Types

1. Regex-Based Transformations

Fast pattern matching and replacement.

Example:

- name: "Add sample rate to FFT"
  pattern: 'fft\.process\((\w+)\)'
  replacement: 'fft.process(\1, sampleRate)'
  file_types: [".cpp", ".h"]
  description: "FFT now requires sample rate parameter"

Use Cases: - Function signature changes - Namespace updates - Macro replacements - Simple refactoring

2. AST-Based Transformations

Semantic code analysis and refactoring.

Example:

- name: "Update buffer allocation"
  type: "ast"
  transformer: "buffer_allocator"
  description: "Replace raw allocation with aligned allocation"

Use Cases: - Complex refactoring - Type changes - Class hierarchy updates - Semantic analysis required

3. Configuration Updates

Update build and configuration files.

Example:

- name: "CMake version bump"
  file: "CMakeLists.txt"
  pattern: 'cmake_minimum_required\(VERSION [\d.]+\)'
  replacement: 'cmake_minimum_required(VERSION 3.20.0)'


Migration Strategies

By Scope

Patch Migration (2.1.0 → 2.1.1) - Difficulty: Trivial - Strategy: Drop-in replacement - Validation: Regression tests only - Example: Bug fixes, performance improvements

Minor Migration (2.0.x → 2.1.0) - Difficulty: Easy - Strategy: Backward compatible - Validation: Feature tests + regression - Example: New features, deprecations announced

Major Migration (1.x → 2.0.0) - Difficulty: Moderate to Hard - Strategy: Breaking changes - Validation: Full test suite + manual verification - Example: API changes, architectural changes


Configuration Files

migration_tools.yaml

Complete configuration (~18 KB): - Migration paths with version constraints - Automated transformation definitions - Manual step specifications - Validation rules - Strategy recommendations

Key Sections:

migration_paths:
  v1_to_v2:
    name: "Legacy to Modern API"
    from_version: "1.x"
    to_version: "2.0.0"
    difficulty: "moderate"
    automated_transforms: [...]
    manual_steps: [...]

transformations:
  regex:
    - name: "..."
      pattern: "..."
      replacement: "..."
      file_types: [...]

  ast:
    - name: "..."
      transformer: "..."

validation:
  pre_migration:
    checks: [...]
  post_migration:
    checks: [...]


Safety Features

1. Pre-Migration Validation

Ensures safe starting state: - ✓ Git working directory clean - ✓ No uncommitted changes - ✓ All tests passing - ✓ Dependencies resolved

2. Automatic Backup

Creates restore point:

git tag pre-migration-20250115_142345

Rollback command:

git reset --hard pre-migration-20250115_142345

3. Dry-Run Mode

Preview without applying:

python migrator.py migrate --from 1.0.0 --to 2.0.0 --dry-run

Shows: - Files to be modified - Exact changes - Manual steps required - Estimated time

4. File Filtering

Automatically excludes: - Build directories (build/, out/) - Hidden files (.git/, .vscode/) - Binary files - Vendor code (third_party/, external/)

5. Error Recovery

On error: - Stop immediately - Report error details - Preserve partial changes - Suggest rollback if needed


Best Practices

Before Migration

  1. Review migration guide thoroughly
  2. Run dry-run to preview changes
  3. Backup important work (beyond git tag)
  4. Schedule downtime if production system
  5. Inform team of migration in progress

During Migration

  1. Follow steps sequentially - don't skip
  2. Verify each step before proceeding
  3. Document issues encountered
  4. Don't modify code manually during automated phase
  5. Test incrementally when possible

After Migration

  1. Compile and test immediately
  2. Review all changes: git diff pre-migration-TAG
  3. Run full test suite
  4. Check performance benchmarks
  5. Update documentation
  6. Commit with descriptive message

Rollback Procedures

Option 1: Git Tag Reset

# Find backup tag
git tag -l "pre-migration-*"

# Reset to backup
git reset --hard pre-migration-20250115_142345

# Clean any untracked files
git clean -fd

Option 2: Migration Branch

# Return to main branch
git checkout main

# Delete migration branch
git branch -D migration/v1-to-v2

Option 3: Revert Commit

# If already committed
git revert <migration-commit-hash>

Common Migration Scenarios

Scenario 1: FFT API Update (v1 → v2)

Breaking Change:

// Before (v1.x)
fft.process(buffer);

// After (v2.0)
fft.process(buffer, sampleRate);

Migration:

python migrator.py migrate --from 1.0.0 --to 2.0.0
# Automatically adds sampleRate parameter

Scenario 2: Buffer Alignment (v1 → v2)

Breaking Change:

// Before (v1.x)
float* buffer = new float[size];

// After (v2.0)
float* buffer = allocateAlignedBuffer(size);

Migration: Manual update required (complex memory management)

Scenario 3: Namespace Refactor (v2.0 → v2.1)

Breaking Change:

// Before (v2.0)
using namespace AudioLab;

// After (v2.1)
using namespace AudioLab::Core;

Migration:

python migrator.py migrate --from 2.0.0 --to 2.1.0
# Automatically updates namespace references


Integration with CI/CD

Pre-Merge Validation

# .github/workflows/migration-check.yml
name: Migration Check

on:
  pull_request:
    branches: [main]

jobs:
  check-migration:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Validate migration
        run: |
          python migrator.py validate

      - name: Test migration (dry-run)
        run: |
          python migrator.py migrate \
            --from ${{ github.base_ref }} \
            --to ${{ github.head_ref }} \
            --dry-run

Automated Migration PR

# .github/workflows/auto-migration.yml
name: Auto Migration PR

on:
  release:
    types: [published]

jobs:
  create-migration:
    runs-on: ubuntu-latest
    steps:
      - name: Run migration
        run: |
          python migrator.py migrate \
            --from ${{ github.event.release.tag_name }} \
            --to ${{ github.ref_name }}

      - name: Create PR
        uses: peter-evans/create-pull-request@v5
        with:
          title: "chore: migrate to ${{ github.ref_name }}"
          body: |
            Automated migration generated by migration tools.

            Please review changes carefully.

Troubleshooting

Issue: Pre-migration checks fail

Symptom:

✗ Pre-migration checks failed
  Checking: Git status clean... ✗ FAILED

Solution:

# Commit or stash changes
git status
git add .
git commit -m "WIP: before migration"

# Or stash
git stash

# Retry migration
python migrator.py migrate --from 1.0.0 --to 2.0.0

Issue: Transformation fails on specific file

Symptom:

Processing: src/complex_processor.cpp
  ✗ ERROR: Regex pattern failed

Solution: 1. Review file manually 2. Fix syntax errors if any 3. Add file to exclusion list if needed 4. Report issue to migration tool maintainers

Issue: Compilation errors after migration

Symptom:

error: 'sampleRate' was not declared in this scope

Solution: 1. Migration may have missed some calls 2. Manually update remaining occurrences 3. Consider improving migration patterns 4. Submit issue/PR to migration config

Issue: Tests fail after migration

Symptom:

ctest: 23 tests passed, 5 tests failed

Solution: 1. Review failed tests 2. Check if tests need updating for new API 3. Verify migration didn't introduce bugs 4. Update test code to match new behavior


Extension Points

Custom Transformers

Create custom AST transformers:

# custom_transformer.py
from migrator import Transformer

class CustomBufferTransformer(Transformer):
    def transform(self, node: ast.Node) -> ast.Node:
        # Custom transformation logic
        pass

# Register
Migrator.register_transformer('custom_buffer', CustomBufferTransformer)

Custom Validators

Add project-specific validation:

# custom_validation.yaml
validation:
  pre_migration:
    custom_checks:
      - name: "Database schema version"
        command: "psql -c 'SELECT version FROM schema_migrations;'"
        expected_pattern: "^1\\.\\d+\\.\\d+$"

Metrics

Migration Success Rate

Track across team: - Automated: 70-80% of changes - Manual: 20-30% of changes - Rollback rate: <5% of migrations

Typical Timings

  • Patch (2.1.0 → 2.1.1): 5-15 minutes
  • Minor (2.0.x → 2.1.0): 30-60 minutes
  • Major (1.x → 2.0.0): 2-4 hours

Code Change Volume

Example major migration (1.0 → 2.0): - Files modified: 89 / 127 (70%) - Total changes: 347 transformations - Manual steps: 5-8 steps


Part of AudioLab Version Control System (05_17_VERSION_CONTROL)