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

Laravel Migration Actions Laravel Package

dragon-code/laravel-migration-actions

Laravel Migration Actions lets you attach custom action classes to migrations and run them automatically around schema changes, so data setup, cleanup, and other migration-related tasks stay organized alongside the migrations that need them.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

What it is: A Laravel package that lets a team define "actions" — classes with up()/down() methods, tracked the same way migrations are tracked — and run them during deployment. It turns ad-hoc one-off scripts (data backfills, cache flushes, seeding lookup tables, config migrations) into versioned, once-only, reviewable deploy steps. Release 7.3.0 confirms a capability that was previously only implied: actions can also be dispatched as queued jobs, with configurable job class and uniqueness-lock duration, and the command supports Laravel-style --isolated execution.

Architecture fit: Strong for any Laravel codebase already living on php artisan migrate. The package follows standard Laravel package conventions: PSR-4 autoloading, service provider auto-discovery, an artisan generator command, and an execution record kept in a database table so actions do not re-run. It remains additive — it does not touch the ORM, routing, or the migration runner itself.

What 7.3.0 changes about the fit: the package now has a second execution surface. Actions can run inline in the release or be handed to your queue workers. That is architecturally the right call — it decouples long-running data work from the deploy window — but it means the package is no longer purely deploy-time tooling. It now depends on your queue connection, worker capacity, retry/timeout policy, and a shared cache lock store. Teams already comfortable with migrate still need no new mental model for the core concept; they do need a mental model for queue topology.

Integration feasibility: Still low. composer require, generate an action class, commit it, add one command to the deploy pipeline. Realistic pilot is now one engineer for three to four days: two to three days to convert existing deploy-script hacks and stand up the inline path, plus roughly half a day to decide queue connection/name, job class override, and lock TTL if you intend to use the queued path at all.

Technical risk:

  • Concurrency risk is materially reduced — but only if configured correctly. The --isolated fix ("match Laravel core presence semantics") means the package now uses Laravel's Isolatable behaviour, i.e. a cache-backed atomic lock, rather than whatever it did before. This was previously flagged as the single most important unknown. The remaining risk is environmental: isolation is only real if the lock store is genuinely shared and atomic (Redis, memcached, or the database cache driver). On array or per-container file cache in a rolling Kubernetes deploy, isolation is theatre. Verify the store before trusting the flag.
  • New: lock TTL versus job duration (queued path). Configurable uniqueness lock duration is a welcome knob and a real footgun. If the lock duration is shorter than the job's runtime or its queue wait time, the lock expires and a second dispatch can run the same operation concurrently. Set the TTL comfortably above p99 queue-wait + runtime, and alert on operations that exceed it.
  • New: deploy/operation skew (queued path). With inline execution, "deploy finished" implied "operations finished." With queued execution, the release can complete while an operation is still pending or stalled behind a backlog. New code is live against old data. This is a genuine ordering hazard that needs a deliberate answer: wait on the job, gate on the record table, or accept and design around the skew.
  • Positive maintenance signal. Three substantive PRs from an outside contributor (mark-year13) landing in a 7.3.0 minor release, on an established 7.x line, is better evidence of a functioning contributor pipeline than the previous assessment credited. It does not eliminate single-vendor concentration, but it weakens the "no downstream constituency" concern at the margin.
  • The overridable job class is a useful escape hatch. Being able to swap the dispatched job via queue.job config gives you a clean place to inject tracing, timeouts, retry policy, or tenant context without forking. It also lowers the cost of a future fork, since the most opinionated part of the queued path is now yours to own.
  • Repository naming drift (carried forward). Package laravel-migration-actions, repository laravel-deploy-operations. Confirm the canonical composer name matches the repository you are auditing, or your dependency scanner watches the wrong thing.
  • Release date anomaly (carried forward). Verify the registry timestamps before treating release cadence as a health signal. 7.3.0 is a real, coherent, semver-minor release, which is itself mild evidence of active maintenance.
  • Deploy-time (and now queue-time) execution remains inherently dangerous. Actions run against production data with no automatic rollback. DDL is non-transactional on MySQL, so a partially failed action leaves a half-applied state that down() may not cleanly reverse. Design property of the domain, not a package defect — but the queued path adds ambiguity about when the operation actually happened.
  • Unanswered from prior review: no evidence of --pretend/dry-run, batching/transaction helpers, or a testing helper for asserting actions in CI. Carry these forward as open questions.

Key questions for the maintainer / spike (revised):

  1. Is there a distributed lock? Partially answered. --isolated now follows Laravel core semantics. Verify: which cache store does it bind to, is it configurable, and what does it do when the store doesn't support atomic locks?
  2. For queued operations: what is the default uniqueness lock duration, is it configurable per-action or globally, and does the lock cover queue wait time or only execution time? What happens when the TTL expires mid-job?
  3. Does the deploy wait for queued operations, or does it return as soon as the job is dispatched? If it returns, how is completion verified?
  4. Does it record executions in the existing migrations table or a dedicated table, and what happens if that table is absent or behind?
  5. What happens on action failure, inline and queued — does the deploy halt, is the record rolled back so a retry re-runs it, and how many retries does the queued path default to?
  6. What is the supported Laravel/PHP version matrix — specifically the minimum version providing the Isolatable contract — and is there a CI matrix proving it?
  7. Is there a testing helper so actions can be asserted in CI rather than discovered in production?

Integration Approach

Stack fit: Fits any Laravel service on a version that provides the Isolatable contract (verify — this is Laravel 10.x-era core behaviour), and slots naturally into the deploy tooling most teams already use — Envoyer, Forge, Deployer, GitHub Actions, GitLab CI, or a Kubernetes pre-upgrade Job/init container. The natural insertion point is immediately before or after php artisan migrate in the release script. The queued path additionally requires a working queue connection and worker pool, which most Laravel services already have for other reasons — meaning the marginal infrastructure cost is usually zero, but the coupling is new.

Migration path: Do not rip out existing deploy scripts. Layer the package in:

  1. Install it in one mid-size service and generate a trivial no-op action to confirm discovery, tracking, and idempotency in staging. Run it with --isolated to prove the lock store works.
  2. Convert exactly one real, painful, currently-manual task — typically a data backfill that someone runs by hand from a laptop — into an inline action. Keep the first one synchronous so the mechanics are observable.
  3. Only once inline is boring, convert one long-running task to a queued action. Confirm the completion semantics and lock TTL under a realistic load before trusting it.
  4. After two clean release cycles, publish an internal convention: when to write an action versus a migration versus a job, and when to queue versus run inline.

Compatibility: Pin the version explicitly in composer.json and verify the constraint against your Laravel minor. 7.3.0 is a minor release and the three changes are additive or corrective rather than breaking, so the upgrade itself is low risk. Test against every database driver you actually run (transaction and locking semantics differ materially between MySQL, PostgreSQL, and SQL Server), and separately test against every cache driver you run — the isolation guarantee now depends on it. If you run multiple database connections, confirm which connection execution records are written to; if you run multiple queues, confirm which one the operations dispatch to.

Sequencing:

  1. Week 1 — spike and risk review. Answer the seven questions above; the two that matter most are the cache-store backing for --isolated and the queued path's completion semantics.
  2. Week 2 — pilot (inline). One service, one synchronous action, staging then production, deploy pipeline otherwise unchanged.
  3. Week 3 — pilot (queued). One long-running action moved to the queue. Set the lock TTL deliberately; instrument the job through the queue.job override if you want tracing without touching the package.
  4. Week 3–4 — convention and guardrails. Written rules on idempotency, size limits (no action should exceed a few minutes inline), chunking, TTL selection, and mandatory code review for anything touching data.
  5. Ongoing — expand. Add to additional services only after the convention has held for a month. Keep the option to fork open; MIT license plus the now-overridable job class make a vendored fork a legitimate, low-cost fallback.

Operational Impact

Maintenance: The package itself is small and stable — expect near-zero ongoing maintenance from the package side, and 7.3.0 is a non-breaking minor you can take at leisure. The maintenance burden is entirely yours: the actions you write are production data operations and need the same review rigor as migrations. Budget for a periodic (quarterly) check on upstream activity and Laravel major-version compatibility, with a standing decision point to fork. The queue.job config hook reduces the cost of a break — you can patch behaviour from your own class rather than waiting upstream.

Support: MIT, community-supported, effectively single-maintainer — but the 7.3.0 contributor activity is a genuine improvement in the bus-factor signal. Treat it as unsupported software with a good idea behind it and an increasingly credible contributor base. Name an internal owner, document the package in your runbook, and be prepared to vendor the small codebase if a Laravel upgrade breaks it. Do not put it on a critical path where a stalled upstream would block a framework upgrade.

Scaling: Inline execution is once-per-deploy by design, so steady-state cost is negligible. The queued path shifts, rather than adds, cost:

  • Concurrency: prefer running the command as a single step in the deploy orchestrator (a Kubernetes Job, a single Envoyer hook) rather than on every container, and rely on --isolated as a second line of defence — not the only one. Verify the lock store is shared and atomic.
  • Deploy duration: queued operations directly address the previous concern that a slow backfill extends the release window. The trade is that "deploy succeeded" no longer implies "data is correct," so define what you gate on. Keep a runtime cap either way; push anything multi-minute into the queue.
  • Worker capacity and backlog: operations now compete with application jobs. A saturated queue delays data changes indefinitely and silently. Give operations a dedicated queue name, monitor its depth, and alert on age-of-oldest-pending-operation.
  • Data volume: large backfills should be chunked inside the action, not written as a single UPDATE — and if queued, chunk at the job level so a failure retries a bounded unit rather than the whole backfill.

Failure modes to design for:

  • Partial application — action fails halfway; no rollback for DML already committed. Mitigation: write actions to be re-runnable and forward-fixable rather than relying on down(). Chunking limits blast radius.
  • Lock expiry / duplicate execution (new) — uniqueness lock duration shorter than queue-wait plus runtime lets two workers run the same operation. Mitigation: set TTL above p99, monitor operation duration, make actions idempotent regardless.
  • Queued but never run (new) — worker pool down or backlogged; the record is never written and nobody notices. Mitigation: post-deploy assertion that expected operation records exist, plus queue-depth alerting.
  • Silent skip — record written, action never actually ran or ran against the wrong connection. Mitigation: assert on the record table after deploy, and log action execution to your observability stack.
  • Deploy halt — a failing action blocks the release (inline), or leaves the release live with stale data (queued). Decide deliberately which behaviour you want per action and document the rollback procedure.
  • Schema/code skew — sharper with the queued path: a rollback may strand a queued operation written against code that no longer exists. Mitigation: enforce ordering in the pipeline, review actions and migrations together, and prefer forward-fixable actions over down().
  • Upstream abandonment — a future Laravel release breaks auto-discovery or the artisan signature. Mitigation: pinned version, queue.job override for local patching, fork readiness.

Ramp-up: Still very low for the core concept — the vocabulary is familiar (up/down, tracked execution, artisan), so a Laravel developer is productive in under an hour. 7.3.0 adds one genuinely new thing to teach: the queued path, and with it the notion that a deploy can be "done" while its data operations are still pending. Budget a short internal write-up covering (a) inline versus queued decision criteria, (b) lock TTL guidance, (c) how to verify operations completed, and (d) the code-review checklist treating actions as production data operations. That artifact matters more than the package.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console