Updates
Check for published Signals releases and install them in place from the owner-only Updates page.
Overview
Updates lets the account owner see which Signals release is installed, which releases are published, and install a newer one in place — Composer download, migrations, cache clear, and queue restart run as one observable job behind maintenance mode.
Self-hosted installations only. Signals Cloud installations are updated for you.
Where it lives
Route: /admin/settings/system (admin.settings.system)
Open Admin → System → Updates. Mount and every action require the owner gate.
Installed version
The installed version is config('signals.version') — the single source of truth, bumped in lockstep with each tagged release. It is compared against the published releases with version_compare().
Checking for releases
App\Services\Updates\ReleaseChecker reads the static Packagist p2 metadata feed for signals-rental/framework:
| Behaviour | Detail |
|---|---|
| Source | signals.updates.metadata_url — https://repo.packagist.org/p2/signals-rental/framework.json |
| Cache | Cache key updates:releases, one hour |
| Filtering | Only fully stable X.Y.Z tags; dev branches and -RC / -beta / -alpha pre-releases are dropped |
| Ordering | Newest first; the newest release above the installed version is the one offered |
| Failure | Every failure path (connection, non-2xx, unexpected payload) logs a warning and degrades to "no releases known" — an unreachable Packagist never breaks the page |
Check again forgets the cached metadata and fetches immediately. When nothing can be retrieved the page says so and offers no install button.
Each row links to the release notes at https://docs.signals.rent/changelog/{version} (base URL: signals.updates.release_notes_url).
Installing an update
Install update confirms, then queues App\Jobs\RunSignalsUpdateJob on the default queue. The job re-validates that the requested version is a published release newer than the installed one — the button is not the gate — and then runs six linear steps:
| Step | Command |
|---|---|
| 1 | php artisan down --secret={random} — maintenance mode with a bypass secret |
| 2 | composer require signals-rental/framework:{version} --update-with-all-dependencies --no-interaction --no-ansi |
| 3 | php artisan migrate --force |
| 4 | php artisan optimize:clear |
| 5 | php artisan queue:restart |
| 6 | php artisan up |
If any step fails, the job lifts maintenance mode again on a best-effort basis, records the failing step, and fails the run — a failed upgrade must never leave the installation dark. The job runs once (tries = 1) with a 30-minute timeout, long enough for Composer resolution plus migrations.
Watching the run
The progress card polls every two seconds while a run is active and shows:
- the current step, its message, and a progress bar (step n of 6)
- the maintenance bypass link (
{app-url}/{secret}) so the owner can keep using the site while it is down for everyone else - Show update output — the captured Composer and Artisan console output, capped at the last 64KB
Progress lives in the cache under job-progress:RunSignalsUpdateJob:{runId} for one hour, following the framework's standard job-progress key convention (see Caching).
The page gives up rather than polling forever:
| Situation | Behaviour |
|---|---|
| Queued for 15s | Warns that it is still waiting for a worker |
| Queued for 120s | Abandons the run and tells you to start php artisan queue:work |
| Running past the job's timeout + 5 min | Abandons the run — the worker was most likely killed; check the logs and site status before retrying |
| Progress entry missing | Abandons the run (the cache was cleared, or the worker was killed) |
On success the card reports the new version and asks you to reload so the new build is picked up.
Updating from the command line
Self-hosted operators can run the whole upgrade from a shell on the machine itself — no queue worker, no browser:
php artisan signals:update
The command prints the installed version and the published releases, says whether an update is available, and asks for confirmation before installing the newest one. It then runs the same six steps in the same order as the queued job — App\Services\Updates\UpdateRunner is shared by both — synchronously, streaming Composer and Artisan output straight to your terminal.
| Option | Behaviour |
|---|---|
--check |
List the releases and exit without prompting. Exit code 0 when an update is available, 1 when already up to date — scriptable for cron or monitoring |
--to=X.Y.Z |
Install a specific published release instead of the latest. A leading v is accepted |
--force |
Skip the confirmation prompt (for unattended runs) |
--no-refresh |
Use the cached release feed instead of re-fetching it from Packagist |
Behaviour worth knowing:
- Same validation as the job. Anything that is not a published stable release newer than the installed version — an older tag, an unknown tag, a dev branch — is refused before maintenance mode is engaged.
- Same lock. The command contends for the
signals-updatelock the queued job uses, so a CLI run and an admin-page run can never overlap; whichever starts second refuses with "a Signals update is already running". - Same recovery. If any step fails the command lifts maintenance mode again on a best-effort basis, reports the failing step, and exits 1.
- Run it as the user that owns
vendor/andcomposer.lock, withcomposeron thePATH.
Requirements
- A queue worker must be consuming the
defaultqueue; without one the run is abandoned after two minutes. composermust be on the web/queue user'sPATH, and that user needs write access tovendor/andcomposer.lock.- The server must be able to reach
repo.packagist.org. - Take a database backup before installing; the update runs migrations and does not roll them back.