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 Updater Laravel Package

salahhusa9/laravel-updater

Laravel Updater lets you update your Laravel project with a single command or click. Supports Laravel 11, 12, and 13, with an Artisan command and web interface for running updates, so deployments and version upgrades stay quick and painless.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install into a staging copy first, never production-first on day one.
    composer require salahhusa9/laravel-updater
    php artisan vendor:publish --tag="laravel-updater-config"
    
  2. Read config/updater.php before you run anything. This single file is the package: it holds your app's current version, the Git/repository settings the updater pulls from, and the before / after pipeline arrays that define what actually happens during an update. If a key name differs from what you expect, trust the published file over any blog post — the config has evolved across v1.x → v2.x.
  3. Confirm the command name in your installed version.
    php artisan list | grep -i update
    
    The command is the entry point for everything (CLI, scheduler, or a button in your admin panel).
  4. Where to look next, in order: the published config → the Updater service class (how it sequences pipelines) → Contracts/Pipeline (what a custom pipeline must implement) → CHANGELOG.md (the repo's only in-tree documentation; the real docs live at salahhusa9.com/laravel-updater).
  5. First use case: a staging server where main is the deploy branch. Run the update command once by hand, watch each pipeline step's output, and record the exact sequence. That output becomes your checklist for every later automation.

Implementation Patterns

Git-pull deploy behind a webhook. The intended pattern is: push to a release branch/tag → webhook hits your app → job runs the updater → pipelines run migrations, clear caches, restart workers. Wrap the call so failures surface:

use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Cache;

Cache::lock('app-update', 600)->block(5, function () {
    Artisan::call('update');            // use the signature you confirmed above
    Log::info('Update output', ['out' => Artisan::output()]);
});

Custom pipelines are where the package earns its keep. Write small, single-purpose classes implementing the package's pipeline contract — e.g. EnableMaintenanceMode, RunMigrations, ClearConfigCache, RestartHorizon, NotifySlackOnSuccess — then register them in the config's before/after arrays. Since v1.2.4 the updater merges your before/after pipelines with the package defaults, so you add steps without having to re-declare the built-ins. Keep the defaults and append; don't rewrite the array wholesale.

Order pipelines by blast radius. Before-update: maintenance mode on, snapshot/backup, stop queue workers. After-update: composer install --no-dev, migrations, config:cache/route:cache/view:cache, asset build if you build on-server, restart workers, maintenance mode off. Anything that writes config should come after anything that reads config.

Expose a version display, not just a command. Store the deployed version in config (or an env var) and surface it in your admin footer/health page. It turns "did the update land?" into a one-glance check and gives you a cheap cache-buster key for the frontend.

Treat pipelines as idempotent steps. Each one will eventually be re-run after a partial failure, so migrate over migrate:fresh, cache:clear over manual deletes, and no "create this record" logic that can't be repeated safely.

Test pipelines locally. You can't safely exercise the git pull on your laptop, but you can instantiate and call your pipeline classes directly in a feature test, and you can run the full command against a disposable staging checkout. Do both before wiring the webhook.

Gotchas and Tips

  • The updater throws away local modifications (v1.2.0). It performs a git checkout/reset as part of the update. Any hotfix someone edited directly on the server is gone — silently. Treat the deployed checkout as read-only, and put that rule in your runbook in bold.
  • It shells out, so the server needs the tools in PATH. Git, composer, php, and (if your pipelines use them) npm/node must all resolve without a login shell. Since v1.2.1 the package no longer uses Symfony's executable finder, so a binary that only exists in a user's .bashrc will fail under www-data/forge/cron. Verify with sudo -u www-data which git composer.
  • Non-interactive only. Git must not prompt for credentials (deploy key or token in the remote URL/credential helper), and Composer must not prompt auth. Test as the web/cron user, not as yourself.
  • Pipelines run in-process. A heavy step (asset build, big migration) can hit max_execution_time or PHP memory limits, and a timeout mid-pipeline leaves the app in a half-updated state. There is no transactional rollback — mitigate with maintenance mode around the whole run and a manual verification step afterward.
  • Don't expose the artisan call on a public route. If you build an admin "Update now" button, put it behind auth + authorization + CSRF, and ideally a queued job with a cache lock so two admins can't trigger concurrent updates.
  • Config-cache ordering bites. If the app boots with a cached config, your edited pipelines won't run until config:cache is rebuilt. Never place config:cache in the before list, and remember the running PHP process has already loaded the old config for the current request.
  • Failures are RuntimeExceptions (v1.0.1). Catch them explicitly around Artisan::call, log Artisan::output() for context, and return a non-zero exit code from any wrapping command so CI/schedulers notice.
  • Version-pin against your framework. v2.0.0 adds Laravel 13 while keeping 11/12; v1.x tops out earlier. A stray composer update across a major version is an infrastructure change, not a dependency bump — pin with a caret and review the CHANGELOG.md before crossing majors.
  • Prefer a release/* branch or tag over main. Updating from a moving branch means the "same" command produces different results on every run. Point the updater at something immutable per deploy and you keep the ability to say what's actually running.
  • The README is a pointer, not a manual. README/changelog is thin; the external docs site is the real reference. Read your installed config file alongside it — the config is the ground truth for the version you actually have.
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.
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table