argws/laravel-updater
argws/laravel-updater is a Laravel package that adds update management to your application, offering a configurable workflow for checking, downloading, and applying updates. It follows Laravel conventions and is intended to simplify keeping installed apps current.
Caveat first: adoption signal is still thin (no stars/dependents data to speak of), but v0.1.223 arriving on top of v0.1.222 with 220+ PRs tells you something more useful than a star count: this is a fast-moving
0.1.xpackage where patch releases change behavior. Pin it exactly and treat every bump as a review item. Verify all claims below againstsrc/, the service provider, and the published config — the changelog is now the closest thing to documentation you have.
composer require argws/laravel-updater:0.1.223
php artisan vendor:publish --provider="Argws\Updater\UpdaterServiceProvider"
php artisan list | grep -i updat
Pin the exact patch (0.1.223, not ^0.1). In 0.1.x semver, ^0.1 accepts every patch, and this release proves patches carry behavioral flips — the kind you do not want arriving unattended on a Friday deploy.
Look at these in order:
config/updater.php — source URL, install path, enabled flags, and the automatic maintenance-mode flag (manutenção automática, likely maintenance / auto_maintenance). v0.1.223 changes its default to disabled; find the exact key name in the published file.updater:check, updater:update. Check for --pretend/--dry-run.exec, Process) to composer, git, rsync, curl, or uses Filesystem directly. This determines your whole trust model, and it tells you whether it can reload PHP-FPM or only swap files.First use case: a read-only check. Run the check command manually in a throwaway environment and confirm it (a) reaches the endpoint, (b) parses a version, (c) reports "no update" cleanly on a second run. The "corrige disponibilidade" line in this release suggests availability/reachability handling was recently fixed — so test the failure path too: point the manifest URL at a 500 and confirm it degrades to "unknown" rather than "update available".
Check-on-schedule, apply-on-demand. Split detection from mutation. Schedule the check nightly, notify a human, and let them run the apply command. In routes/console.php (Laravel 11+) or app/Console/Kernel.php:
Schedule::command('updater:check')->dailyAt('03:00')->onOneServer();
onOneServer() matters — without it a multi-server fleet attempts concurrent updates.
Own the maintenance-mode envelope yourself. As of v0.1.223 the package no longer puts the app into maintenance automatically, which is the right call for a library but means the protection is now your job. Wrap every apply:
Artisan::call('down', ['--render' => 'errors::503']);
try {
// backup DB, snapshot current release, run updater
Artisan::call('updater:update');
Artisan::call('migrate', ['--force' => true]);
Artisan::call('optimize:clear');
Artisan::call('queue:restart');
} finally {
Artisan::call('up');
}
The finally is not optional: with the package's own maintenance handling off by default, a thrown exception mid-update leaves the app up with a half-written vendor/ unless you guarantee the restore yourself.
Version manifest as the contract. Model it explicitly: { "version": "1.4.0", "released_at": "...", "download": "https://.../release.zip", "checksum": "sha256:..." }. Host it next to your release pipeline so it cannot drift from the artifact.
Stage before prod. Build a staging profile (different manifest URL, different target path), run updates there weekly, promote only versions you've exercised. With this release cadence, staging is also how you notice a patch release changed a default before your production box does.
Post-update hook. Hang config:cache, route:cache, view:cache, queue:restart, and a PHP-FPM reload off whatever post_update / after callback array the config exposes. Register them in config, not in your own code, so they fire for scheduler-triggered updates too.
Coordinate with your deployer, or don't use both. If Envoyer/Deployer/Kubernetes already owns releases, this package is a second writer to the same directory. Scope it to a single-tenant on-prem or single-VM install, or don't run it in a rolling-deploy cluster.
config/updater.php almost certainly hardcodes the old maintenance => true value from an earlier publish. After upgrading, diff your published config against vendor/.../config/updater.php and reconcile by hand (vendor:publish --force would clobber your customizations). Then decide deliberately: leave it off and use the wrapper above, or re-enable it and accept the package owning artisan down/up.composer outdated check plus a changelog skim to your upgrade routine; the one-line release notes are short enough that there's no excuse.vendor/ ends up owned by www-data and your next composer install as the deploy user fails. Run updates as the app owner; grant the web user read-only.opcache.validate_timestamps=1 with a short revalidate_freq, or reload PHP-FPM in the post-update hook. Symptom: version bumps, old behavior persists.composer install in the hook. If the package ships app code only, composer.lock and vendor/ drift. Include composer install --no-dev --optimize-autoloader, or you get class-not-found on newly referenced dependencies.config/updater.php after config:cache and your change is invisible — especially confusing now that a default changed upstream. Always php artisan config:clear before debugging why the updater ignores a setting.tar the release directory in your wrapper — don't assume it exists.-vvv and tail storage/logs/laravel.log; failures here are usually silent filesystem or HTTP errors. Check whether --pretend/--dry-run is honored; if not, guard against local-dev invocations clobbering your working tree.0 unconditionally — verify.How can I help you explore Laravel packages today?