nekoos/laravel-seed-drain

Incremental seed execution aligned with migrations, without extra schema.

Installs: 133

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/nekoos/laravel-seed-drain

v1.0.0 2026-02-14 22:42 UTC

This package is auto-updated.

Last update: 2026-02-14 23:24:02 UTC


README

CI Checks

Languages: English | EspaƱol

Incremental seed execution aligned with migrations.

artisan migrate --seed is useful for initial bootstrap, but it falls short in continuous automation workflows:

  • Migrations have native incremental control.
  • Seeders do not provide that same control by default.
  • In repeated deployments, db:seed can be hard to scope to the right moment.

laravel-seed-drain simplifies this with an explicit temporary seeder queue. By default, it does not require additional database tables. Optionally, it can persist queue state in a dedicated database table.

What Problem It Solves

  • Execute only relevant seeders after migrations.
  • Avoid introducing extra tracking schema for seeder execution.
  • Keep CI/CD workflows simple for development and production.
  • Optionally separate seeders by logical queues (default, core, demo).

Core Idea

Register seeders during migration up().

Then execute a dedicated command to drain them.

php artisan migrate --force
php artisan seed:drain --force

Installation

Install the package via Composer:

composer require nekoos/laravel-seed-drain:^1.0

Setup

Publish package files when you need to customize them:

# Publish configuration
php artisan vendor:publish --tag=seed-drain-config

# Publish package migrations (including seed_drain_queues)
php artisan vendor:publish --tag=seed-drain-migrations

Run migrations:

php artisan migrate

For contribution and local development guidelines, see CONTRIBUTING.md.

Proposed Public API

Default usage (default queue):

use NekoOs\LaravelSeedDrain\Support\SeedQueue;

SeedQueue::add(
    \Database\Seeders\UsersSeeder::class,
    \Database\Seeders\SessionSeeder::class,
);

Explicit queues (fluent API):

use NekoOs\LaravelSeedDrain\Support\SeedQueue;

SeedQueue::on('core')->add(
    \Database\Seeders\PermissionsSeeder::class,
    \Database\Seeders\StatusesSeeder::class,
);

SeedQueue::on('demo')->add(
    \Database\Seeders\DemoUsersSeeder::class,
);

By default, duplicate seeders are kept in the queue and executed in order.

Migration Example

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use NekoOs\LaravelSeedDrain\Support\SeedQueue;

return new class extends Migration {
    public function up(): void
    {
        Schema::create('customers', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });

        SeedQueue::add(\Database\Seeders\CustomersBaseSeeder::class);
        SeedQueue::on('demo')->add(\Database\Seeders\DemoCustomersSeeder::class);
    }
};

seed:drain Command

Suggested options:

  • --queue=default
  • --queue=core --queue=demo (repeatable)
  • --queue=core,demo (CSV)
  • --queue=all
  • --dedupe (optional fallback: compact duplicates before draining)
  • --no-lock (disable execution lock for this run)
  • --lock-store=... (cache store used by lock)
  • --lock-seconds=... (lock TTL)
  • --dry-run
  • --clear
  • --continue-on-failure
  • --force

Examples:

# Default queue
php artisan seed:drain --force

# Multiple queues
php artisan seed:drain --queue=core --queue=demo --force

# All queues
php artisan seed:drain --queue=all --force

# Inspection only
php artisan seed:drain --queue=core --dry-run

# Drain with duplicate cleanup
php artisan seed:drain --queue=core --dedupe --force

# Use lock in a specific cache store
php artisan seed:drain --queue=core --lock-store=database --lock-seconds=600 --force

# Disable lock explicitly
php artisan seed:drain --queue=core --no-lock --force

seed:drain:doctor Command

Use diagnostics to validate the active queue store, lock setup, and queued items:

# Inspect default queue selection
php artisan seed:drain:doctor

# Inspect specific queue set
php artisan seed:drain:doctor --queue=core --queue=demo

Events and Conditional Skip

The package dispatches events during drain execution:

  • NekoOs\LaravelSeedDrain\Events\SeedDrainStarting
  • NekoOs\LaravelSeedDrain\Events\SeederRunning
  • NekoOs\LaravelSeedDrain\Events\SeederSkipped
  • NekoOs\LaravelSeedDrain\Events\SeederSucceeded
  • NekoOs\LaravelSeedDrain\Events\SeederFailed
  • NekoOs\LaravelSeedDrain\Events\SeedDrainFinished

You can skip a seeder conditionally from a listener:

use NekoOs\LaravelSeedDrain\Events\SeederRunning;

Event::listen(SeederRunning::class, function (SeederRunning $event): void {
    if (app()->environment('production') && str_contains($event->seeder, 'Demo')) {
        $event->skip();
    }
});

Recommended Automation

Development:

php artisan migrate --force
php artisan seed:drain --queue=default --queue=demo --force

Production:

php artisan migrate --force
php artisan seed:drain --queue=default --force

Package Philosophy

  • No environment-specific magic in the package core.
  • No extra database tables.
  • Explicit API for technical teams.
  • Clean integration with existing pipelines.

Best Practices

  • Make seeders idempotent (upsert, updateOrCreate, firstOrCreate).
  • Keep demo seeders separate from functional seeders.
  • Treat --dedupe as a discretionary fallback, not as the default workflow.
  • Use --dry-run in CI when you need auditability before execution.

Queue Persistence

  • SEED_DRAIN_STORE=cache uses Laravel cache (default).
  • SEED_DRAIN_STORE=file persists queue state to a file path.
  • SEED_DRAIN_STORE=database persists queue state in a database table.
  • In deploy environments where cache can be reset, prefer file or a persistent cache backend.
  • Configure file path with SEED_DRAIN_FILE_PATH (ideally a persistent/shared path).

When using SEED_DRAIN_STORE=cache, persistence depends on the selected cache store:

  • Redis: set SEED_DRAIN_CACHE_STORE=redis (or your Redis-backed cache store name).
  • Database cache table: set SEED_DRAIN_CACHE_STORE=database.
  • Any custom Laravel cache store: set SEED_DRAIN_CACHE_STORE to that store name.

When using SEED_DRAIN_STORE=database:

  • Default table is seed_drain_queues.
  • Override table with SEED_DRAIN_DB_TABLE.
  • Override connection with SEED_DRAIN_DB_CONNECTION.
  • Override logical queue key with SEED_DRAIN_DB_KEY.
  • The package ships a migration for this table and auto-loads it.
  • The database store also creates the table lazily if it does not exist yet.

Custom queue persistence is also supported by binding your own implementation of NekoOs\LaravelSeedDrain\Core\Contracts\QueueStoreInterface in the container.

Status

This README defines the target contract and API direction for the package.