mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
fix(previews): key docker tags by preview id so a delete cannot shift them
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
f1ab9956e8
commit
5f460c06c6
@@ -80,8 +80,8 @@ class Previews extends Component
|
||||
private function syncDockerTags(): void
|
||||
{
|
||||
$this->previewDockerTags = [];
|
||||
foreach ($this->application->previews as $key => $preview) {
|
||||
$this->previewDockerTags[$key] = $preview->docker_registry_image_tag;
|
||||
foreach ($this->application->previews as $preview) {
|
||||
$this->previewDockerTags[$preview->id] = $preview->docker_registry_image_tag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,16 +118,8 @@ class Previews extends Component
|
||||
throw new \Exception('Preview not found');
|
||||
}
|
||||
|
||||
$previewKey = $this->application->previews->search(function ($item) use ($preview_id) {
|
||||
return $item->id == $preview_id;
|
||||
});
|
||||
|
||||
if ($previewKey === false) {
|
||||
throw new \Exception('Preview not found');
|
||||
}
|
||||
|
||||
$this->validateOnly("previewDockerTags.{$previewKey}");
|
||||
$preview->docker_registry_image_tag = $this->previewDockerTags[$previewKey] ?? null;
|
||||
$this->validateOnly("previewDockerTags.{$preview->id}");
|
||||
$preview->docker_registry_image_tag = $this->previewDockerTags[$preview->id] ?? null;
|
||||
$changedFields = $preview->isDirty('docker_registry_image_tag') ? ['docker_registry_image_tag'] : [];
|
||||
$preview->save();
|
||||
if ($changedFields !== []) {
|
||||
@@ -385,6 +377,7 @@ class Previews extends Component
|
||||
|
||||
// Refresh the application and its previews relationship to reflect the soft delete
|
||||
$this->application->load('previews');
|
||||
unset($this->previewDockerTags[$preview->id]);
|
||||
$this->dispatch('update_links');
|
||||
$this->dispatch('success', 'Preview deletion started. It may take a few moments to complete.');
|
||||
} catch (\Throwable $e) {
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
|
||||
<x-application.settings-section id="preview-deployments-section" title="Preview deployments"
|
||||
helper="Manage domains, deployments, logs, and lifecycle actions for configured previews." flush>
|
||||
@forelse (data_get($application, 'previews') as $previewName => $preview)
|
||||
@forelse (data_get($application, 'previews') as $preview)
|
||||
@php
|
||||
$previewStatus = str(data_get($preview, 'status'));
|
||||
$previewIsStopped = $previewStatus->startsWith('exited');
|
||||
@@ -298,7 +298,7 @@
|
||||
class="application-settings-section-body is-flush mt-3 overflow-visible">
|
||||
<div class="data-table-header grid-cols-1"><span>Docker tag</span></div>
|
||||
<div class="p-3">
|
||||
<x-forms.input id="previewDockerTags.{{ $previewName }}" canGate="update"
|
||||
<x-forms.input id="previewDockerTags.{{ $preview->id }}" canGate="update"
|
||||
:canResource="$application"
|
||||
wire:change="save_preview('{{ $preview->id }}')" />
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
use App\Livewire\Project\Application\Previews;
|
||||
use App\Models\Application;
|
||||
use App\Models\ApplicationPreview;
|
||||
use App\Models\Environment;
|
||||
use App\Models\GitlabApp;
|
||||
use App\Models\InstanceSettings;
|
||||
@@ -12,6 +13,7 @@ use App\Models\StandaloneDocker;
|
||||
use App\Models\Team;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Queue;
|
||||
use Illuminate\Support\Str;
|
||||
use Livewire\Livewire;
|
||||
|
||||
@@ -159,3 +161,17 @@ it('denies preview setting changes without application update permission', funct
|
||||
->is_preview_deployments_enabled->toBeFalse()
|
||||
->is_pr_deployments_public_enabled->toBeFalse();
|
||||
})->with([['member', false], ['owner', true]]);
|
||||
|
||||
it('saves the docker tag of the remaining preview after another preview is deleted', function () {
|
||||
$this->application->update(['build_pack' => 'dockerimage']);
|
||||
$previewA = ApplicationPreview::create(['application_id' => $this->application->id, 'pull_request_id' => 2, 'pull_request_html_url' => '', 'docker_registry_image_tag' => 'tag-a']);
|
||||
$previewB = ApplicationPreview::create(['application_id' => $this->application->id, 'pull_request_id' => 1, 'pull_request_html_url' => '', 'docker_registry_image_tag' => 'tag-b']);
|
||||
Queue::fake();
|
||||
|
||||
Livewire::test(Previews::class, ['application' => $this->application->fresh()])
|
||||
->call('delete', 2)
|
||||
->call('save_preview', $previewB->id)
|
||||
->assertHasNoErrors();
|
||||
|
||||
expect($previewB->fresh()->docker_registry_image_tag)->toBe('tag-b');
|
||||
});
|
||||
|
||||
@@ -127,7 +127,7 @@ it('audits adding, retagging and deleting a preview', function () {
|
||||
->and($created->first()->metadata['pull_request_id'])->toBe(42)
|
||||
->and($created->first()->resource_uuid)->toBe($this->application->uuid);
|
||||
|
||||
$component->set('previewDockerTags.0', 'pr-42')
|
||||
$component->set('previewDockerTags.'.ApplicationPreview::query()->where('pull_request_id', 42)->value('id'), 'pr-42')
|
||||
->call('save_preview', ApplicationPreview::query()->where('pull_request_id', 42)->value('id'));
|
||||
|
||||
$updated = applicationSettingsAuditEvents('ui.application.preview_updated');
|
||||
|
||||
Reference in New Issue
Block a user