Weave 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

Automation Laravel Laravel Package

liberusoftware/automation-laravel

A Laravel package for automating application workflows. Define triggers, conditions, and actions to run repetitive tasks automatically, with scheduler and queue integration and an expressive API for managing automated processes in your Laravel apps.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat this as a Filament panel you extend, not a package you consume as a library. The provisioning engine ships as resources, actions and jobs behind a Filament 5 panel provider; your day-to-day work happens in the admin UI and in the models it exposes.

Minimum viable setup:

composer require liberusoftware/automation-laravel
php artisan vendor:publish --tag="automation-config"
php artisan vendor:publish --tag="automation-migrations"
php artisan migrate
php artisan make:filament-user

Then register the plugin in your panel provider (app/Providers/Filament/AdminPanelProvider.php), not in AppServiceProvider:

->plugin(\Liberusoftware\Automation\AutomationPlugin::make())

If you are running this under lerd, the order matters:

  1. site → action: "list" to confirm the site is registered and note the runtime (fpm vs fpm-custom).
  2. db → action: "set" to move off SQLite if you want a realistic provisioning DB.
  3. env → action: "setup", then always framework → action: "setup" (composer install, key, migrations). Skipping the framework step is the most common "nothing works" cause.
  4. Start a worker for the provisioning queue — this package is queue-driven and the UI will sit at "pending" forever without one.

Where to look first, in order:

  • config/automation.php — queue name, connection, timeouts, driver/credentials keys. Everything you'll want to tune lives here.
  • The published migrations — they tell you the real domain model (targets, steps, runs, statuses) faster than any README.
  • The Filament resources directory — the Actions on each resource are the supported entry points. If an operation isn't an Action or a console command, it's probably internal.
  • php artisan about and php artisan automation:... (check artisan list) for the CLI surface, which is usually the same code path as the UI.

First real use case: register one target (a server or a local environment record), let the package validate connectivity, then run its provisioning action from the resource's table row. Watch the run record move through its status enum while your worker picks up the job, then open the run's step list. Getting that single happy path green teaches you 80% of the package: the model graph, the queue contract, and where failures are recorded.

Implementation Patterns

One code path for UI, CLI and CI. The most valuable habit with a package like this is to never let a provisioning flow exist only as a Filament button. Put the dispatch in a small action class or console command and have the Filament Action call it:

->action(fn (Target $record) => ProvisionTarget::dispatch($record))

Now a deploy script, a test, and a human in the panel all do the same thing, and you can Queue::fake() the lot in tests.

Model the run, not the side effect. Keep a parent run/provisioning record whose status enum is the single source of truth, with child step rows. When something fails at 3am, the run page is your incident report. Anything you add (custom checks, post-provision smoke tests) should write a step row rather than Log::error and vanish.

Idempotent steps, resumable runs. Provisioning hits the network and remote shells; steps will be re-run after a timeout or a worker restart. Make each step check current state first (if ($alreadyConfigured) return StepResult::skipped();). This also makes a "retry from failed step" action trivial to add and is the difference between a system you trust and one you babysit.

Dedicated queue, dedicated worker. Don't share the default queue with mail and notifications — a slow provision will starve everything else. Set automation.queue to provisioning and run one worker on it:

# under lerd: add as a custom worker in .lerd.yaml
command: php artisan queue:work --queue=provisioning --timeout=900 --tries=1

--tries=1 plus explicit retry-from-step is almost always better than blind retries for provisioning.

Live status in Filament without polling everything. Use ->poll('5s') on the runs table only, and eager-load steps in the query. For long flows, broadcast step transitions over Reverb and ->refreshTableOnBroadcast() instead of polling; the scheduler/queue worker split on lerd already makes this cheap.

Guard destructive actions. Wipe/rebuild/rollback actions get ->requiresConfirmation(), a typed confirmation string where the package supports it, and a policy check. Filament's visible() is presentation, not authorization — put the real check in the policy so the CLI path is covered too.

Wrap package services for injection. Where you need behaviour in your own code (a webhook after provisioning, an audit entry), bind a thin decorator around the package's service in a service provider rather than forking or subclassing internals. Subclassing Filament resources is brittle across releases; decorating a service is not.

Test at two levels. Queue::fake() + RefreshDatabase for the dispatch/authorization layer (fast, runs in CI). A separate, opt-in integration suite that actually provisions a throwaway target for the engine itself. Never let the slow suite gate every PR, but never have zero coverage on the steps either.

Gotchas and Tips

Everything is bleeding edge. Laravel 12, PHP 8.5 and Filament 5 in one dependency graph means conflicts are routine. Pin filament/filament and this package together in composer.json, commit the lock file, and upgrade on a branch with the panel booted — not in a composer update sweep.

Plugin registration in the wrong provider. Registering the plugin in AppServiceProvider (or forgetting it entirely after publishing) leaves you with migrations applied and an empty navigation. If resources are missing, check the panel provider first, then php artisan filament:optimize-clear.

Config caching hides your edits. After publishing automation-config and editing queue/driver keys, php artisan config:clear. On lerd sites this bites twice — the FPM container and any host worker can see different cached configs.

Long jobs meet queue:restart. Deploys call queue:restart, which kills in-flight jobs after their current step. Design for it: short steps, persisted progress, and a supervisor/manual retry. Add WithoutOverlapping keyed on the target so a user double-clicking the action can't provision the same machine twice.

Timeouts are three separate settings. The job's $timeout, the worker's --timeout, and the process timeout inside the step. The effective limit is the smallest, and the failure mode differs for each (job released vs worker killed vs silent step hang). Set them deliberately and log the elapsed time per step so you can see which one bit you.

Credentials in Filament forms. Use ->password() with ->dehydrated(fn ($state) => filled($state)) so an empty field on edit doesn't null out a stored secret. Store secrets with encrypted casts, and remember they'll appear in $record->toArray() — exclude them from any JSON export or activity log.

SQLite is fine for the UI, awful for provisioning. db action: "set" to MySQL/Postgres early: the run/step tables grow with every attempt, and concurrent workers on SQLite will lock and produce failures that look like provisioning bugs.

Custom-image PHP sites on lerd. If runtime reports fpm-custom, php artisan must run inside lerd-cfpm-<site>. Running it on the host gives you a different PHP version and confusing class-not-found errors that have nothing to do with the package.

DB grants, not package bugs. Provisioning issues DDL. A database user without CREATE/ALTER produces a failure three steps in, after everything looked fine. Verify grants before opening an issue.

Give provisioning its own log channel. One channel per run (or a shared log context with the run id) means you can tail one file during a repro instead of grepping laravel.log for a UUID. This is the single highest-leverage debugging change you'll make.

Treat pre-1.0 as moving. With a low star count and a recent release date, the internal API is not stable. Keep your extensions in app/ behind service bindings and custom Filament pages, re-publish stubs on upgrade, and read the changelog diff for migration changes before running migrate in anything shared.

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.
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo
bernskioldmedia/laravel-harvest
bernskiold/laravel-data-scrubber
bernskiold/laravel-currency-converter
bernskiold/laravel-campaign-monitor
bernskioldmedia/laravel-autotranslate
siberfx/telegram-bot
roy-sandip/laravel-view-extended
gregsphotography/site-builder-core
roy-sandip/laravel-view
anodyne/blade-fluentui-icons
webx-ui/module-catalog-collections