fix(domains): close edit modal after save and drop Lima seeds

Dispatch edit-domain-saved so Alpine closes the domain edit modal,
wire Save to updateDomain, and force white active log toolbar text in
dark mode. Seed railpack examples on the local Docker destination only
and remove Lima servers, environments, and V5DevLimaSeeder.
This commit is contained in:
Andras Bacsai 2026-08-06 13:45:19 +02:00
parent bb83c1e3be
commit 9fd2a21f24
17 changed files with 116 additions and 402 deletions

View file

@ -1039,6 +1039,7 @@ public function updateDomain(): void
$this->forceSaveDomains = false;
$this->pendingAction = null;
$this->cancelEdit();
$this->dispatch('edit-domain-saved');
$this->dispatch('success', 'Domain updated.');
$this->refreshDomains();
$this->checkUrlsDns([$newUrl], $service);

View file

@ -964,6 +964,7 @@ public function updateDomain(): void
}
$this->cancelEdit();
$this->dispatch('edit-domain-saved');
$this->forceSaveDomains = false;
$this->forceRemovePort = false;
$this->pendingAction = null;

View file

@ -35,7 +35,6 @@ public function run(): void
if (in_array(config('app.env'), ['local', 'development', 'dev'], true)) {
$this->call([
DevelopmentRailpackExamplesSeeder::class,
V5DevLimaSeeder::class,
]);
}
}

View file

@ -26,27 +26,6 @@ class DevelopmentRailpackExamplesSeeder extends Seeder
public const REPOSITORY_PROJECT_ID = 603035348;
public const LIMA_SERVERS = [
[
'server_uuid' => 'lima-ubuntu-2404',
'server_name' => 'lima-ubuntu-2404',
'port' => 2222,
'environment_name' => 'ubuntu24',
'environment_uuid' => 'railpack-examples-ubuntu24',
'uuid_prefix' => 'ubuntu24-',
],
[
'server_uuid' => 'lima-ubuntu-2604',
'server_name' => 'lima-ubuntu-2604',
'port' => 2223,
'environment_name' => 'ubuntu26',
'environment_uuid' => 'railpack-examples-ubuntu26',
'uuid_prefix' => 'ubuntu26-',
],
];
private const LIMA_SENTINEL_URL = 'http://host.lima.internal:8000';
public function run(): void
{
if (! $this->isDevelopmentEnvironment()) {
@ -64,15 +43,7 @@ public function run(): void
$this->cleanupLegacyLimaProjects();
$this->cleanupLegacyProductionExamples();
foreach (self::LIMA_SERVERS as $limaServer) {
$this->seedEnvironment(
environmentUuid: $limaServer['environment_uuid'],
environmentName: $limaServer['environment_name'],
destination: $this->limaDestination($limaServer['server_uuid']),
uuidPrefix: $limaServer['uuid_prefix'],
nameSuffix: " ({$limaServer['environment_name']})",
);
}
$this->seedEnvironment(StandaloneDocker::query()->findOrFail(0));
}
/**
@ -465,37 +436,6 @@ private function ensureDevelopmentPrerequisitesExist(): void
],
);
foreach (self::LIMA_SERVERS as $limaServer) {
$server = Server::query()->firstOrCreate(
['uuid' => $limaServer['server_uuid']],
[
'name' => $limaServer['server_name'],
'description' => 'This is a Lima VM for local development testing',
'ip' => 'host.docker.internal',
'port' => $limaServer['port'],
'team_id' => 0,
'private_key_id' => 1,
'proxy' => [
'type' => ProxyTypes::TRAEFIK->value,
'status' => ProxyStatus::EXITED->value,
],
],
);
$server->settings->forceFill([
'sentinel_custom_url' => self::LIMA_SENTINEL_URL,
])->saveQuietly();
StandaloneDocker::query()->firstOrCreate(
['server_id' => $server->id],
[
'uuid' => "{$limaServer['server_uuid']}-docker",
'name' => "{$limaServer['server_name']} Docker",
'network' => 'coolify',
],
);
}
StandaloneDocker::query()->firstOrCreate(
['id' => 0],
[
@ -545,21 +485,6 @@ private function isDevelopmentEnvironment(): bool
return in_array(config('app.env'), ['local', 'development', 'dev'], true);
}
private function limaDestination(string $serverUuid): StandaloneDocker
{
$limaDestination = Server::query()
->where('uuid', $serverUuid)
->first()
?->standaloneDockers()
->first();
if (! $limaDestination) {
throw new RuntimeException("Lima StandaloneDocker destination is required for {$serverUuid} before running DevelopmentRailpackExamplesSeeder.");
}
return $limaDestination;
}
private function cleanupLegacyLimaProjects(): void
{
Project::query()
@ -595,21 +520,16 @@ private function cleanupLegacyProductionExamples(): void
->forceDelete();
}
private function seedEnvironment(
string $environmentUuid,
string $environmentName,
StandaloneDocker $destination,
string $uuidPrefix = '',
string $nameSuffix = '',
): void {
$environment = $this->prepareEnvironment($environmentUuid, $environmentName);
private function seedEnvironment(StandaloneDocker $destination): void
{
$environment = $this->prepareEnvironment();
foreach (self::examples() as $example) {
$this->upsertApplication($environment, $destination, $example, $uuidPrefix, $nameSuffix);
$this->upsertApplication($environment, $destination, $example);
}
}
private function prepareEnvironment(string $environmentUuid, string $environmentName): Environment
private function prepareEnvironment(): Environment
{
$project = Project::query()->firstOrNew(['uuid' => self::PROJECT_UUID]);
$project->fill([
@ -619,31 +539,20 @@ private function prepareEnvironment(string $environmentUuid, string $environment
]);
$project->save();
$environment = $project->environments()
->where(function ($query) use ($environmentName, $environmentUuid): void {
$query
->where('name', $environmentName)
->orWhere('uuid', $environmentUuid);
})
->first();
$environment = $project->environments()->firstOrCreate(['name' => 'production']);
$existingEnvironment = $project->environments()->first();
$project->environments()
->whereKeyNot($environment->id)
->get()
->each(function (Environment $obsoleteEnvironment): void {
Application::withTrashed()
->where('environment_id', $obsoleteEnvironment->id)
->get()
->each
->forceDelete();
if (! $environment && $project->environments()->count() === 1 && $existingEnvironment?->name === 'production') {
$environment = $existingEnvironment;
}
if (! $environment) {
$environment = $project->environments()->create([
'name' => $environmentName,
'uuid' => $environmentUuid,
]);
} else {
$environment->update([
'name' => $environmentName,
'uuid' => $environmentUuid,
]);
}
$obsoleteEnvironment->delete();
});
return $environment;
}
@ -651,10 +560,10 @@ private function prepareEnvironment(string $environmentUuid, string $environment
/**
* @param array<string, mixed> $example
*/
private function upsertApplication(Environment $environment, StandaloneDocker $destination, array $example, string $uuidPrefix = '', string $nameSuffix = ''): void
private function upsertApplication(Environment $environment, StandaloneDocker $destination, array $example): void
{
$uuid = $uuidPrefix.$example['uuid'];
$name = $example['name'].$nameSuffix;
$uuid = $example['uuid'];
$name = $example['name'];
$application = Application::withTrashed()->firstOrNew(['uuid' => $uuid]);
$application->fill([
'name' => $name,

View file

@ -7,28 +7,13 @@
class ProjectSeeder extends Seeder
{
private const LIMA_ENVIRONMENTS = [
['name' => 'ubuntu24', 'uuid' => 'ubuntu24'],
['name' => 'ubuntu26', 'uuid' => 'ubuntu26'],
];
public function run(): void
{
$project = Project::create([
Project::create([
'uuid' => 'project',
'name' => 'My first project',
'description' => 'This is a test project in development',
'team_id' => 0,
]);
foreach (self::LIMA_ENVIRONMENTS as $index => $environment) {
if ($index === 0) {
$project->environments()->first()->update($environment);
continue;
}
$project->environments()->create($environment);
}
}
}

View file

@ -9,13 +9,6 @@
class ServerSeeder extends Seeder
{
private const LIMA_SENTINEL_URL = 'http://host.lima.internal:8000';
private const LIMA_SERVERS = [
['uuid' => 'lima-ubuntu-2404', 'name' => 'lima-ubuntu-2404', 'port' => 2222],
['uuid' => 'lima-ubuntu-2604', 'name' => 'lima-ubuntu-2604', 'port' => 2223],
];
public function run(): void
{
Server::create([
@ -31,25 +24,5 @@ public function run(): void
'status' => ProxyStatus::EXITED->value,
],
]);
foreach (self::LIMA_SERVERS as $limaServer) {
$server = Server::create([
'uuid' => $limaServer['uuid'],
'name' => $limaServer['name'],
'description' => 'This is a Lima VM for local development testing',
'ip' => 'host.docker.internal',
'port' => $limaServer['port'],
'team_id' => 0,
'private_key_id' => 1,
'proxy' => [
'type' => ProxyTypes::TRAEFIK->value,
'status' => ProxyStatus::EXITED->value,
],
]);
$server->settings->forceFill([
'sentinel_custom_url' => self::LIMA_SENTINEL_URL,
])->saveQuietly();
}
}
}

View file

@ -2692,6 +2692,10 @@ .logs-viewer-btn-active {
color: #fff;
}
.dark .logs-viewer-btn-active {
color: #fff;
}
.logs-viewer-viewport {
min-width: 0;
padding: 0.5rem 0.75rem;

View file

@ -38,7 +38,8 @@
$wire.showEditDomainModal = true;
},
}"
@open-edit-domain.window="openEditDomain($event.detail.index, $event.detail.url, $event.detail.service)">
@open-edit-domain.window="openEditDomain($event.detail.index, $event.detail.url, $event.detail.service)"
@edit-domain-saved.window="closeEditDomain()">
<x-application.settings-section id="domains-section" title="Domains" :helper="$helperText">
@can('update', $application)
<x-slot:actions>
@ -368,16 +369,13 @@ class="icon-button shrink-0" aria-label="Close">
@endif
<div class="flex flex-wrap items-center justify-end gap-2 pt-2">
<x-forms.button type="button" @click="closeEditDomain()">
Cancel
</x-forms.button>
@if ($editDomainDnsFailed)
<x-forms.button type="button" isError
@click="prepareEditSubmit(); $wire.forceSaveEditDns = true; $wire.confirmUpdateDomainDespiteDns()">
Continue
</x-forms.button>
@else
<x-forms.button type="submit" isHighlighted>
<x-forms.button type="submit" wire:target="updateDomain" isHighlighted>
Save
</x-forms.button>
@endif

View file

@ -37,7 +37,8 @@
$wire.showEditDomainModal = true;
},
}"
@open-edit-domain.window="openEditDomain($event.detail.index, $event.detail.url, $event.detail.serviceApplicationId, $event.detail.serviceLabel)">
@open-edit-domain.window="openEditDomain($event.detail.index, $event.detail.url, $event.detail.serviceApplicationId, $event.detail.serviceLabel)"
@edit-domain-saved.window="closeEditDomain()">
<x-application.settings-section id="service-domains-section" title="Domains">
@can('update', $service)
<x-slot:actions>
@ -273,16 +274,13 @@ class="application-settings-form application-settings-section relative flex max-
@endif
<div class="flex flex-wrap items-center justify-end gap-2 pt-2">
<x-forms.button type="button" @click="closeEditDomain()">
Cancel
</x-forms.button>
@if ($editDomainDnsFailed)
<x-forms.button type="button" isError
@click="prepareEditSubmit(); $wire.forceSaveEditDns = true; $wire.confirmUpdateDomainDespiteDns()">
Continue
</x-forms.button>
@else
<x-forms.button type="submit" isHighlighted>
<x-forms.button type="submit" wire:target="updateDomain" isHighlighted>
Save
</x-forms.button>
@endif

View file

@ -275,6 +275,7 @@
->call('updateDomain')
->assertHasNoErrors()
->assertSet('showEditDomainModal', false)
->assertDispatched('edit-domain-saved')
->assertDispatched('success');
$this->application->refresh();

View file

@ -5,6 +5,7 @@
expect($styles)
->toMatch('/\.logs-viewer-btn-active\s*\{[^}]*background:\s*var\(--color-coollabs\);[^}]*color:\s*#fff;/s')
->toMatch('/\.dark \.logs-viewer-btn-active\s*\{[^}]*color:\s*#fff;/s')
->not->toMatch('/\.logs-viewer-btn-active\s*\{[^}]*var\(--color-warning\)/s');
});

View file

@ -32,7 +32,7 @@
$developmentSeederBlock = str($databaseSeeder)->after("if (in_array(config('app.env'), ['local', 'development', 'dev'], true)) {")->before(' }')->toString();
expect($developmentSeederBlock)->toContain('DevelopmentRailpackExamplesSeeder::class')
->and($developmentSeederBlock)->toContain('V5DevLimaSeeder::class');
->and($developmentSeederBlock)->not->toContain('V5DevLimaSeeder::class');
});
it('disables Flux host binding by default in the Docker development environment', function () {

View file

@ -17,7 +17,6 @@
use Database\Seeders\TeamSeeder;
use Database\Seeders\UserSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Collection;
uses(RefreshDatabase::class);
@ -34,189 +33,79 @@ function seedRailpackExamplePrerequisites(): void
]);
}
function limaServers(): Collection
{
return collect(DevelopmentRailpackExamplesSeeder::LIMA_SERVERS);
}
it('can seed the railpack examples directly on a clean development database', function () {
config()->set('app.env', 'local');
$this->seed(DevelopmentRailpackExamplesSeeder::class);
expect(Team::query()->find(0))->not->toBeNull();
expect(PrivateKey::query()->find(1))->not->toBeNull();
expect(Server::query()->find(0))->not->toBeNull();
expect(StandaloneDocker::query()->find(0))->not->toBeNull();
expect(GithubApp::query()->find(0))->not->toBeNull();
expect(GitlabApp::query()->find(1))->not->toBeNull();
expect(Application::query()->count())->toBe(count(DevelopmentRailpackExamplesSeeder::examples()) * limaServers()->count());
expect(Team::query()->find(0))->not->toBeNull()
->and(PrivateKey::query()->find(1))->not->toBeNull()
->and(Server::query()->count())->toBe(1)
->and(Server::query()->find(0)?->uuid)->toBe('localhost')
->and(StandaloneDocker::query()->find(0))->not->toBeNull()
->and(GithubApp::query()->find(0))->not->toBeNull()
->and(GitlabApp::query()->find(1))->not->toBeNull()
->and(Application::query()->count())->toBe(count(DevelopmentRailpackExamplesSeeder::examples()));
$project = Project::query()
->where('uuid', DevelopmentRailpackExamplesSeeder::PROJECT_UUID)
->first();
$project = Project::query()->where('uuid', DevelopmentRailpackExamplesSeeder::PROJECT_UUID)->firstOrFail();
expect($project)
->not->toBeNull()
->and($project->environments)->toHaveCount(limaServers()->count());
foreach (limaServers() as $limaServer) {
$server = Server::query()->where('uuid', $limaServer['server_uuid'])->first();
expect($server)->not->toBeNull();
expect($server->settings->sentinel_custom_url)->toBe('http://host.lima.internal:8000');
expect(StandaloneDocker::query()->whereRelation('server', 'uuid', $limaServer['server_uuid'])->exists())->toBeTrue();
expect($project->environments()->where('uuid', $limaServer['environment_uuid'])->exists())->toBeTrue();
}
expect($project->environments)->toHaveCount(1)
->and($project->environments->first()->name)->toBe('production')
->and($project->applications()->whereRelation('destination.server', 'uuid', 'localhost')->count())
->toBe(count(DevelopmentRailpackExamplesSeeder::examples()));
});
it('seeds the railpack examples in development mode', function () {
it('seeds every railpack example in the production environment on testing-host', function () {
config()->set('app.env', 'local');
seedRailpackExamplePrerequisites();
$legacyProject = Project::query()->create([
'uuid' => 'railpack-examples-lima-ubuntu-2404',
'name' => 'Railpack Examples - lima-ubuntu-2404',
'description' => 'Legacy generated Railpack examples project',
$this->seed(DevelopmentRailpackExamplesSeeder::class);
$project = Project::query()->where('uuid', DevelopmentRailpackExamplesSeeder::PROJECT_UUID)->firstOrFail();
$environment = $project->environments()->sole();
$applications = $environment->applications()->with('settings', 'destination.server')->orderBy('uuid')->get();
expect($environment->name)->toBe('production')
->and($applications)->toHaveCount(count(DevelopmentRailpackExamplesSeeder::examples()))
->and($applications->every(fn (Application $application) => $application->build_pack === 'railpack'))->toBeTrue()
->and($applications->every(fn (Application $application) => $application->destination->server->uuid === 'localhost'))->toBeTrue()
->and($applications->pluck('uuid')->sort()->values()->all())
->toBe(collect(DevelopmentRailpackExamplesSeeder::examples())->pluck('uuid')->sort()->values()->all());
$nestjs = $applications->firstWhere('uuid', 'railpack-nestjs');
$angularStatic = $applications->firstWhere('uuid', 'railpack-angular-static');
$githubDeployKey = $applications->firstWhere('uuid', 'railpack-github-deploy-key');
$gitlabDeployKey = $applications->firstWhere('uuid', 'railpack-gitlab-deploy-key');
expect($nestjs->base_directory)->toBe('/node/nestjs')
->and($nestjs->build_command)->toBe('npm run build')
->and($nestjs->start_command)->toBe('npm run start:prod')
->and($angularStatic->publish_directory)->toBe('/dist/static/browser')
->and($angularStatic->settings->is_static)->toBeTrue()
->and($githubDeployKey->private_key_id)->toBe(1)
->and($githubDeployKey->source_type)->toBe(GithubApp::class)
->and($gitlabDeployKey->source_type)->toBe(GitlabApp::class);
});
it('consolidates legacy railpack environments into production', function () {
config()->set('app.env', 'local');
seedRailpackExamplePrerequisites();
$project = Project::query()->create([
'uuid' => DevelopmentRailpackExamplesSeeder::PROJECT_UUID,
'name' => 'Railpack Examples',
'team_id' => 0,
]);
Application::query()->create([
'uuid' => 'lima-ubuntu-2404-railpack-nextjs-ssr',
'name' => 'Legacy Railpack Next.js SSR Example',
'repository_project_id' => DevelopmentRailpackExamplesSeeder::REPOSITORY_PROJECT_ID,
'git_repository' => DevelopmentRailpackExamplesSeeder::GIT_REPOSITORY,
'git_branch' => DevelopmentRailpackExamplesSeeder::GIT_BRANCH,
'build_pack' => 'railpack',
'ports_exposes' => '3000',
'environment_id' => $legacyProject->environments()->first()->id,
'destination_id' => 0,
'destination_type' => StandaloneDocker::class,
'source_id' => 0,
'source_type' => GithubApp::class,
]);
$project->environments()->first()->update(['name' => 'ubuntu24', 'uuid' => 'railpack-examples-ubuntu24']);
$project->environments()->create(['name' => 'ubuntu26', 'uuid' => 'railpack-examples-ubuntu26']);
$this->seed(DevelopmentRailpackExamplesSeeder::class);
$project = Project::query()
->where('uuid', DevelopmentRailpackExamplesSeeder::PROJECT_UUID)
->first();
$project->refresh();
expect($project)
->not->toBeNull()
->and($project->name)->toBe('Railpack Examples')
->and($project->environments)->toHaveCount(limaServers()->count());
expect(Project::query()->pluck('uuid')->sort()->values()->all())->toBe([
'project',
DevelopmentRailpackExamplesSeeder::PROJECT_UUID,
]);
expect(Application::query()->where('uuid', 'lima-ubuntu-2404-railpack-nextjs-ssr')->exists())->toBeFalse();
$applications = $project->applications()->with('settings')->orderBy('uuid')->get();
expect($applications)->toHaveCount(count(DevelopmentRailpackExamplesSeeder::examples()) * limaServers()->count());
expect($applications->every(fn (Application $application) => $application->build_pack === 'railpack'))->toBeTrue();
$examples = collect(DevelopmentRailpackExamplesSeeder::examples())->keyBy('uuid');
expect($applications->every(
fn (Application $application) => $application->git_repository === ($examples->get(str($application->uuid)->after('-')->value())['git_repository'] ?? DevelopmentRailpackExamplesSeeder::GIT_REPOSITORY)
))->toBeTrue();
expect($applications->every(
fn (Application $application) => $application->git_branch === ($examples->get(str($application->uuid)->after('-')->value())['git_branch'] ?? DevelopmentRailpackExamplesSeeder::GIT_BRANCH)
))->toBeTrue();
foreach (limaServers() as $limaServer) {
$limaEnvironment = $project->environments()
->where('uuid', $limaServer['environment_uuid'])
->first();
expect($limaEnvironment)
->not->toBeNull()
->and($limaEnvironment->name)->toBe($limaServer['environment_name']);
$limaApplications = $limaEnvironment->applications()->with('settings', 'destination.server')->orderBy('uuid')->get();
expect($limaApplications)->toHaveCount(count(DevelopmentRailpackExamplesSeeder::examples()));
expect($limaApplications->every(fn (Application $application) => $application->build_pack === 'railpack'))->toBeTrue();
expect($limaApplications->every(fn (Application $application) => str($application->uuid)->startsWith($limaServer['uuid_prefix'])))->toBeTrue();
expect($limaApplications->every(fn (Application $application) => $application->destination->server->uuid === $limaServer['server_uuid']))->toBeTrue();
expect($limaApplications->every(
fn (Application $application) => $application->git_repository === ($examples->get(str($application->uuid)->after($limaServer['uuid_prefix'])->value())['git_repository'] ?? DevelopmentRailpackExamplesSeeder::GIT_REPOSITORY)
))->toBeTrue();
expect($limaApplications->every(
fn (Application $application) => $application->git_branch === ($examples->get(str($application->uuid)->after($limaServer['uuid_prefix'])->value())['git_branch'] ?? DevelopmentRailpackExamplesSeeder::GIT_BRANCH)
))->toBeTrue();
}
$nestjs = $applications->firstWhere('uuid', 'ubuntu24-railpack-nestjs');
$angularStatic = $applications->firstWhere('uuid', 'ubuntu24-railpack-angular-static');
$eleventyStatic = $applications->firstWhere('uuid', 'ubuntu24-railpack-eleventy-static');
$pythonFlask = $applications->firstWhere('uuid', 'ubuntu24-railpack-python-flask');
$goGin = $applications->firstWhere('uuid', 'ubuntu24-railpack-go-gin');
$rust = $applications->firstWhere('uuid', 'ubuntu24-railpack-rust');
$githubDeployKey = $applications->firstWhere('uuid', 'ubuntu24-railpack-github-deploy-key');
$gitlabDeployKey = $applications->firstWhere('uuid', 'ubuntu24-railpack-gitlab-deploy-key');
$gitlabPublic = $applications->firstWhere('uuid', 'ubuntu24-railpack-gitlab-public-example');
expect($nestjs)
->not->toBeNull()
->and($nestjs->base_directory)->toBe('/node/nestjs')
->and($nestjs->ports_exposes)->toBe('3000')
->and($nestjs->build_command)->toBe('npm run build')
->and($nestjs->start_command)->toBe('npm run start:prod')
->and($nestjs->settings->is_static)->toBeFalse();
expect($angularStatic)
->not->toBeNull()
->and($angularStatic->publish_directory)->toBe('/dist/static/browser')
->and($angularStatic->ports_exposes)->toBe('80')
->and($angularStatic->settings->is_static)->toBeTrue()
->and($angularStatic->settings->is_spa)->toBeTrue();
expect($eleventyStatic)
->not->toBeNull()
->and($eleventyStatic->publish_directory)->toBe('/_site')
->and($eleventyStatic->settings->is_static)->toBeTrue()
->and($eleventyStatic->settings->is_spa)->toBeFalse();
expect($pythonFlask)
->not->toBeNull()
->and($pythonFlask->ports_exposes)->toBe('5000')
->and($pythonFlask->start_command)->toBe('flask run --host=0.0.0.0 --port=5000');
expect($goGin)
->not->toBeNull()
->and($goGin->ports_exposes)->toBe('3000');
expect($rust)
->not->toBeNull()
->and($rust->ports_exposes)->toBe('8000');
expect($githubDeployKey)
->not->toBeNull()
->and($githubDeployKey->git_repository)->toBe('git@github.com:coollabsio/coolify-examples-deploy-key.git')
->and($githubDeployKey->git_branch)->toBe('main')
->and($githubDeployKey->build_pack)->toBe('railpack')
->and($githubDeployKey->private_key_id)->toBe(1)
->and($githubDeployKey->source_type)->toBe(GithubApp::class)
->and($githubDeployKey->source_id)->toBe(0);
expect($gitlabDeployKey)
->not->toBeNull()
->and($gitlabDeployKey->git_repository)->toBe('git@gitlab.com:coollabsio/php-example.git')
->and($gitlabDeployKey->git_branch)->toBe('main')
->and($gitlabDeployKey->build_pack)->toBe('railpack')
->and($gitlabDeployKey->private_key_id)->toBe(1)
->and($gitlabDeployKey->source_type)->toBe(GitlabApp::class)
->and($gitlabDeployKey->source_id)->toBe(1);
expect($gitlabPublic)
->not->toBeNull()
->and($gitlabPublic->git_repository)->toBe('https://gitlab.com/andrasbacsai/coolify-examples.git')
->and($gitlabPublic->base_directory)->toBe('/astro/static')
->and($gitlabPublic->publish_directory)->toBe('/dist')
->and($gitlabPublic->build_pack)->toBe('railpack')
->and($gitlabPublic->source_type)->toBe(GitlabApp::class)
->and($gitlabPublic->settings->is_static)->toBeTrue();
expect($project->environments)->toHaveCount(1)
->and($project->environments->first()->name)->toBe('production')
->and($project->applications)->toHaveCount(count(DevelopmentRailpackExamplesSeeder::examples()));
});
it('skips the railpack examples outside development mode', function () {
@ -226,13 +115,6 @@ function limaServers(): Collection
$this->seed(DevelopmentRailpackExamplesSeeder::class);
expect(Project::query()->where('uuid', DevelopmentRailpackExamplesSeeder::PROJECT_UUID)->exists())->toBeFalse();
expect(Application::query()->where('uuid', 'railpack-nextjs-ssr')->exists())->toBeFalse();
foreach (limaServers() as $limaServer) {
expect(Project::query()->where('uuid', 'railpack-examples-lima-ubuntu-2404')->exists())->toBeFalse();
expect(Project::query()->where('uuid', 'railpack-examples-lima-ubuntu-2604')->exists())->toBeFalse();
expect(Application::query()->where('uuid', $limaServer['uuid_prefix'].'railpack-nextjs-ssr')->exists())->toBeFalse();
}
});
it('is idempotent when run multiple times', function () {
@ -242,19 +124,8 @@ function limaServers(): Collection
$this->seed(DevelopmentRailpackExamplesSeeder::class);
$this->seed(DevelopmentRailpackExamplesSeeder::class);
$project = Project::query()
->where('uuid', DevelopmentRailpackExamplesSeeder::PROJECT_UUID)
->first();
$project = Project::query()->where('uuid', DevelopmentRailpackExamplesSeeder::PROJECT_UUID)->firstOrFail();
expect($project)->not->toBeNull();
expect($project->applications()->count())->toBe(count(DevelopmentRailpackExamplesSeeder::examples()) * limaServers()->count());
foreach (limaServers() as $limaServer) {
$limaEnvironment = $project->environments()
->where('uuid', $limaServer['environment_uuid'])
->first();
expect($limaEnvironment)->not->toBeNull();
expect($limaEnvironment->applications()->count())->toBe(count(DevelopmentRailpackExamplesSeeder::examples()));
}
expect($project->environments)->toHaveCount(1)
->and($project->applications)->toHaveCount(count(DevelopmentRailpackExamplesSeeder::examples()));
});

View file

@ -1,5 +1,19 @@
<?php
test('edit domain dialogs close after saving and omit redundant cancel actions', function () {
foreach ([
resource_path('views/livewire/project/application/domains.blade.php'),
resource_path('views/livewire/project/service/domains.blade.php'),
] as $viewPath) {
$view = file_get_contents($viewPath);
expect($view)
->toContain('@edit-domain-saved.window="closeEditDomain()"')
->toContain('<x-forms.button type="submit" wire:target="updateDomain" isHighlighted>')
->not->toContain("@click=\"closeEditDomain()\">\n Cancel");
}
});
it('provides a reusable domain chips form component', function () {
$component = file_get_contents(resource_path('views/components/forms/domain-chips.blade.php'));

View file

@ -9,7 +9,7 @@
uses(RefreshDatabase::class);
it('seeds the first project with lima environments', function () {
it('seeds the first project with only a production environment', function () {
$this->seed([
UserSeeder::class,
TeamSeeder::class,
@ -24,8 +24,6 @@
expect($project)
->not->toBeNull()
->and($project->name)->toBe('My first project')
->and($project->environments()->pluck('uuid', 'name')->all())->toBe([
'ubuntu24' => 'ubuntu24',
'ubuntu26' => 'ubuntu26',
]);
->and($project->environments)->toHaveCount(1)
->and($project->environments->first()->name)->toBe('production');
});

View file

@ -6,19 +6,10 @@
use Database\Seeders\TeamSeeder;
use Database\Seeders\UserSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Symfony\Component\Yaml\Yaml;
uses(RefreshDatabase::class);
function limaServerDefinitions(): array
{
return [
['uuid' => 'lima-ubuntu-2404', 'port' => 2222, 'template' => 'ubuntu-2404.yaml', 'memory' => '2GiB', 'disk' => '20GiB'],
['uuid' => 'lima-ubuntu-2604', 'port' => 2223, 'template' => 'ubuntu-2604.yaml', 'memory' => '2GiB', 'disk' => '20GiB'],
];
}
it('seeds the development testing host and lima servers', function () {
it('seeds only the development testing host', function () {
$this->seed([
UserSeeder::class,
TeamSeeder::class,
@ -30,37 +21,6 @@ function limaServerDefinitions(): array
expect($testingHost)
->not->toBeNull()
->and($testingHost->ip)->toBe('coolify-testing-host');
foreach (limaServerDefinitions() as $definition) {
$limaServer = Server::query()->where('uuid', $definition['uuid'])->first();
expect($limaServer)
->not->toBeNull()
->and($limaServer->name)->toBe($definition['uuid'])
->and($limaServer->ip)->toBe('host.docker.internal')
->and($limaServer->port)->toBe($definition['port'])
->and($limaServer->user)->toBe('root')
->and($limaServer->team_id)->toBe(0)
->and($limaServer->private_key_id)->toBe(1)
->and($limaServer->settings)->not->toBeNull()
->and($limaServer->settings->sentinel_custom_url)->toBe('http://host.lima.internal:8000')
->and($limaServer->destinations())->toHaveCount(1);
}
});
it('keeps the lima templates aligned with the seeded servers', function () {
foreach (limaServerDefinitions() as $definition) {
$template = Yaml::parseFile(base_path("docker/lima/{$definition['template']}"));
$script = data_get($template, 'provision.0.script');
expect(data_get($template, 'ssh.localPort'))
->toBe($definition['port'])
->and(data_get($template, 'memory'))->toBe($definition['memory'])
->and(data_get($template, 'disk'))->toBe($definition['disk'])
->and(data_get($template, 'containerd.system'))->toBeFalse()
->and(data_get($template, 'containerd.user'))->toBeFalse()
->and(data_get($template, 'networks'))->toBeNull()
->and($script)->toContain('ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFuGmoeGq/pojrsyP1pszcNVuZx9iFkCELtxrh31QJ68');
}
->and($testingHost->ip)->toBe('coolify-testing-host')
->and(Server::query()->count())->toBe(1);
});

View file

@ -332,6 +332,7 @@
->set('editingDomain', 'https://renamed.example.com')
->call('updateDomain')
->assertHasNoErrors()
->assertDispatched('edit-domain-saved')
->assertDispatched('success');
$this->apiApp->refresh();