ScriptTracker
A Ruby gem that provides a migration-like system for managing one-off scripts in Rails applications with execution tracking, transaction support, and built-in logging.
Features
- Execution Tracking - Automatically tracks which scripts have been run and their status
- Transaction Support - Wraps script execution in database transactions
- Status Management - Track scripts as success, failed, running, or skipped
- Built-in Logging - Convenient logging methods with timestamps
- Batch Processing - Helper methods for processing large datasets efficiently
- Timeout Support - Configure custom timeouts for long-running scripts
Installation
Add to your Gemfile:
gem 'script_tracker'Then run:
bundle install
rails generate script_tracker:install
rails db:migrateQuick Start
Create a Script
rake scripts:create["update user preferences"]This creates a timestamped script file in lib/scripts/ :
module Scripts
class UpdateUserPreferences < ScriptTracker::Base
def self.execute
log "Starting script"
User.find_each do |user|
user.update!(preferences: { theme: 'dark' })
end
log "Script completed"
end
end
endRun Scripts
rake scripts:run # Run all pending scripts
rake scripts:status # View script status
rake scripts:rollback[filename] # Rollback a script
rake scripts:cleanup # Cleanup stale scriptsAdvanced Usage
Skip Script Conditionally
def self.execute
skip! "No users need updating" if User.where(needs_update: true).count.zero?
# Your logic here
endCustom Timeout
def self.timeout
3600 # 1 hour in seconds
endBatch Processing
def self.execute
users = User.where(processed: false)
process_in_batches(users, batch_size: 1000) do |user|
user.update!(processed: true)
end
endProgress Logging
def self.execute
total = User.count
processed = 0
User.find_each do |user|
# Process user
processed += 1
log_progress(processed, total) if (processed % 100).zero?
end
endAPI Reference
ScriptTracker:: Base
Class Methods:
-
execute- Implement with your script logic (required) -
timeout- Override to set custom timeout (default: 300 seconds) -
skip!(reason)- Skip script execution -
log(message, level: :info)- Log a message -
log_progress(current, total)- Log progress percentage -
process_in_batches(relation, batch_size: 1000, &block)- Process in batches
ScriptTracker:: ExecutedScript
Scopes: successful , failed , running , skipped , completed , ordered , recent_first
Class Methods:
-
executed?(filename)- Check if script has been executed -
cleanup_stale_running_scripts(older_than: 1.hour.ago)- Clean up stale scripts
Rake Tasks
-
rake scripts:create[description]- Create a new script -
rake scripts:run- Run all pending scripts -
rake scripts:status- Show status of all scripts -
rake scripts:rollback[filename]- Rollback a script -
rake scripts:cleanup- Cleanup stale running scripts
Releasing
GitHub Actions (Recommended)
- Go to Actions → Release workflow
- Click Run workflow
- Enter version number (e.g.,
0.1.3)
Or push a tag:
git tag -a v0.1.3 -m "Release version 0.1.3"
git push origin v0.1.3Required: Set RUBYGEMS_AUTH_TOKEN in GitHub repository secrets.
Local Release
bin/release 0.1.3Similar Gems
Choosing the right tool for your data migration needs depends on your use case. Here's how ScriptTracker compares to other popular solutions:
vs. data_migrate
data_migrate runs data migrations alongside schema migrations using a db/data directory.
| Feature | ScriptTracker | data_migrate |
|---|---|---|
| Integration | Standalone script system with dedicated rake tasks | Integrates directly with rails db:migrate
|
| Execution Tracking | Rich status tracking (success/failed/running/skipped) | Simple executed/not executed |
| Transaction Support | Built-in with automatic rollback on failure | Depends on migration implementation |
| Rollback | Dedicated rollback command with custom logic | Standard Rails migration rollback |
| Logging | Built-in logging helpers with timestamps | Standard Rails logger |
| Batch Processing | Helper methods included | Manual implementation |
| Timeout Support | Configurable per script | Not included |
| Best For | One-off maintenance scripts and data fixes | Keeping data migrations in sync with schema changes |
When to choose data_migrate: You want data migrations to run automatically with schema migrations in your deployment pipeline.
When to choose ScriptTracker: You need more control over one-off scripts with detailed tracking, rollback capabilities, and don't want them tied to your schema migration workflow.
vs. maintenance_tasks (Shopify)
maintenance_tasks is a Rails engine providing a web UI for queueing and managing long-running data migrations.
| Feature | ScriptTracker | maintenance_tasks |
|---|---|---|
| Web UI | Command-line only | Full web interface for managing tasks |
| Job Backend | Direct execution | Active Job integration |
| Interruptibility | Not supported | Tasks can pause and resume across deploys |
| Throttling | Not supported | Built-in throttling with backoff |
| CSV Processing | Manual implementation | Built-in CSV upload and processing |
| Complexity | Lightweight, minimal dependencies | Heavier, requires mounting engine and UI |
| Learning Curve | Simple, migration-like syntax | More setup, additional concepts |
| Best For | Simple one-off scripts, small teams | Production-grade tasks, large teams, complex workflows |
When to choose maintenance_tasks: You need a robust UI for non-technical users, want tasks to survive deploys/restarts, or need advanced features like throttling.
When to choose ScriptTracker: You prefer simplicity, want CLI-based workflow, or don't need the overhead of a web UI and Active Job.
vs. after_party
after_party automates post-deploy tasks that run once per environment.
| Feature | ScriptTracker | after_party |
|---|---|---|
| Execution Model | Manual or automated via rake | Automatic on deployment |
| Status Tracking | Rich status (success/failed/running/skipped) | Binary executed/not executed |
| Rollback Support | Dedicated rollback with custom logic | No rollback support |
| Skip Logic | Built-in skip! method |
Manual implementation |
| Logging | Built-in helpers with timestamps | Manual implementation |
| Batch Processing | Helper methods included | Manual implementation |
| Progress Tracking |
log_progress helper |
Manual implementation |
| Best For | Managed execution with detailed tracking | Fire-and-forget deployment tasks |
When to choose after_party: You want tasks to run automatically after each deployment with minimal configuration.
When to choose ScriptTracker: You need more visibility, control, and features like rollback, status tracking, and skip logic.
Quick Decision Guide
Choose ScriptTracker if you want:
- Rich execution tracking with detailed status
- Built-in logging, batch processing, and progress tracking
- Rollback capabilities for one-off scripts
- CLI-based workflow without web UI overhead
- Transaction support with automatic rollback on failure
Choose data_migrate if you want:
- Data migrations that run with schema migrations
- Integration with existing Rails migration workflow
- Automatic execution during deployments
Choose maintenance_tasks if you want:
- Web UI for managing tasks
- Tasks that survive deploys and restarts
- Advanced features (throttling, CSV processing)
- Production-grade task management for large teams
Choose after_party if you want:
- Simple post-deploy automation
- Fire-and-forget task execution
- Minimal configuration and setup
Contributing
Bug reports and pull requests welcome at https://github.com/a-abdellatif98/script_tracker.
License
MIT License - see LICENSE file for details.