feat(versions): auto-check for updates on page load

The available-update banner + button now appear automatically when the page
opens, instead of only after clicking 'check'. autoCheck() runs via wire:init
(async, non-render-blocking) and no-ops while an update is in progress so it
never clobbers the running/poll state.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat/v1-foundation v0.9.14
boban 2026-06-19 19:22:53 +02:00
parent 6b5bc6938c
commit 07020a9ea0
5 changed files with 50 additions and 2 deletions

View File

@ -13,6 +13,16 @@ getaggte Releases (Kanal `stable`, optional `beta`) — niemals Entwicklungs-Bui
_Keine offenen Änderungen — der nächste Stand wird hier gesammelt und als `vX.Y.Z` getaggt._
## [0.9.14] - 2026-06-19
### Geändert
- **Updates werden beim Öffnen der Seite automatisch geprüft** (System → Version & Releases). Bisher
zeigte nur das Badge eine neuere Version; der „Jetzt aktualisieren"-Knopf erschien erst nach Klick
auf „Nach Updates suchen". Die Seite prüft jetzt direkt beim Laden selbst (asynchron via
`wire:init`, blockiert das Rendern nicht) und zeigt ein verfügbares Update samt Knopf sofort an —
kein manuelles Suchen mehr. Während eines laufenden Updates wird der Auto-Check übersprungen, damit
er den „läuft"-Zustand nicht überschreibt.
## [0.9.13] - 2026-06-19
### Behoben

View File

@ -124,6 +124,20 @@ class Index extends Component
}
}
/**
* Auto-check on page load (wire:init) so an available update + button appear without the
* operator clicking "check" first. No-op while an update is running, so it never clobbers the
* "läuft"/poll state. Async (wire:init), so it never blocks the initial render.
*/
public function autoCheck(): void
{
if ($this->updateRequested) {
return;
}
$this->checkUpdates();
}
/**
* Honest update check: compare the installed version against the newest release
* tag visible in the channel. No external server, no stars, no CVE feed.

View File

@ -2,7 +2,7 @@
return [
// First tagged release is v0.1.0 (semantic, not -dev).
'version' => '0.9.13',
'version' => '0.9.14',
// Deployed commit + branch. install.sh bakes these into .env from the host's .git (the prod
// image ships no .git); the Versions page prefers them and falls back to a live .git read in

View File

@ -22,7 +22,9 @@
$isUpdate = $updateState === 'update';
@endphp
<div class="space-y-5">
{{-- Auto-check for updates on load (async, non-blocking) so an available update + button show
without the operator clicking "check" first. autoCheck() no-ops while an update is running. --}}
<div class="space-y-5" wire:init="autoCheck">
{{-- Header --}}
<div class="flex flex-wrap items-end justify-between gap-3">
<div>

View File

@ -137,6 +137,28 @@ class VersionUpdateCheckTest extends TestCase
Livewire::test(Index::class)->assertViewHas('latestTag', null);
}
public function test_auto_check_on_load_surfaces_an_update_without_a_manual_click(): void
{
config()->set('clusev.version', '0.9.10');
Http::fake([self::TAGS_URL => Http::response([['name' => 'v0.9.13']])]);
Livewire::test(Index::class)
->call('autoCheck')
->assertSet('updateState', 'update')
->assertSee('0.9.13');
}
public function test_auto_check_does_not_run_while_an_update_is_in_progress(): void
{
Http::fake([self::TAGS_URL => Http::response([['name' => 'v0.9.13']])]);
Livewire::test(Index::class)
->set('updateRequested', true)
->call('autoCheck');
Http::assertNothingSent(); // guarded — never clobbers the running state
}
public function test_update_available_is_shown_on_load_without_clicking_check(): void
{
// The cached check (badge already knew) surfaces the update + button on mount, no re-click.