feat(release): wire the live pipeline + test-server setting into the page
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>feat/v1-foundation
parent
070c6646f3
commit
0ac819e4ad
|
|
@ -3,6 +3,8 @@
|
|||
namespace App\Livewire\Release;
|
||||
|
||||
use App\Models\AuditEvent;
|
||||
use App\Models\Setting;
|
||||
use App\Services\PipelineStatus;
|
||||
use App\Services\ReleaseBridge;
|
||||
use App\Services\ReleasePlanner;
|
||||
use App\Support\Confirm\ConfirmToken;
|
||||
|
|
@ -38,9 +40,14 @@ class Index extends Component
|
|||
/** The tag of the last successfully-pushed staging beta (shown until the next deploy). */
|
||||
public ?string $lastTag = null;
|
||||
|
||||
/** The configured test-server URL (bound to the inline input). */
|
||||
public string $testServer = '';
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
abort_unless((bool) config('clusev.release_controls'), 404);
|
||||
|
||||
$this->testServer = (string) Setting::get('pipeline_test_server', '');
|
||||
}
|
||||
|
||||
/** Opens the wire-elements/modal confirm dialog (R5) before cutting a staging beta of $target. */
|
||||
|
|
@ -147,6 +154,34 @@ class Index extends Component
|
|||
$this->reset(['pendingId', 'pendingSince', 'pendingTarget']);
|
||||
}
|
||||
|
||||
/** wire:poll target while the pipeline is in flight — drops the cached step results so the next
|
||||
* render re-fetches the live GitHub/test-server status. */
|
||||
public function pollPipeline(PipelineStatus $pipeline): void
|
||||
{
|
||||
$pipeline->refresh();
|
||||
}
|
||||
|
||||
/** Save (or clear) the test-server URL whose /version.json the pipeline polls. */
|
||||
public function saveTestServer(string $url): void
|
||||
{
|
||||
$url = trim($url);
|
||||
if ($url === '') {
|
||||
Setting::put('pipeline_test_server', '');
|
||||
$this->testServer = '';
|
||||
$this->dispatch('notify', message: __('release.test_server_cleared'));
|
||||
|
||||
return;
|
||||
}
|
||||
if (filter_var($url, FILTER_VALIDATE_URL) === false || ! preg_match('#^https?://#i', $url)) {
|
||||
$this->dispatch('notify', message: __('release.test_server_invalid'), level: 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
Setting::put('pipeline_test_server', $url);
|
||||
$this->testServer = $url;
|
||||
$this->dispatch('notify', message: __('release.test_server_saved'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the shared ConfirmAction modal (R5) for the staging release. The issued token carries NO
|
||||
* audit descriptor — applyDeployStaging → deployStaging audits exactly once itself.
|
||||
|
|
@ -176,6 +211,7 @@ class Index extends Component
|
|||
return view('livewire.release.index', [
|
||||
'current' => $current,
|
||||
'targets' => app(ReleasePlanner::class)->proposedTargets($current),
|
||||
'pipeline' => app(PipelineStatus::class)->forTrackedBeta(),
|
||||
])->title(__('release.title'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,4 +96,39 @@ class ReleasePageTest extends TestCase
|
|||
config()->set('clusev.release_controls', false);
|
||||
Livewire::test(Index::class)->assertStatus(404);
|
||||
}
|
||||
|
||||
public function test_render_includes_the_live_pipeline_for_a_beta(): void
|
||||
{
|
||||
config()->set('clusev.version', '0.9.61-beta1');
|
||||
config()->set('clusev.staging_slug', ''); // degrade: no GitHub calls
|
||||
config()->set('clusev.github_token', '');
|
||||
|
||||
Livewire::test(Index::class)
|
||||
->assertViewHas('pipeline', fn ($p) => is_array($p) && $p['tag'] === 'v0.9.61-beta1');
|
||||
}
|
||||
|
||||
public function test_render_pipeline_is_null_for_a_stable_version(): void
|
||||
{
|
||||
config()->set('clusev.version', '0.9.60');
|
||||
Livewire::test(Index::class)->assertViewHas('pipeline', null);
|
||||
}
|
||||
|
||||
public function test_save_test_server_persists_a_valid_url(): void
|
||||
{
|
||||
Livewire::test(Index::class)->call('saveTestServer', 'http://staging.local');
|
||||
$this->assertSame('http://staging.local', \App\Models\Setting::get('pipeline_test_server'));
|
||||
}
|
||||
|
||||
public function test_save_test_server_rejects_a_bad_url(): void
|
||||
{
|
||||
Livewire::test(Index::class)->call('saveTestServer', 'not-a-url');
|
||||
$this->assertNull(\App\Models\Setting::get('pipeline_test_server'));
|
||||
}
|
||||
|
||||
public function test_save_test_server_empty_clears_it(): void
|
||||
{
|
||||
\App\Models\Setting::put('pipeline_test_server', 'http://staging.local');
|
||||
Livewire::test(Index::class)->call('saveTestServer', '');
|
||||
$this->assertSame('', (string) \App\Models\Setting::get('pipeline_test_server', ''));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue