Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel One Time Operations Laravel Package

timokoerber/laravel-one-time-operations

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require timokoerber/laravel-one-time-operations
    php artisan migrate
    
    • Runs a single migration to create the one_time_operations table.
  2. First Operation:

    php artisan operations:make SeedAdminUser
    
    • Generates a stub file in app/Operations/SeedAdminUser.php.
    • Implement the handle() method to define your one-time logic (e.g., seeding an admin user).
  3. Run Immediately:

    php artisan operations:run
    
    • Executes all pending operations in order (like migrations).
  4. Verify:

    • Check the one_time_operations table for completed entries or debug logs.

Where to Look First

  • Stub File: app/Operations/ (auto-generated by operations:make).
  • Table Schema: database/migrations/[timestamp]_create_one_time_operations_table.php.
  • Artisan Commands: app/Console/Kernel.php (registers OperationsCommand).

Implementation Patterns

Core Workflows

  1. Deployment Hooks:

    • Use php artisan operations:run in your post-deploy script (e.g., Deployer, GitHub Actions, or deploy.php).
    • Example (.github/workflows/deploy.yml):
      - name: Run one-time operations
        run: php artisan operations:run --env=production
      
  2. Conditional Execution:

    • Environment-Specific: Pass --env=staging to target specific environments.
    • Manual Trigger: Run php artisan operations:run --force to bypass checks (e.g., for local testing).
  3. Ordering:

    • Operations run in alphabetical order by filename (e.g., ASeedAdmin.php runs before BUpdatePricing.php).
    • Use prefixes (e.g., 01_, 02_) for explicit ordering if needed.
  4. Integration with Jobs/Commands:

    • From a Command:
      use Illuminate\Support\Facades\Artisan;
      
      public function handle() {
          Artisan::call('operations:run');
      }
      
    • From a Job:
      public function handle() {
          if ($this->shouldRunOperations()) {
              Artisan::queue('operations:run');
          }
      }
      
  5. Data-Dependent Logic:

    • Use the OneTimeOperation model to query pending operations:
      $pending = OneTimeOperation::where('executed_at', null)->get();
      

Best Practices

  • Naming Conventions: Use PascalCase for operation files (e.g., CreateInitialData.php).
  • Idempotency: Ensure handle() is idempotent (safe to re-run if needed).
  • Logging: Leverage Laravel’s logging or add custom logs in handle():
    \Log::info('Admin user seeded successfully', ['user_id' => $user->id]);
    

Gotchas and Tips

Pitfalls

  1. Race Conditions:

    • If multiple deployments run concurrently, operations may execute out of order.
    • Fix: Use database transactions in handle() or add a lock column to the table.
  2. Stuck Operations:

    • If handle() throws an exception, the operation marks as failed but not retried.
    • Fix: Wrap logic in a try-catch and log errors:
      try {
          $this->performLogic();
      } catch (\Exception $e) {
          \Log::error("Operation failed: {$e->getMessage()}");
          throw $e; // Marks as failed in the DB
      }
      
  3. Environment Mismatches:

    • Operations run in the current environment (check app()->environment() in handle()).
    • Fix: Explicitly check environments:
      if (app()->environment('production')) {
          // Production-only logic
      }
      
  4. Table Bloat:

    • The one_time_operations table grows indefinitely.
    • Fix: Add a cleanup command to purge old entries (e.g., older than 30 days):
      php artisan operations:cleanup --days=30
      

Debugging Tips

  • Dry Run: Use --dry-run to preview operations without executing:
    php artisan operations:run --dry-run
    
  • Verbose Output: Add -v for detailed logs:
    php artisan operations:run -v
    
  • Check Table Directly:
    SELECT * FROM one_time_operations ORDER BY created_at;
    

Extension Points

  1. Custom Storage:

    • Override the default table by binding a custom OneTimeOperationRepository in AppServiceProvider:
      $this->app->bind(
          OneTimeOperationRepository::class,
          CustomRepository::class
      );
      
  2. Event Listeners:

    • Listen for OperationExecuted events to trigger side effects:
      public function handle(OperationExecuted $event) {
          // Send Slack notification, etc.
      }
      
  3. Parallel Execution:

    • Use Laravel Queues to run operations in parallel (modify the run command):
      foreach ($operations as $operation) {
          RunOperationJob::dispatch($operation);
      }
      
  4. Rollback Support:

    • Add a rollback() method to operations for undo logic:
      public function rollback() {
          // Reverse changes made in handle()
      }
      
    • Extend the package’s OperationsCommand to support rollbacks.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours