fix(previews): enhance domain generation logic for application previews, ensuring unique domains are created when none are set

This commit is contained in:
Andras Bacsai
2025-07-14 15:42:01 +02:00
parent 98ceec3b7e
commit a9e542bc4b
2 changed files with 56 additions and 8 deletions

View File

@@ -38,9 +38,25 @@ class PreviewsCompose extends Component
$domain = $domains->first(function ($_, $key) {
return $key === $this->serviceName;
});
if ($domain) {
$domain = data_get($domain, 'domain');
$url = Url::fromString($domain);
$domain_string = data_get($domain, 'domain');
// If no domain is set in the main application, generate a default domain
if (empty($domain_string)) {
$server = $this->preview->application->destination->server;
$template = $this->preview->application->preview_url_template;
$random = new Cuid2;
// Generate a unique domain like main app services do
$generated_fqdn = generateFqdn($server, $random);
$preview_fqdn = str_replace('{{random}}', $random, $template);
$preview_fqdn = str_replace('{{domain}}', str($generated_fqdn)->after('://'), $preview_fqdn);
$preview_fqdn = str_replace('{{pr_id}}', $this->preview->pull_request_id, $preview_fqdn);
$preview_fqdn = str($generated_fqdn)->before('://').'://'.$preview_fqdn;
} else {
// Use the existing domain from the main application
$url = Url::fromString($domain_string);
$template = $this->preview->application->preview_url_template;
$host = $url->getHost();
$schema = $url->getScheme();
@@ -49,12 +65,15 @@ class PreviewsCompose extends Component
$preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn);
$preview_fqdn = str_replace('{{pr_id}}', $this->preview->pull_request_id, $preview_fqdn);
$preview_fqdn = "$schema://$preview_fqdn";
}
// Save the generated domain
$docker_compose_domains = data_get($this->preview, 'docker_compose_domains');
$docker_compose_domains = json_decode($docker_compose_domains, true);
$docker_compose_domains[$this->serviceName]['domain'] = $this->service->domain = $preview_fqdn;
$this->preview->docker_compose_domains = json_encode($docker_compose_domains);
$this->preview->save();
}
$this->dispatch('update_links');
$this->dispatch('success', 'Domain generated.');
}

View File

@@ -56,8 +56,34 @@ class ApplicationPreview extends BaseModel
$docker_compose_domains = data_get($this, 'docker_compose_domains');
$docker_compose_domains = json_decode($docker_compose_domains, true) ?? [];
// Get all services from the parsed compose file to ensure all services have entries
$parsedServices = $this->application->parse(pull_request_id: $this->pull_request_id);
if (isset($parsedServices['services'])) {
foreach ($parsedServices['services'] as $serviceName => $service) {
if (! isDatabaseImage(data_get($service, 'image'))) {
// Remove PR suffix from service name to get original service name
$originalServiceName = str($serviceName)->replaceLast('-pr-'.$this->pull_request_id, '')->toString();
// Ensure all services have an entry, even if empty
if (! $services->has($originalServiceName)) {
$services->put($originalServiceName, ['domain' => '']);
}
}
}
}
foreach ($services as $service_name => $service_config) {
$domain_string = data_get($service_config, 'domain');
// If domain string is empty or null, don't auto-generate domain
// Only generate domains when main app already has domains set
if (empty($domain_string)) {
// Ensure service has an empty domain entry for form binding
$docker_compose_domains[$service_name]['domain'] = '';
continue;
}
$service_domains = str($domain_string)->explode(',')->map(fn ($d) => trim($d));
$preview_domains = [];
@@ -80,6 +106,9 @@ class ApplicationPreview extends BaseModel
if (! empty($preview_domains)) {
$docker_compose_domains[$service_name]['domain'] = implode(',', $preview_domains);
} else {
// Ensure service has an empty domain entry for form binding
$docker_compose_domains[$service_name]['domain'] = '';
}
}