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:migrate
Quick 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
end
Run 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 scripts
Advanced Usage
Skip Script Conditionally
def self.execute
skip! "No users need updating" if User.where(needs_update: true).count.zero?
# Your logic here
end
Custom Timeout
def self.timeout
3600 # 1 hour in seconds
end
Batch Processing
def self.execute
users = User.where(processed: false)
process_in_batches(users, batch_size: 1000) do |user|
user.update!(processed: true)
end
end
Progress 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
end
API 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 executionlog(message, level: :info)- Log a messagelog_progress(current, total)- Log progress percentageprocess_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 executedcleanup_stale_running_scripts(older_than: 1.hour.ago)- Clean up stale scripts
Rake Tasks
rake scripts:create[description]- Create a new scriptrake scripts:run- Run all pending scriptsrake scripts:status- Show status of all scriptsrake scripts:rollback[filename]- Rollback a scriptrake 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.3
Required: Set RUBYGEMS_AUTH_TOKEN in GitHub repository secrets.
Local Release
bin/release 0.1.3
Contributing
Bug reports and pull requests welcome at https://github.com/a-abdellatif98/script_tracker.
License
MIT License - see LICENSE file for details.