feat: able to add several domains to compose based previews
This commit is contained in:
parent
e9e12ad843
commit
7fd0deedb1
@ -26,7 +26,6 @@ class ServicesGenerate extends Command
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
// ray()->clearAll();
|
|
||||||
$files = array_diff(scandir(base_path('templates/compose')), ['.', '..']);
|
$files = array_diff(scandir(base_path('templates/compose')), ['.', '..']);
|
||||||
$files = array_filter($files, function ($file) {
|
$files = array_filter($files, function ($file) {
|
||||||
return strpos($file, '.yaml') !== false;
|
return strpos($file, '.yaml') !== false;
|
||||||
|
@ -113,7 +113,6 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
public $tries = 1;
|
public $tries = 1;
|
||||||
public function __construct(int $application_deployment_queue_id)
|
public function __construct(int $application_deployment_queue_id)
|
||||||
{
|
{
|
||||||
ray()->clearAll();
|
|
||||||
$this->application_deployment_queue = ApplicationDeploymentQueue::find($application_deployment_queue_id);
|
$this->application_deployment_queue = ApplicationDeploymentQueue::find($application_deployment_queue_id);
|
||||||
$this->application = Application::find($this->application_deployment_queue->application_id);
|
$this->application = Application::find($this->application_deployment_queue->application_id);
|
||||||
$this->build_pack = data_get($this->application, 'build_pack');
|
$this->build_pack = data_get($this->application, 'build_pack');
|
||||||
@ -373,7 +372,7 @@ private function deploy_docker_compose_buildpack()
|
|||||||
$yaml = $composeFile = $this->application->docker_compose_raw;
|
$yaml = $composeFile = $this->application->docker_compose_raw;
|
||||||
$this->save_environment_variables();
|
$this->save_environment_variables();
|
||||||
} else {
|
} else {
|
||||||
$composeFile = $this->application->parseCompose(pull_request_id: $this->pull_request_id);
|
$composeFile = $this->application->parseCompose(pull_request_id: $this->pull_request_id, preview_id: data_get($this, 'preview.id'));
|
||||||
$this->save_environment_variables();
|
$this->save_environment_variables();
|
||||||
if (!is_null($this->env_filename)) {
|
if (!is_null($this->env_filename)) {
|
||||||
$services = collect($composeFile['services']);
|
$services = collect($composeFile['services']);
|
||||||
|
@ -25,6 +25,7 @@ public function getListeners()
|
|||||||
return [
|
return [
|
||||||
"echo-private:team.{$teamId},ApplicationStatusChanged" => 'check_status',
|
"echo-private:team.{$teamId},ApplicationStatusChanged" => 'check_status',
|
||||||
"compose_loaded" => '$refresh',
|
"compose_loaded" => '$refresh',
|
||||||
|
"update_links" => '$refresh',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
public function mount()
|
public function mount()
|
||||||
|
@ -43,7 +43,7 @@ public function save_preview($preview_id)
|
|||||||
try {
|
try {
|
||||||
$success = true;
|
$success = true;
|
||||||
$preview = $this->application->previews->find($preview_id);
|
$preview = $this->application->previews->find($preview_id);
|
||||||
if (isset($preview->fqdn)) {
|
if (data_get_str($preview, 'fqdn')->isNotEmpty()) {
|
||||||
$preview->fqdn = str($preview->fqdn)->replaceEnd(',', '')->trim();
|
$preview->fqdn = str($preview->fqdn)->replaceEnd(',', '')->trim();
|
||||||
$preview->fqdn = str($preview->fqdn)->replaceStart(',', '')->trim();
|
$preview->fqdn = str($preview->fqdn)->replaceStart(',', '')->trim();
|
||||||
$preview->fqdn = str($preview->fqdn)->trim()->lower();
|
$preview->fqdn = str($preview->fqdn)->trim()->lower();
|
||||||
@ -79,7 +79,7 @@ public function generate_preview($preview_id)
|
|||||||
$random = new Cuid2(7);
|
$random = new Cuid2(7);
|
||||||
$preview_fqdn = str_replace('{{random}}', $random, $template);
|
$preview_fqdn = str_replace('{{random}}', $random, $template);
|
||||||
$preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn);
|
$preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn);
|
||||||
$preview_fqdn = str_replace('{{pr_id}}', $preview_id, $preview_fqdn);
|
$preview_fqdn = str_replace('{{pr_id}}', $preview->pull_request_id, $preview_fqdn);
|
||||||
$preview_fqdn = "$schema://$preview_fqdn";
|
$preview_fqdn = "$schema://$preview_fqdn";
|
||||||
$preview->fqdn = $preview_fqdn;
|
$preview->fqdn = $preview_fqdn;
|
||||||
$preview->save();
|
$preview->save();
|
||||||
@ -88,17 +88,34 @@ public function generate_preview($preview_id)
|
|||||||
public function add(int $pull_request_id, string|null $pull_request_html_url = null)
|
public function add(int $pull_request_id, string|null $pull_request_html_url = null)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->setDeploymentUuid();
|
if ($this->application->build_pack === 'dockercompose') {
|
||||||
$found = ApplicationPreview::where('application_id', $this->application->id)->where('pull_request_id', $pull_request_id)->first();
|
$this->setDeploymentUuid();
|
||||||
if (!$found && !is_null($pull_request_html_url)) {
|
$found = ApplicationPreview::where('application_id', $this->application->id)->where('pull_request_id', $pull_request_id)->first();
|
||||||
ApplicationPreview::create([
|
if (!$found && !is_null($pull_request_html_url)) {
|
||||||
'application_id' => $this->application->id,
|
$found = ApplicationPreview::create([
|
||||||
'pull_request_id' => $pull_request_id,
|
'application_id' => $this->application->id,
|
||||||
'pull_request_html_url' => $pull_request_html_url
|
'pull_request_id' => $pull_request_id,
|
||||||
]);
|
'pull_request_html_url' => $pull_request_html_url,
|
||||||
|
'docker_compose_domains' => $this->application->docker_compose_domains,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
$found->generate_preview_fqdn_compose();
|
||||||
|
$this->application->refresh();
|
||||||
|
} else {
|
||||||
|
$this->setDeploymentUuid();
|
||||||
|
$found = ApplicationPreview::where('application_id', $this->application->id)->where('pull_request_id', $pull_request_id)->first();
|
||||||
|
if (!$found && !is_null($pull_request_html_url)) {
|
||||||
|
$found = ApplicationPreview::create([
|
||||||
|
'application_id' => $this->application->id,
|
||||||
|
'pull_request_id' => $pull_request_id,
|
||||||
|
'pull_request_html_url' => $pull_request_html_url,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
$this->application->generate_preview_fqdn($pull_request_id);
|
||||||
|
$this->application->refresh();
|
||||||
|
$this->dispatch('update_links');
|
||||||
|
$this->dispatch('success', 'Preview added.');
|
||||||
}
|
}
|
||||||
$this->application->generate_preview_fqdn($pull_request_id);
|
|
||||||
$this->application->refresh();
|
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
}
|
}
|
||||||
@ -152,7 +169,7 @@ public function stop(int $pull_request_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
GetContainersStatus::dispatchSync($this->application->destination->server);
|
GetContainersStatus::dispatchSync($this->application->destination->server);
|
||||||
$this->application->refresh();
|
$this->dispatch('reloadWindow');
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
}
|
}
|
||||||
@ -172,15 +189,10 @@ public function delete(int $pull_request_id)
|
|||||||
}
|
}
|
||||||
ApplicationPreview::where('application_id', $this->application->id)->where('pull_request_id', $pull_request_id)->first()->delete();
|
ApplicationPreview::where('application_id', $this->application->id)->where('pull_request_id', $pull_request_id)->first()->delete();
|
||||||
$this->application->refresh();
|
$this->application->refresh();
|
||||||
|
$this->dispatch('update_links');
|
||||||
|
$this->dispatch('success', 'Preview deleted.');
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function previewRefresh()
|
|
||||||
{
|
|
||||||
$this->application->previews->each(function ($preview) {
|
|
||||||
$preview->refresh();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
56
app/Livewire/Project/Application/PreviewsCompose.php
Normal file
56
app/Livewire/Project/Application/PreviewsCompose.php
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire\Project\Application;
|
||||||
|
|
||||||
|
use App\Models\ApplicationPreview;
|
||||||
|
use Livewire\Component;
|
||||||
|
use Spatie\Url\Url;
|
||||||
|
use Visus\Cuid2\Cuid2;
|
||||||
|
|
||||||
|
class PreviewsCompose extends Component
|
||||||
|
{
|
||||||
|
public $service;
|
||||||
|
public $serviceName;
|
||||||
|
public ApplicationPreview $preview;
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.project.application.previews-compose');
|
||||||
|
}
|
||||||
|
public function save()
|
||||||
|
{
|
||||||
|
$domain = data_get($this->service, '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'] = $domain;
|
||||||
|
$this->preview->docker_compose_domains = json_encode($docker_compose_domains);
|
||||||
|
$this->preview->save();
|
||||||
|
$this->dispatch('update_links');
|
||||||
|
$this->dispatch('success', 'Domain saved.');
|
||||||
|
}
|
||||||
|
public function generate()
|
||||||
|
{
|
||||||
|
$domains = collect(json_decode($this->preview->application->docker_compose_domains)) ?? collect();
|
||||||
|
$domain = $domains->first(function ($_, $key) {
|
||||||
|
return $key === $this->serviceName;
|
||||||
|
});
|
||||||
|
if ($domain) {
|
||||||
|
$domain = data_get($domain, 'domain');
|
||||||
|
$url = Url::fromString($domain);
|
||||||
|
$template = $this->preview->application->preview_url_template;
|
||||||
|
$host = $url->getHost();
|
||||||
|
$schema = $url->getScheme();
|
||||||
|
$random = new Cuid2(7);
|
||||||
|
$preview_fqdn = str_replace('{{random}}', $random, $template);
|
||||||
|
$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";
|
||||||
|
$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.');
|
||||||
|
}
|
||||||
|
}
|
@ -861,14 +861,10 @@ function parseRawCompose()
|
|||||||
|
|
||||||
instant_remote_process($commands, $this->destination->server, false);
|
instant_remote_process($commands, $this->destination->server, false);
|
||||||
}
|
}
|
||||||
function parseCompose(int $pull_request_id = 0)
|
function parseCompose(int $pull_request_id = 0, ?int $preview_id = null)
|
||||||
{
|
{
|
||||||
if ($this->docker_compose_raw) {
|
if ($this->docker_compose_raw) {
|
||||||
$mainCompose = parseDockerComposeFile(resource: $this, isNew: false, pull_request_id: $pull_request_id);
|
return parseDockerComposeFile(resource: $this, isNew: false, pull_request_id: $pull_request_id, preview_id: $preview_id);
|
||||||
if ($this->getMorphClass() === 'App\Models\Application' && $this->docker_compose_pr_raw) {
|
|
||||||
parseDockerComposeFile(resource: $this, isNew: false, pull_request_id: $pull_request_id, is_pr: true);
|
|
||||||
}
|
|
||||||
return $mainCompose;
|
|
||||||
} else {
|
} else {
|
||||||
return collect([]);
|
return collect([]);
|
||||||
}
|
}
|
||||||
@ -1052,7 +1048,8 @@ public function parseHealthcheckFromDockerfile($dockerfile, bool $isInit = false
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function generate_preview_fqdn(int $pull_request_id) {
|
function generate_preview_fqdn(int $pull_request_id)
|
||||||
|
{
|
||||||
$preview = ApplicationPreview::findPreviewByApplicationAndPullId($this->id, $pull_request_id);
|
$preview = ApplicationPreview::findPreviewByApplicationAndPullId($this->id, $pull_request_id);
|
||||||
if (is_null(data_get($preview, 'fqdn')) && $this->fqdn) {
|
if (is_null(data_get($preview, 'fqdn')) && $this->fqdn) {
|
||||||
if (str($this->fqdn)->contains(',')) {
|
if (str($this->fqdn)->contains(',')) {
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Spatie\Url\Url;
|
||||||
|
use Visus\Cuid2\Cuid2;
|
||||||
|
|
||||||
class ApplicationPreview extends BaseModel
|
class ApplicationPreview extends BaseModel
|
||||||
{
|
{
|
||||||
protected $guarded = [];
|
protected $guarded = [];
|
||||||
@ -34,4 +37,26 @@ public function application()
|
|||||||
{
|
{
|
||||||
return $this->belongsTo(Application::class);
|
return $this->belongsTo(Application::class);
|
||||||
}
|
}
|
||||||
|
function generate_preview_fqdn_compose()
|
||||||
|
{
|
||||||
|
$domains = collect(json_decode($this->application->docker_compose_domains)) ?? collect();
|
||||||
|
foreach ($domains as $service_name => $domain) {
|
||||||
|
$domain = data_get($domain, 'domain');
|
||||||
|
$url = Url::fromString($domain);
|
||||||
|
$template = $this->application->preview_url_template;
|
||||||
|
$host = $url->getHost();
|
||||||
|
$schema = $url->getScheme();
|
||||||
|
$random = new Cuid2(7);
|
||||||
|
$preview_fqdn = str_replace('{{random}}', $random, $template);
|
||||||
|
$preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn);
|
||||||
|
$preview_fqdn = str_replace('{{pr_id}}', $this->pull_request_id, $preview_fqdn);
|
||||||
|
$preview_fqdn = "$schema://$preview_fqdn";
|
||||||
|
$docker_compose_domains = data_get($this, 'docker_compose_domains');
|
||||||
|
$docker_compose_domains = json_decode($docker_compose_domains, true);
|
||||||
|
$docker_compose_domains[$service_name]['domain'] = $preview_fqdn;
|
||||||
|
$docker_compose_domains = json_encode($docker_compose_domains);
|
||||||
|
$this->docker_compose_domains = $docker_compose_domains;
|
||||||
|
$this->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -488,8 +488,10 @@ function generateLabelsApplication(Application $application, ?ApplicationPreview
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ($preview->fqdn) {
|
if (data_get($preview,'fqdn')) {
|
||||||
$domains = Str::of(data_get($preview, 'fqdn'))->explode(',');
|
$domains = Str::of(data_get($preview, 'fqdn'))->explode(',');
|
||||||
|
} else {
|
||||||
|
$domains = collect([]);
|
||||||
}
|
}
|
||||||
$labels = $labels->merge(fqdnLabelsForTraefik(
|
$labels = $labels->merge(fqdnLabelsForTraefik(
|
||||||
uuid: $appUuid,
|
uuid: $appUuid,
|
||||||
|
@ -657,9 +657,8 @@ function getTopLevelNetworks(Service|Application $resource)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseDockerComposeFile(Service|Application $resource, bool $isNew = false, int $pull_request_id = 0, bool $is_pr = false)
|
function parseDockerComposeFile(Service|Application $resource, bool $isNew = false, int $pull_request_id = 0, ?int $preview_id = null)
|
||||||
{
|
{
|
||||||
// ray()->clearAll();
|
|
||||||
if ($resource->getMorphClass() === 'App\Models\Service') {
|
if ($resource->getMorphClass() === 'App\Models\Service') {
|
||||||
if ($resource->docker_compose_raw) {
|
if ($resource->docker_compose_raw) {
|
||||||
try {
|
try {
|
||||||
@ -1283,20 +1282,11 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
|||||||
$isSameDockerComposeFile = false;
|
$isSameDockerComposeFile = false;
|
||||||
if ($resource->dockerComposePrLocation() === $resource->dockerComposeLocation()) {
|
if ($resource->dockerComposePrLocation() === $resource->dockerComposeLocation()) {
|
||||||
$isSameDockerComposeFile = true;
|
$isSameDockerComposeFile = true;
|
||||||
$is_pr = false;
|
|
||||||
}
|
}
|
||||||
if ($is_pr) {
|
try {
|
||||||
try {
|
$yaml = Yaml::parse($resource->docker_compose_raw);
|
||||||
$yaml = Yaml::parse($resource->docker_compose_pr_raw);
|
} catch (\Exception $e) {
|
||||||
} catch (\Exception $e) {
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
$yaml = Yaml::parse($resource->docker_compose_raw);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$server = $resource->destination->server;
|
$server = $resource->destination->server;
|
||||||
$topLevelVolumes = collect(data_get($yaml, 'volumes', []));
|
$topLevelVolumes = collect(data_get($yaml, 'volumes', []));
|
||||||
@ -1330,7 +1320,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
|||||||
if ($pull_request_id !== 0) {
|
if ($pull_request_id !== 0) {
|
||||||
$definedNetwork = collect(["{$resource->uuid}-$pull_request_id"]);
|
$definedNetwork = collect(["{$resource->uuid}-$pull_request_id"]);
|
||||||
}
|
}
|
||||||
$services = collect($services)->map(function ($service, $serviceName) use ($topLevelVolumes, $topLevelNetworks, $definedNetwork, $isNew, $generatedServiceFQDNS, $resource, $server, $pull_request_id) {
|
$services = collect($services)->map(function ($service, $serviceName) use ($topLevelVolumes, $topLevelNetworks, $definedNetwork, $isNew, $generatedServiceFQDNS, $resource, $server, $pull_request_id, $preview_id) {
|
||||||
$serviceVolumes = collect(data_get($service, 'volumes', []));
|
$serviceVolumes = collect(data_get($service, 'volumes', []));
|
||||||
$servicePorts = collect(data_get($service, 'ports', []));
|
$servicePorts = collect(data_get($service, 'ports', []));
|
||||||
$serviceNetworks = collect(data_get($service, 'networks', []));
|
$serviceNetworks = collect(data_get($service, 'networks', []));
|
||||||
@ -1716,21 +1706,14 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
|||||||
if ($fqdns) {
|
if ($fqdns) {
|
||||||
$fqdns = str($fqdns)->explode(',');
|
$fqdns = str($fqdns)->explode(',');
|
||||||
if ($pull_request_id !== 0) {
|
if ($pull_request_id !== 0) {
|
||||||
$fqdns = $fqdns->map(function ($fqdn) use ($pull_request_id, $resource) {
|
$preview = $resource->previews()->find($preview_id);
|
||||||
$preview = ApplicationPreview::findPreviewByApplicationAndPullId($resource->id, $pull_request_id);
|
$docker_compose_domains = collect(json_decode(data_get($preview, 'docker_compose_domains')));
|
||||||
$url = Url::fromString($fqdn);
|
$found_fqdn = data_get($docker_compose_domains, "$serviceName.domain");
|
||||||
$template = $resource->preview_url_template;
|
if ($found_fqdn) {
|
||||||
$host = $url->getHost();
|
$fqdns = collect($found_fqdn);
|
||||||
$schema = $url->getScheme();
|
} else {
|
||||||
$random = new Cuid2(7);
|
$fqdns = collect([]);
|
||||||
$preview_fqdn = str_replace('{{random}}', $random, $template);
|
}
|
||||||
$preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn);
|
|
||||||
$preview_fqdn = str_replace('{{pr_id}}', $pull_request_id, $preview_fqdn);
|
|
||||||
$preview_fqdn = "$schema://$preview_fqdn";
|
|
||||||
$preview->fqdn = $preview_fqdn;
|
|
||||||
$preview->save();
|
|
||||||
return $preview_fqdn;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
$serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik(
|
$serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik(
|
||||||
uuid: $resource->uuid,
|
uuid: $resource->uuid,
|
||||||
@ -1797,13 +1780,8 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
|||||||
$resource->docker_compose_raw = Yaml::dump($yaml, 10, 2);
|
$resource->docker_compose_raw = Yaml::dump($yaml, 10, 2);
|
||||||
$resource->docker_compose = Yaml::dump($finalServices, 10, 2);
|
$resource->docker_compose = Yaml::dump($finalServices, 10, 2);
|
||||||
} else {
|
} else {
|
||||||
if ($is_pr) {
|
$resource->docker_compose_raw = Yaml::dump($yaml, 10, 2);
|
||||||
$resource->docker_compose_pr_raw = Yaml::dump($yaml, 10, 2);
|
$resource->docker_compose = Yaml::dump($finalServices, 10, 2);
|
||||||
$resource->docker_compose_pr = Yaml::dump($finalServices, 10, 2);
|
|
||||||
} else {
|
|
||||||
$resource->docker_compose_raw = Yaml::dump($yaml, 10, 2);
|
|
||||||
$resource->docker_compose = Yaml::dump($finalServices, 10, 2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$resource->save();
|
$resource->save();
|
||||||
return collect($finalServices);
|
return collect($finalServices);
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('application_previews', function (Blueprint $table) {
|
||||||
|
$table->text('docker_compose_domains')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('application_previews', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('docker_compose_domains');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@ -45,24 +45,48 @@
|
|||||||
</a>
|
</a>
|
||||||
@endforeach
|
@endforeach
|
||||||
@endif
|
@endif
|
||||||
@if (data_get($application, 'previews', collect([]))->count() > 0)
|
@if (data_get($application, 'previews', collect())->count() > 0)
|
||||||
@foreach (data_get($application, 'previews') as $preview)
|
@if (data_get($application, 'build_pack') === 'dockercompose')
|
||||||
@if (data_get($preview, 'fqdn'))
|
@foreach ($application->previews as $preview)
|
||||||
<a class="dropdown-item" target="_blank"
|
@foreach (collect(json_decode($preview->docker_compose_domains)) as $fqdn)
|
||||||
href="{{ getFqdnWithoutPort(data_get($preview, 'fqdn')) }}">
|
@if (data_get($fqdn, 'domain'))
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" viewBox="0 0 24 24" stroke-width="1.5"
|
@foreach (explode(',', data_get($fqdn, 'domain')) as $domain)
|
||||||
stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
<a class="dropdown-item" target="_blank" href="{{ getFqdnWithoutPort($domain) }}">
|
||||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" viewBox="0 0 24 24"
|
||||||
<path d="M9 15l6 -6" />
|
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||||
<path d="M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464" />
|
stroke-linejoin="round">
|
||||||
<path
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
d="M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463" />
|
<path d="M9 15l6 -6" />
|
||||||
</svg>
|
<path d="M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464" />
|
||||||
PR{{ data_get($preview, 'pull_request_id') }} |
|
<path
|
||||||
{{ data_get($preview, 'fqdn') }}
|
d="M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463" />
|
||||||
</a>
|
</svg>PR{{ data_get($preview, 'pull_request_id') }} |
|
||||||
@endif
|
{{ getFqdnWithoutPort($domain) }}
|
||||||
@endforeach
|
</a>
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
@endforeach
|
||||||
|
@else
|
||||||
|
@foreach (data_get($application, 'previews') as $preview)
|
||||||
|
@if (data_get($preview, 'fqdn'))
|
||||||
|
<a class="dropdown-item" target="_blank"
|
||||||
|
href="{{ getFqdnWithoutPort(data_get($preview, 'fqdn')) }}">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||||
|
stroke-linejoin="round">
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<path d="M9 15l6 -6" />
|
||||||
|
<path d="M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464" />
|
||||||
|
<path
|
||||||
|
d="M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463" />
|
||||||
|
</svg>
|
||||||
|
PR{{ data_get($preview, 'pull_request_id') }} |
|
||||||
|
{{ data_get($preview, 'fqdn') }}
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
@endif
|
@endif
|
||||||
@if (data_get($application, 'ports_mappings_array'))
|
@if (data_get($application, 'ports_mappings_array'))
|
||||||
@foreach ($application->ports_mappings_array as $port)
|
@foreach ($application->ports_mappings_array as $port)
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
<form wire:submit="save" class="flex items-end gap-2">
|
||||||
|
<x-forms.input helper="One domain per preview." label="Domains for {{ str($serviceName)->headline() }}"
|
||||||
|
id="service.domain"></x-forms.input>
|
||||||
|
<x-forms.button type="submit">Save</x-forms.button>
|
||||||
|
<x-forms.button wire:click="generate">Generate
|
||||||
|
Domain</x-forms.button>
|
||||||
|
</form>
|
@ -42,11 +42,16 @@ class="dark:text-warning">{{ $application->destination->server->name }}</span>.<
|
|||||||
<td class="flex flex-col gap-1 md:flex-row">
|
<td class="flex flex-col gap-1 md:flex-row">
|
||||||
<x-forms.button
|
<x-forms.button
|
||||||
wire:click="add('{{ data_get($pull_request, 'number') }}', '{{ data_get($pull_request, 'html_url') }}')">
|
wire:click="add('{{ data_get($pull_request, 'number') }}', '{{ data_get($pull_request, 'html_url') }}')">
|
||||||
Add
|
Configure
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
<x-forms.button
|
<x-forms.button
|
||||||
wire:click="deploy('{{ data_get($pull_request, 'number') }}', '{{ data_get($pull_request, 'html_url') }}')">
|
wire:click="deploy('{{ data_get($pull_request, 'number') }}', '{{ data_get($pull_request, 'html_url') }}')">
|
||||||
Deploy
|
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 dark:text-warning"
|
||||||
|
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
|
||||||
|
fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<path d="M7 4v16l13 -8z" />
|
||||||
|
</svg>Deploy
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -58,7 +63,7 @@ class="dark:text-warning">{{ $application->destination->server->name }}</span>.<
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@if ($application->previews->count() > 0)
|
@if ($application->previews->count() > 0)
|
||||||
<div class="pb-4">Previews</div>
|
<h3 class="py-4">Deployed Previews</h3>
|
||||||
<div class="flex flex-wrap w-full gap-4">
|
<div class="flex flex-wrap w-full gap-4">
|
||||||
@foreach (data_get($application, 'previews') as $previewName => $preview)
|
@foreach (data_get($application, 'previews') as $previewName => $preview)
|
||||||
<div class="flex flex-col w-full p-4 border dark:border-coolgray-200">
|
<div class="flex flex-col w-full p-4 border dark:border-coolgray-200">
|
||||||
@ -81,21 +86,25 @@ class="dark:text-warning">{{ $application->destination->server->name }}</span>.<
|
|||||||
<x-external-link />
|
<x-external-link />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<form wire:submit="save_preview('{{ $preview->id }}')" class="flex items-end gap-2 pt-4">
|
|
||||||
<x-forms.input label="Domain" helper="One domain per preview."
|
@if ($application->build_pack === 'dockercompose')
|
||||||
id="application.previews.{{ $previewName }}.fqdn"></x-forms.input>
|
<div class="flex flex-col gap-4 pt-4">
|
||||||
<x-forms.button type="submit">Save</x-forms.button>
|
@foreach (collect(json_decode($preview->docker_compose_domains)) as $serviceName => $service)
|
||||||
<x-forms.button wire:click="generate_preview('{{ $preview->id }}')">Generate
|
<livewire:project.application.previews-compose wire:key="{{ $preview->id }}"
|
||||||
Domain</x-forms.button>
|
:service="$service" :serviceName="$serviceName" :preview="$preview" />
|
||||||
</form>
|
@endforeach
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
<form wire:submit="save_preview('{{ $preview->id }}')" class="flex items-end gap-2 pt-4">
|
||||||
|
<x-forms.input label="Domain" helper="One domain per preview."
|
||||||
|
id="application.previews.{{ $previewName }}.fqdn"></x-forms.input>
|
||||||
|
<x-forms.button type="submit">Save</x-forms.button>
|
||||||
|
<x-forms.button wire:click="generate_preview('{{ $preview->id }}')">Generate
|
||||||
|
Domain</x-forms.button>
|
||||||
|
</form>
|
||||||
|
@endif
|
||||||
<div class="flex items-center gap-2 pt-6">
|
<div class="flex items-center gap-2 pt-6">
|
||||||
<x-forms.button wire:click="deploy({{ data_get($preview, 'pull_request_id') }})">
|
|
||||||
@if (data_get($preview, 'status') === 'exited')
|
|
||||||
Deploy
|
|
||||||
@else
|
|
||||||
Redeploy
|
|
||||||
@endif
|
|
||||||
</x-forms.button>
|
|
||||||
@if (count($parameters) > 0)
|
@if (count($parameters) > 0)
|
||||||
<a
|
<a
|
||||||
href="{{ route('project.application.deployment.index', [...$parameters, 'pull_request_id' => data_get($preview, 'pull_request_id')]) }}">
|
href="{{ route('project.application.deployment.index', [...$parameters, 'pull_request_id' => data_get($preview, 'pull_request_id')]) }}">
|
||||||
@ -111,6 +120,27 @@ class="dark:text-warning">{{ $application->destination->server->name }}</span>.<
|
|||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
<div class="flex-1"></div>
|
<div class="flex-1"></div>
|
||||||
|
<x-forms.button wire:click="deploy({{ data_get($preview, 'pull_request_id') }})">
|
||||||
|
@if (data_get($preview, 'status') === 'exited')
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 dark:text-warning"
|
||||||
|
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none"
|
||||||
|
stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<path d="M7 4v16l13 -8z" />
|
||||||
|
</svg>
|
||||||
|
Deploy
|
||||||
|
@else
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 dark:text-orange-400"
|
||||||
|
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
|
||||||
|
stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||||
|
<path
|
||||||
|
d="M10.09 4.01l.496 -.495a2 2 0 0 1 2.828 0l7.071 7.07a2 2 0 0 1 0 2.83l-7.07 7.07a2 2 0 0 1 -2.83 0l-7.07 -7.07a2 2 0 0 1 0 -2.83l3.535 -3.535h-3.988">
|
||||||
|
</path>
|
||||||
|
<path d="M7.05 11.038v-3.988"></path>
|
||||||
|
</svg> Redeploy
|
||||||
|
@endif
|
||||||
|
</x-forms.button>
|
||||||
@if (data_get($preview, 'status') !== 'exited')
|
@if (data_get($preview, 'status') !== 'exited')
|
||||||
<x-modal-confirmation isErrorButton
|
<x-modal-confirmation isErrorButton
|
||||||
action="stop({{ data_get($preview, 'pull_request_id') }})">
|
action="stop({{ data_get($preview, 'pull_request_id') }})">
|
||||||
|
Loading…
Reference in New Issue
Block a user