Merge remote-tracking branch 'origin/next' into audit-policies

This commit is contained in:
Andras Bacsai committed 2026-05-13 11:15:29 +02:00
commit 6ab88c46b2
66 files changed
+2155 -792

No files matched your search

@@ -4,6 +4,8 @@ namespace App\Livewire\Project\Application;
use App\Models\Application;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;
use Livewire\Attributes\Validate;
use Livewire\Component;
@@ -61,6 +63,9 @@ class Advanced extends Component
#[Validate(['string', 'nullable'])]
public ?string $gpuOptions = null;
#[Validate(['string', 'nullable'])]
public ?string $stopGracePeriod = null;
#[Validate(['boolean'])]
public bool $isBuildServerEnabled = false;
@@ -145,6 +150,10 @@ class Advanced extends Component
$this->injectBuildArgsToDockerfile = $this->application->settings->inject_build_args_to_dockerfile ?? true;
$this->includeSourceCommitInBuild = $this->application->settings->include_source_commit_in_build ?? false;
}
// Load stop_grace_period separately since it has its own save handler
// Convert null to empty string to prevent dirty detection issues
$this->stopGracePeriod = $this->application->settings->stop_grace_period ?? '';
}
private function resetDefaultLabels()
@@ -210,6 +219,7 @@ class Advanced extends Component
}
$this->syncData(true);
$this->dispatch('success', 'Settings saved.');
$this->dispatch('configurationChanged');
} catch (\Throwable $e) {
return handleError($e, $this);
}
@@ -228,6 +238,7 @@ class Advanced extends Component
if (is_null($this->customInternalName)) {
$this->syncData(true);
$this->dispatch('success', 'Custom name saved.');
$this->dispatch('configurationChanged');
return;
}
@@ -247,6 +258,32 @@ class Advanced extends Component
}
$this->syncData(true);
$this->dispatch('success', 'Custom name saved.');
$this->dispatch('configurationChanged');
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
public function saveStopGracePeriod()
{
try {
$this->authorize('update', $this->application);
$validated = Validator::make(
['stopGracePeriod' => $this->stopGracePeriod === '' ? null : $this->stopGracePeriod],
['stopGracePeriod' => ['nullable', 'integer', 'min:'.MIN_STOP_GRACE_PERIOD_SECONDS, 'max:'.MAX_STOP_GRACE_PERIOD_SECONDS]],
[],
['stopGracePeriod' => 'stop grace period']
)->validate();
$this->application->settings->stop_grace_period = $validated['stopGracePeriod'] === null
? null
: (int) $validated['stopGracePeriod'];
$this->application->settings->save();
$this->dispatch('success', 'Stop grace period updated.');
} catch (ValidationException $e) {
throw $e;
} catch (\Throwable $e) {
return handleError($e, $this);
}
@@ -345,10 +345,11 @@ class Previews extends Component
private function stopContainers(array $containers, $server)
{
$containersToStop = collect($containers)->pluck('Names')->toArray();
$timeout = $this->application->settings->stopGracePeriodSeconds();
foreach ($containersToStop as $containerName) {
instant_remote_process(command: [
"docker stop -t 30 $containerName",
"docker stop --time=$timeout $containerName",
"docker rm -f $containerName",
], server: $server, throwError: false);
}
@@ -109,6 +109,7 @@ class Source extends Component
$this->application->refresh();
$this->privateKeyName = $this->application->private_key->name;
$this->dispatch('success', 'Private key updated!');
$this->dispatch('configurationChanged');
} catch (\Throwable $e) {
return handleError($e, $this);
}
@@ -124,6 +125,7 @@ class Source extends Component
}
$this->syncData(true);
$this->dispatch('success', 'Application source updated!');
$this->dispatch('configurationChanged');
} catch (\Throwable $e) {
return handleError($e, $this);
}
@@ -12,15 +12,20 @@ use App\Models\StandaloneMongodb;
use App\Models\StandaloneMysql;
use App\Models\StandalonePostgresql;
use App\Models\StandaloneRedis;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class ConfigurationChecker extends Component
{
public bool $isConfigurationChanged = false;
public array $configurationDiff = [];
public array $groupedConfigurationChanges = [];
public Application|Service|StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|StandaloneKeydb|StandaloneDragonfly|StandaloneClickhouse $resource;
public function getListeners()
public function getListeners(): array
{
$teamId = auth()->user()->currentTeam()->id;
@@ -30,18 +35,36 @@ class ConfigurationChecker extends Component
];
}
public function mount()
public function mount(): void
{
$this->configurationChanged();
}
public function render()
public function render(): View
{
return view('livewire.project.shared.configuration-checker');
}
public function configurationChanged()
public function refreshConfigurationChanges(): void
{
$this->configurationChanged();
}
public function configurationChanged(): void
{
$this->resource->refresh();
if ($this->resource instanceof Application) {
$diff = $this->resource->pendingDeploymentConfigurationDiff();
$this->isConfigurationChanged = $diff->isChanged();
$this->configurationDiff = $diff->toArray();
$this->groupedConfigurationChanges = $diff->groupedChanges();
return;
}
$this->isConfigurationChanged = $this->resource->isConfigurationChanged();
$this->configurationDiff = [];
$this->groupedConfigurationChanges = [];
}
}