sandermuller/boost-pipeline
A Laravel package for building and running pipelines composed of reusable stages. It helps organize multi-step application logic into clear, testable flows that are easier to maintain and extend.
Minimum viable setup:
composer require sandermuller/boost-pipeline --dev (it is a workflow/agent-orchestration tool, not a runtime dependency of your app).config/pipeline.php first. As of v0.22.0 this file is load-bearing: a config that uses Shell::exclusive() without a withResponseWindow() policy is refused at load, so validate the config before you debug anything else.php artisan pipeline:history — it is the cheapest smoke test that the package is wired up, and it is also the primary observability surface you will live in day to day (there is a corresponding UI page that renders the same run data).First use case: define a single Shell step, run it, and watch it in pipeline:history. Do not start with a multi-step pipeline; you want to see one step's duration_ms land in the history output before you add branching, because that confirms your run/step persistence and your next_step contract are both working.
Where to look first in the codebase: the step definition API (Shell::…), the next_step resolver, and the history command/page. Those three cover 90% of day-to-day work.
Step authoring with cleanup. Shell::onAbort('<cmd>') gives you a real cleanup hook for the first time — previously a timed-out step left debris behind. Pair it with every step that writes to a scratch directory, holds a lock file, or starts a long-lived child process. Treat it as a finally block, not as an error handler: it fires on timeout and on stop, not on ordinary non-zero exits.
Serialising shared resources. Shell::exclusive('name', $capacity) is the correct tool when steps contend for something machine-wide — a database, a port, a browser, a build cache, an npm lockfile. Name the resource, set the capacity to the actual number of concurrent holders the resource tolerates (not the number of CPUs), and let the scheduler queue the rest. This replaces hand-rolled flock/lock-file code inside step commands.
Agent-loop integration. next_step reporting waiting_for_slot is the signal your driver loop should treat as "poll again, do not fail". Build your loop to distinguish three outcomes: a step to run, waiting_for_slot (sleep and re-ask), and terminal — including the new abandoned status, which means no further walking will happen and the loop must exit rather than retry.
Run hygiene across deploys. open_run now refuses once vendor/composer/installed.php has changed, and asks for a reconnect. This is a deliberate safety rail: a half-finished run whose step code has been swapped underneath it produces nonsense. If you run pipelines from a queue worker or a long-lived container, plan for the refusal — catch it, tear the run down, and reconnect rather than retrying open_run in a tight loop.
Cost and latency accounting. Persist duration_ms and slot_wait_ms from step results into your own metrics. They answer different questions: duration_ms is what the step cost, slot_wait_ms is what your exclusive() capacity setting cost you. If slot_wait_ms dominates, your capacity is too low or your resource name is too coarse.
exclusive() without withResponseWindow() is a hard load failure. This is the single most likely upgrade breakage. Audit every pipeline definition for exclusive() before deploying v0.22.0; the failure is at config load, so it will take down anything that boots the package, not just the offending pipeline.onAbort-adjacent lifecycle you control.waiting_for_slot time is excluded from the step's timeout. If a step is timing out, the cause is inside the step, never the queue — do not "fix" a timeout by raising capacity.abandoned is not failed. It means nobody will walk the run further. Alerts, dashboards, and retry logic written against v0.21.0 will silently miss these runs; add the case explicitly to anything that enumerates run statuses.open_run starts refusing after a composer update or a container rebuild, that is the guard working. Debugging tip: check vendor/composer/installed.php mtime against the run's start time before you go looking at the queue or the filesystem.exclusive() yourself.How can I help you explore Laravel packages today?