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 Task Runner Laravel Package

protonemedia/laravel-task-runner

Laravel Task Runner lets you define reusable tasks as classes and run them from Artisan, code, or a schedule. It offers clean task registration, output handling, and cron-like scheduling for maintenance routines and background work.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit protonemedia/laravel-task-runner targets a specific gap in most Laravel codebases: shell logic that lives in .sh files, Makefiles, Envoy files, or copy-pasted exec() calls, outside of dependency injection, outside of tests, and outside of code review conventions. It reframes each script as a Task class whose body is a Blade template, executed through a runner abstraction that can target localhost or a configured remote host over SSH. For a TPM, the relevant architectural claim is not "we can run shell commands" — Artisan and Process already do that — it is "shell becomes a first-class, testable, reviewable artifact in the same language and repo as the application." That fits well with Laravel monoliths and mid-sized platform teams that already own their deploy/provisioning scripts but do not want to stand up Ansible, Terraform provisioners, or a full config-management discipline. It fits poorly with organizations that already have an established ops toolchain (Ansible/Puppet/Salt), a platform team that owns infrastructure-as-code separately, or a hard requirement for agent-based execution and orchestration beyond "SSH into host, run script."

Integration feasibility Integration cost is genuinely low: composer require, publish the config, declare one or more servers (host, port, user, key material), write task classes, invoke via the facade or from an Artisan command/job. There is no schema change, no service to deploy, no daemon. The package is pure PHP on top of Composer, so it slots into existing CI without new infrastructure. The main feasibility question is not "can we install it" but "where does it run from" — an HTTP request, a queued job, a scheduled command, or a CI runner each impose very different timeout, credential, and audit constraints.

Technical risk

  • Bus factor and adoption. 131 stars and zero dependents is a thin signal. The maintainer (Protone Media / Pascal Baljet) has a strong track record across many Laravel packages, which materially de-risks quality, but it does not de-risk longevity of this package. Treat it as "credible solo-maintainer package," not "platform dependency." The 1.7.0 "new contributor" is a first-party automation account, not evidence of a broadening contributor base — the bus factor is unchanged.
  • Shell escaping semantics. Blade's {{ }} escaping model is HTML-oriented, not shell-oriented. Any interpolation of user- or env-supplied values into a command string is a potential quoting bug or injection vector. This needs an explicit, enforced convention (quote-and-escape helper, or restrict to validated scalars) before the package is used with anything dynamic.
  • Credential surface. SSH keys and host credentials land in Laravel config/env. That is convenient and also a new secret to manage, rotate, and scope. Combined with remote execution, the blast radius of a compromised app server increases.
  • Execution model. Long-running shell in a PHP request is a well-known failure pattern (max_execution_time, memory from buffered output, no retry). Whether the package gives you queue-native ergonomics — retries, backoff, locking, per-task timeouts, output streaming — determines whether it is a developer convenience or a production execution layer. Verify before committing.
  • Version stability. 1.7.0 (from 1.6.0) is strictly maintenance: Dependabot bumps to CI actions (checkout, fetch-metadata, laravel-pint-action, git-auto-commit-action) plus adding PHP 8.5 to the test matrix. No API changes, no deprecations, no new capability, no breaking changes; the 1.x line is behaving as a stable, additive-only series. Read that as positive on hygiene and neutral on everything else — the release does not tell us anything about SSH semantics, escaping, or execution model, so none of the substantive risks move.
  • Portability. Local localhost execution on Windows dev machines and non-POSIX shells is a likely rough edge; assume Linux/macOS-only for local runs.

Key questions

  1. Is SSH-per-task sufficient, or do we need fan-out to dozens/hundreds of hosts with concurrency limits and partial-failure reporting?
  2. Does the runner provide idempotency primitives (locking, single-flight, already-ran guards), or is that entirely our convention?
  3. What are the supported Laravel/PHP version ranges, and what is the release/BC policy? (Partially answered by 1.7.0: PHP 8.5 is now in the CI matrix alongside earlier versions, confirming prompt PHP-version tracking. The full supported matrix, the Laravel-side bounds, and a written BC policy for 1.x are still unconfirmed — infer "additive within 1.x" from release history rather than from documentation.)
  4. How is output captured, streamed, truncated, and redacted before it hits logs?
  5. Does host-key verification / known_hosts handling exist, and can it be enforced rather than bypassed?
  6. Is there a fake/assertion helper for tests (e.g., TaskRunner::fake() + assert-rendered-command)? This is the package's core value proposition — if testing is weak, the justification collapses.
  7. How are secrets passed to remote scripts — env, stdin, temp file — and are they visible in process listings or logs?
  8. What happens on timeout or process kill mid-script — is there cleanup, or do we own remote state consistency?

Integration Approach

Stack fit Best fit: Laravel 10/11/12 monolith on PHP 8.1+, Linux hosts, existing Artisan-command culture, small platform team (1–4 people) that owns its own deploys, and no incumbent configuration-management tool. Poor fit: polyglot estates with a dedicated infra team, Kubernetes-first deployments (where kubectl exec/Jobs already cover this), or environments with strict no-SSH-from-app-tier policy.

Migration path Adopt as a refactor of what already exists, not as a new capability. The lowest-risk first move is to port an existing .sh script verbatim into a Task::render() Blade template with no behavioral change, then diff the emitted command against the original for a set of representative inputs. That validates the escaping model and the execution semantics against real scripts before anything new is written. Keep Envoy/Deployer in place during this phase; the task runner wraps individual steps, it does not need to replace the orchestrator. Upgrading 1.6.0 → 1.7.0 is a no-op for application code; pick up 1.7.0 if the team is already on or moving to PHP 8.5, otherwise it is a patch-level bump with no behavioral surface.

Compatibility Pin an exact minor version in composer.json — 1.7.0 is the current best pin, both for PHP 8.5 readiness and because it is the only release tested against 8.5 — and add the package's requirements to the CI matrix (PHP version, Laravel version). Confirm there is no dependency on the ssh2 PECL extension — a pure-PHP SSH implementation is strongly preferable because it removes a per-host build step and keeps CI and container images unchanged. Verify behavior against the oldest Laravel version still in support on the team, not just the newest.

Sequencing

  1. Spike (1 week, one engineer). Install in a scratch branch, implement three tasks: a read-only health check (df -h, systemctl is-active), an idempotent maintenance task, and one non-idempotent task to observe failure behavior. Confirm fake/assert helpers work.
  2. Conventions document. Shell escaping rule, mandatory set -euo pipefail, naming, output redaction, where credentials come from, which hosts are eligible.
  3. Secret and host config. Move SSH key material into the existing secret store rather than .env plaintext; define per-environment server entries; decide host-key verification policy.
  4. Convert 2–3 real scripts already in production, behind an Artisan command, so invocation path is unchanged for operators.
  5. Execution wrapper. Decide the invocation surface — scheduled command vs. queued job — and add timeout, retry, and failure alerting at that layer, not inside the task.
  6. Test coverage. Assert rendered commands for every task; this is the deliverable that justifies the package.
  7. Optional promotion into the deploy pipeline, only after 4–6 have run cleanly for a release cycle.
  8. Documented fallback. Keep the original scripts in the repo, tagged, so a package abandonment or breaking change is a revert, not a rewrite.

Operational Impact

Maintenance Code footprint is small — a config file, a handful of task classes, and a wrapper. The recurring cost is the package itself: one maintainer, low issue volume, release cadence tied loosely to Laravel majors. 1.7.0 reinforces that the package tracks upstream PHP releases (8.5 support landed via CI matrix changes and shipped with no API impact), which is the maintenance behavior you want from a dependency this small — but it is still a one-person release train, and the dependabot-heavy changelog confirms the release volume is CI housekeeping rather than feature work. Budget a half-day per Laravel upgrade to validate compatibility, and maintain an internal fork-ready posture (the MIT license and small surface make a fork genuinely viable, which is the real mitigation for the bus-factor risk). Do not let task classes sprawl into dozens of bespoke scripts; that recreates the problem the package was adopted to solve.

Support No vendor SLA, no paid support tier. Support is GitHub issues plus internal expertise. That is acceptable for developer tooling with a documented fallback, and unacceptable for anything on the critical path of customer-facing availability. Keep the task runner off the request path of production traffic.

Scaling SSH-per-task does not scale horizontally on its own: N hosts means N connections, N timeouts, and a partial-success matrix the package likely does not model. For fan-out, wrap in queued jobs with per-host granularity, a concurrency limit, and per-host success/failure records. Output buffering in memory means output-heavy commands (large log dumps, tar, rsync progress) should be redirected to files rather than captured. For a handful of hosts and a few dozen tasks a day, scaling is a non-issue; for fleet-wide operations, this package is the wrong tool and should be scoped to single-target or small-fan-out work.

Failure modes

  • Auth/connectivity: expired keys, rotated credentials, DNS changes, firewall changes — surface as opaque task failures unless the wrapper distinguishes exit codes from transport errors.
  • Partial execution: a non-idempotent script that fails halfway leaves remote state inconsistent and unrecoverable without a runbook. Enforce idempotency by convention and review.
  • Quoting/injection: dynamic values in Blade templates silently altering commands. This is the highest-severity failure mode because it can be both a correctness bug and a security incident. Mitigate with a lint rule or code-review checklist on any {{ }} inside a task template.
  • Timeout/kill: PHP process death mid-command orphans the remote process; the local runner reports nothing. Requires remote-side timeouts (timeout command) as a belt-and-braces measure.
  • Silent success: exit code captured but not checked by the caller. The wrapper must fail loudly on non-zero.
  • Log leakage: credentials echoed into captured output that lands in application logs.

Ramp-up API surface is small enough that a Laravel developer is productive in under a day. The real ramp-up cost is on the operations side: whoever reviews these tasks needs enough shell literacy to spot an unquoted variable or a missing set -e. Plan for a short internal guild session and a conventions doc; without it, the package becomes a way to ship unreviewed bash with a PHP veneer, which is worse than the status quo.

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