Merge branch 'next' into feat/deployment-token
This commit is contained in:
@@ -44,13 +44,13 @@ function queue_application_deployment(Application $application, string $deployme
|
||||
]);
|
||||
|
||||
if ($no_questions_asked) {
|
||||
dispatch(new ApplicationDeploymentJob(
|
||||
ApplicationDeploymentJob::dispatch(
|
||||
application_deployment_queue_id: $deployment->id,
|
||||
))->onQueue('high');
|
||||
);
|
||||
} elseif (next_queuable($server_id, $application_id)) {
|
||||
dispatch(new ApplicationDeploymentJob(
|
||||
ApplicationDeploymentJob::dispatch(
|
||||
application_deployment_queue_id: $deployment->id,
|
||||
))->onQueue('high');
|
||||
);
|
||||
}
|
||||
}
|
||||
function force_start_deployment(ApplicationDeploymentQueue $deployment)
|
||||
@@ -59,9 +59,9 @@ function force_start_deployment(ApplicationDeploymentQueue $deployment)
|
||||
'status' => ApplicationDeploymentStatus::IN_PROGRESS->value,
|
||||
]);
|
||||
|
||||
dispatch(new ApplicationDeploymentJob(
|
||||
ApplicationDeploymentJob::dispatch(
|
||||
application_deployment_queue_id: $deployment->id,
|
||||
))->onQueue('high');
|
||||
);
|
||||
}
|
||||
function queue_next_deployment(Application $application)
|
||||
{
|
||||
@@ -72,9 +72,9 @@ function queue_next_deployment(Application $application)
|
||||
'status' => ApplicationDeploymentStatus::IN_PROGRESS->value,
|
||||
]);
|
||||
|
||||
dispatch(new ApplicationDeploymentJob(
|
||||
ApplicationDeploymentJob::dispatch(
|
||||
application_deployment_queue_id: $next_found->id,
|
||||
))->onQueue('high');
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ function next_queuable(string $server_id, string $application_id): bool
|
||||
$server = Server::find($server_id);
|
||||
$concurrent_builds = $server->settings->concurrent_builds;
|
||||
|
||||
ray("serverId:{$server->id}", "concurrentBuilds:{$concurrent_builds}", "deployments:{$deployments->count()}", "sameApplicationDeployments:{$same_application_deployments->count()}")->green();
|
||||
// ray("serverId:{$server->id}", "concurrentBuilds:{$concurrent_builds}", "deployments:{$deployments->count()}", "sameApplicationDeployments:{$same_application_deployments->count()}")->green();
|
||||
|
||||
if ($deployments->count() > $concurrent_builds) {
|
||||
return false;
|
||||
@@ -113,9 +113,9 @@ function next_after_cancel(?Server $server = null)
|
||||
'status' => ApplicationDeploymentStatus::IN_PROGRESS->value,
|
||||
]);
|
||||
|
||||
dispatch(new ApplicationDeploymentJob(
|
||||
ApplicationDeploymentJob::dispatch(
|
||||
application_deployment_queue_id: $next->id,
|
||||
))->onQueue('high');
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ const SPECIFIC_SERVICES = [
|
||||
|
||||
// Based on /etc/os-release
|
||||
const SUPPORTED_OS = [
|
||||
'ubuntu debian raspbian',
|
||||
'ubuntu debian raspbian pop',
|
||||
'centos fedora rhel ol rocky amzn almalinux',
|
||||
'sles opensuse-leap opensuse-tumbleweed',
|
||||
'arch',
|
||||
|
||||
@@ -109,7 +109,8 @@ function format_docker_envs_to_json($rawOutput)
|
||||
function checkMinimumDockerEngineVersion($dockerVersion)
|
||||
{
|
||||
$majorDockerVersion = str($dockerVersion)->before('.')->value();
|
||||
if ($majorDockerVersion <= 22) {
|
||||
$requiredDockerVersion = str(config('constants.docker.minimum_required_version'))->before('.')->value();
|
||||
if ($majorDockerVersion < $requiredDockerVersion) {
|
||||
$dockerVersion = null;
|
||||
}
|
||||
|
||||
@@ -191,7 +192,7 @@ function defaultLabels($id, $name, $pull_request_id = 0, string $type = 'applica
|
||||
{
|
||||
$labels = collect([]);
|
||||
$labels->push('coolify.managed=true');
|
||||
$labels->push('coolify.version='.config('version'));
|
||||
$labels->push('coolify.version='.config('constants.coolify.version'));
|
||||
$labels->push('coolify.'.$type.'Id='.$id);
|
||||
$labels->push("coolify.type=$type");
|
||||
$labels->push('coolify.name='.$name);
|
||||
@@ -225,16 +226,18 @@ function generateServiceSpecificFqdns(ServiceApplication|Application $resource)
|
||||
case $type?->contains('minio'):
|
||||
$MINIO_BROWSER_REDIRECT_URL = $variables->where('key', 'MINIO_BROWSER_REDIRECT_URL')->first();
|
||||
$MINIO_SERVER_URL = $variables->where('key', 'MINIO_SERVER_URL')->first();
|
||||
|
||||
if (is_null($MINIO_BROWSER_REDIRECT_URL) || is_null($MINIO_SERVER_URL)) {
|
||||
return $payload;
|
||||
return collect([]);
|
||||
}
|
||||
if (is_null($MINIO_BROWSER_REDIRECT_URL?->value)) {
|
||||
$MINIO_BROWSER_REDIRECT_URL?->update([
|
||||
|
||||
if (str($MINIO_BROWSER_REDIRECT_URL->value ?? '')->isEmpty()) {
|
||||
$MINIO_BROWSER_REDIRECT_URL->update([
|
||||
'value' => generateFqdn($server, 'console-'.$uuid, true),
|
||||
]);
|
||||
}
|
||||
if (is_null($MINIO_SERVER_URL?->value)) {
|
||||
$MINIO_SERVER_URL?->update([
|
||||
if (str($MINIO_SERVER_URL->value ?? '')->isEmpty()) {
|
||||
$MINIO_SERVER_URL->update([
|
||||
'value' => generateFqdn($server, 'minio-'.$uuid, true),
|
||||
]);
|
||||
}
|
||||
@@ -246,16 +249,18 @@ function generateServiceSpecificFqdns(ServiceApplication|Application $resource)
|
||||
case $type?->contains('logto'):
|
||||
$LOGTO_ENDPOINT = $variables->where('key', 'LOGTO_ENDPOINT')->first();
|
||||
$LOGTO_ADMIN_ENDPOINT = $variables->where('key', 'LOGTO_ADMIN_ENDPOINT')->first();
|
||||
|
||||
if (is_null($LOGTO_ENDPOINT) || is_null($LOGTO_ADMIN_ENDPOINT)) {
|
||||
return $payload;
|
||||
return collect([]);
|
||||
}
|
||||
if (is_null($LOGTO_ENDPOINT?->value)) {
|
||||
$LOGTO_ENDPOINT?->update([
|
||||
|
||||
if (str($LOGTO_ENDPOINT->value ?? '')->isEmpty()) {
|
||||
$LOGTO_ENDPOINT->update([
|
||||
'value' => generateFqdn($server, 'logto-'.$uuid),
|
||||
]);
|
||||
}
|
||||
if (is_null($LOGTO_ADMIN_ENDPOINT?->value)) {
|
||||
$LOGTO_ADMIN_ENDPOINT?->update([
|
||||
if (str($LOGTO_ADMIN_ENDPOINT->value ?? '')->isEmpty()) {
|
||||
$LOGTO_ADMIN_ENDPOINT->update([
|
||||
'value' => generateFqdn($server, 'logto-admin-'.$uuid),
|
||||
]);
|
||||
}
|
||||
@@ -283,6 +288,10 @@ function fqdnLabelsForCaddy(string $network, string $uuid, Collection $domains,
|
||||
$host_without_www = str($host)->replace('www.', '');
|
||||
$schema = $url->getScheme();
|
||||
$port = $url->getPort();
|
||||
$handle = 'handle_path';
|
||||
if (! $is_stripprefix_enabled) {
|
||||
$handle = 'handle';
|
||||
}
|
||||
if (is_null($port) && ! is_null($onlyPort)) {
|
||||
$port = $onlyPort;
|
||||
}
|
||||
@@ -294,11 +303,11 @@ function fqdnLabelsForCaddy(string $network, string $uuid, Collection $domains,
|
||||
$labels->push("caddy_{$loop}.try_files={path} /index.html /index.php");
|
||||
|
||||
if ($port) {
|
||||
$labels->push("caddy_{$loop}.handle_path.{$loop}_reverse_proxy={{upstreams $port}}");
|
||||
$labels->push("caddy_{$loop}.{$handle}.{$loop}_reverse_proxy={{upstreams $port}}");
|
||||
} else {
|
||||
$labels->push("caddy_{$loop}.handle_path.{$loop}_reverse_proxy={{upstreams}}");
|
||||
$labels->push("caddy_{$loop}.{$handle}.{$loop}_reverse_proxy={{upstreams}}");
|
||||
}
|
||||
$labels->push("caddy_{$loop}.handle_path={$path}*");
|
||||
$labels->push("caddy_{$loop}.{$handle}={$path}*");
|
||||
if ($is_gzip_enabled) {
|
||||
$labels->push("caddy_{$loop}.encode=zstd gzip");
|
||||
}
|
||||
@@ -359,8 +368,11 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
$https_label = "https-{$loop}-{$uuid}-{$service_name}";
|
||||
}
|
||||
if (str($image)->contains('ghost')) {
|
||||
$labels->push("traefik.http.middlewares.redir-ghost.redirectregex.regex=^{$path}/(.*)");
|
||||
$labels->push('traefik.http.middlewares.redir-ghost.redirectregex.replacement=/$1');
|
||||
$labels->push("traefik.http.middlewares.redir-ghost-{$uuid}.redirectregex.regex=^{$path}/(.*)");
|
||||
$labels->push("traefik.http.middlewares.redir-ghost-{$uuid}.redirectregex.replacement=/$1");
|
||||
$labels->push("caddy_{$loop}.handle_path.{$loop}_redir-ghost-{$uuid}.handler=rewrite");
|
||||
$labels->push("caddy_{$loop}.handle_path.{$loop}_redir-ghost-{$uuid}.rewrite.regexp=^{$path}/(.*)");
|
||||
$labels->push("caddy_{$loop}.handle_path.{$loop}_redir-ghost-{$uuid}.rewrite.replacement=/$1");
|
||||
}
|
||||
|
||||
$to_www_name = "{$loop}-{$uuid}-to-www";
|
||||
@@ -394,7 +406,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
$middlewares->push('gzip');
|
||||
}
|
||||
if (str($image)->contains('ghost')) {
|
||||
$middlewares->push('redir-ghost');
|
||||
$middlewares->push("redir-ghost-{$uuid}");
|
||||
}
|
||||
if ($redirect_direction === 'non-www' && str($host)->startsWith('www.')) {
|
||||
$labels = $labels->merge($redirect_to_non_www);
|
||||
@@ -417,7 +429,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
$middlewares->push('gzip');
|
||||
}
|
||||
if (str($image)->contains('ghost')) {
|
||||
$middlewares->push('redir-ghost');
|
||||
$middlewares->push("redir-ghost-{$uuid}");
|
||||
}
|
||||
if ($redirect_direction === 'non-www' && str($host)->startsWith('www.')) {
|
||||
$labels = $labels->merge($redirect_to_non_www);
|
||||
@@ -466,7 +478,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
$middlewares->push('gzip');
|
||||
}
|
||||
if (str($image)->contains('ghost')) {
|
||||
$middlewares->push('redir-ghost');
|
||||
$middlewares->push("redir-ghost-{$uuid}");
|
||||
}
|
||||
if ($redirect_direction === 'non-www' && str($host)->startsWith('www.')) {
|
||||
$labels = $labels->merge($redirect_to_non_www);
|
||||
@@ -489,7 +501,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
|
||||
$middlewares->push('gzip');
|
||||
}
|
||||
if (str($image)->contains('ghost')) {
|
||||
$middlewares->push('redir-ghost');
|
||||
$middlewares->push("redir-ghost-{$uuid}");
|
||||
}
|
||||
if ($redirect_direction === 'non-www' && str($host)->startsWith('www.')) {
|
||||
$labels = $labels->merge($redirect_to_non_www);
|
||||
@@ -654,7 +666,7 @@ function isDatabaseImage(?string $image = null)
|
||||
return false;
|
||||
}
|
||||
|
||||
function convert_docker_run_to_compose(?string $custom_docker_run_options = null)
|
||||
function convertDockerRunToCompose(?string $custom_docker_run_options = null)
|
||||
{
|
||||
$options = [];
|
||||
$compose_options = collect([]);
|
||||
@@ -679,9 +691,17 @@ function convert_docker_run_to_compose(?string $custom_docker_run_options = null
|
||||
'--privileged' => 'privileged',
|
||||
'--ip' => 'ip',
|
||||
'--shm-size' => 'shm_size',
|
||||
'--gpus' => 'gpus',
|
||||
]);
|
||||
foreach ($matches as $match) {
|
||||
$option = $match[1];
|
||||
if ($option === '--gpus') {
|
||||
$regexForParsingDeviceIds = '/device=([0-9A-Za-z-,]+)/';
|
||||
preg_match($regexForParsingDeviceIds, $custom_docker_run_options, $device_matches);
|
||||
$value = $device_matches[1] ?? 'all';
|
||||
$options[$option][] = $value;
|
||||
$options[$option] = array_unique($options[$option]);
|
||||
}
|
||||
if (isset($match[2]) && $match[2] !== '') {
|
||||
$value = $match[2];
|
||||
$options[$option][] = $value;
|
||||
@@ -694,7 +714,6 @@ function convert_docker_run_to_compose(?string $custom_docker_run_options = null
|
||||
$options = collect($options);
|
||||
// Easily get mappings from https://github.com/composerize/composerize/blob/master/packages/composerize/src/mappings.js
|
||||
foreach ($options as $option => $value) {
|
||||
// ray($option,$value);
|
||||
if (! data_get($mapping, $option)) {
|
||||
continue;
|
||||
}
|
||||
@@ -723,6 +742,28 @@ function convert_docker_run_to_compose(?string $custom_docker_run_options = null
|
||||
if (! is_null($value) && is_array($value) && count($value) > 0) {
|
||||
$compose_options->put($mapping[$option], $value[0]);
|
||||
}
|
||||
} elseif ($option === '--gpus') {
|
||||
$payload = [
|
||||
'driver' => 'nvidia',
|
||||
'capabilities' => ['gpu'],
|
||||
];
|
||||
if (! is_null($value) && is_array($value) && count($value) > 0) {
|
||||
if (str($value[0]) != 'all') {
|
||||
if (str($value[0])->contains(',')) {
|
||||
$payload['device_ids'] = str($value[0])->explode(',')->toArray();
|
||||
} else {
|
||||
$payload['device_ids'] = [$value[0]];
|
||||
}
|
||||
}
|
||||
}
|
||||
ray($payload);
|
||||
$compose_options->put('deploy', [
|
||||
'resources' => [
|
||||
'reservations' => [
|
||||
'devices' => [$payload],
|
||||
],
|
||||
],
|
||||
]);
|
||||
} else {
|
||||
if ($list_options->contains($option)) {
|
||||
if ($compose_options->has($mapping[$option])) {
|
||||
@@ -744,7 +785,7 @@ function convert_docker_run_to_compose(?string $custom_docker_run_options = null
|
||||
return $compose_options->toArray();
|
||||
}
|
||||
|
||||
function generate_custom_docker_run_options_for_databases($docker_run_options, $docker_compose, $container_name, $network)
|
||||
function generateCustomDockerRunOptionsForDatabases($docker_run_options, $docker_compose, $container_name, $network)
|
||||
{
|
||||
$ipv4 = data_get($docker_run_options, 'ip.0');
|
||||
$ipv6 = data_get($docker_run_options, 'ip6.0');
|
||||
|
||||
@@ -173,13 +173,12 @@ function generate_default_proxy_configuration(Server $server)
|
||||
],
|
||||
'volumes' => [
|
||||
'/var/run/docker.sock:/var/run/docker.sock:ro',
|
||||
"{$proxy_path}:/traefik",
|
||||
|
||||
],
|
||||
'command' => [
|
||||
'--ping=true',
|
||||
'--ping.entrypoint=http',
|
||||
'--api.dashboard=true',
|
||||
'--api.insecure=false',
|
||||
'--entrypoints.http.address=:80',
|
||||
'--entrypoints.https.address=:443',
|
||||
'--entrypoints.http.http.encodequerysemicolons=true',
|
||||
@@ -187,21 +186,26 @@ function generate_default_proxy_configuration(Server $server)
|
||||
'--entrypoints.https.http.encodequerysemicolons=true',
|
||||
'--entryPoints.https.http2.maxConcurrentStreams=50',
|
||||
'--entrypoints.https.http3',
|
||||
'--providers.docker.exposedbydefault=false',
|
||||
'--providers.file.directory=/traefik/dynamic/',
|
||||
'--providers.docker.exposedbydefault=false',
|
||||
'--providers.file.watch=true',
|
||||
'--certificatesresolvers.letsencrypt.acme.httpchallenge=true',
|
||||
'--certificatesresolvers.letsencrypt.acme.storage=/traefik/acme.json',
|
||||
'--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http',
|
||||
'--certificatesresolvers.letsencrypt.acme.storage=/traefik/acme.json',
|
||||
],
|
||||
'labels' => $labels,
|
||||
],
|
||||
],
|
||||
];
|
||||
if (isDev()) {
|
||||
// $config['services']['traefik']['command'][] = "--log.level=debug";
|
||||
$config['services']['traefik']['command'][] = '--api.insecure=true';
|
||||
$config['services']['traefik']['command'][] = '--log.level=debug';
|
||||
$config['services']['traefik']['command'][] = '--accesslog.filepath=/traefik/access.log';
|
||||
$config['services']['traefik']['command'][] = '--accesslog.bufferingsize=100';
|
||||
$config['services']['traefik']['volumes'][] = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/proxy/:/traefik';
|
||||
} else {
|
||||
$config['services']['traefik']['command'][] = '--api.insecure=false';
|
||||
$config['services']['traefik']['volumes'][] = "{$proxy_path}:/traefik";
|
||||
}
|
||||
if ($server->isSwarm()) {
|
||||
data_forget($config, 'services.traefik.container_name');
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Models\Application;
|
||||
use App\Models\ApplicationDeploymentQueue;
|
||||
use App\Models\ApplicationPreview;
|
||||
use App\Models\EnvironmentVariable;
|
||||
use App\Models\GithubApp;
|
||||
use App\Models\InstanceSettings;
|
||||
use App\Models\LocalFileVolume;
|
||||
use App\Models\LocalPersistentVolume;
|
||||
@@ -26,6 +27,7 @@ use App\Models\Team;
|
||||
use App\Models\User;
|
||||
use App\Notifications\Channels\DiscordChannel;
|
||||
use App\Notifications\Channels\EmailChannel;
|
||||
use App\Notifications\Channels\SlackChannel;
|
||||
use App\Notifications\Channels\TelegramChannel;
|
||||
use App\Notifications\Internal\GeneralNotification;
|
||||
use Carbon\CarbonImmutable;
|
||||
@@ -35,6 +37,7 @@ use Illuminate\Mail\Message;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Process\Pool;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
@@ -88,8 +91,31 @@ function metrics_dir(): string
|
||||
return base_configuration_dir().'/metrics';
|
||||
}
|
||||
|
||||
function sanitize_string(?string $input = null): ?string
|
||||
{
|
||||
if (is_null($input)) {
|
||||
return null;
|
||||
}
|
||||
// Remove any HTML/PHP tags
|
||||
$sanitized = strip_tags($input);
|
||||
|
||||
// Convert special characters to HTML entities
|
||||
$sanitized = htmlspecialchars($sanitized, ENT_QUOTES | ENT_HTML5, 'UTF-8');
|
||||
|
||||
// Remove any control characters
|
||||
$sanitized = preg_replace('/[\x00-\x1F\x7F]/u', '', $sanitized);
|
||||
|
||||
// Trim whitespace
|
||||
$sanitized = trim($sanitized);
|
||||
|
||||
return $sanitized;
|
||||
}
|
||||
|
||||
function generate_readme_file(string $name, string $updated_at): string
|
||||
{
|
||||
$name = sanitize_string($name);
|
||||
$updated_at = sanitize_string($updated_at);
|
||||
|
||||
return "Resource name: $name\nLatest Deployment Date: $updated_at";
|
||||
}
|
||||
|
||||
@@ -100,12 +126,12 @@ function isInstanceAdmin()
|
||||
|
||||
function currentTeam()
|
||||
{
|
||||
return auth()?->user()?->currentTeam() ?? null;
|
||||
return Auth::user()?->currentTeam() ?? null;
|
||||
}
|
||||
|
||||
function showBoarding(): bool
|
||||
{
|
||||
if (auth()->user()?->isMember()) {
|
||||
if (Auth::user()?->isMember()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -114,14 +140,14 @@ function showBoarding(): bool
|
||||
function refreshSession(?Team $team = null): void
|
||||
{
|
||||
if (! $team) {
|
||||
if (auth()->user()?->currentTeam()) {
|
||||
$team = Team::find(auth()->user()->currentTeam()->id);
|
||||
if (Auth::user()->currentTeam()) {
|
||||
$team = Team::find(Auth::user()->currentTeam()->id);
|
||||
} else {
|
||||
$team = User::find(auth()->user()->id)->teams->first();
|
||||
$team = User::find(Auth::id())->teams->first();
|
||||
}
|
||||
}
|
||||
Cache::forget('team:'.auth()->user()->id);
|
||||
Cache::remember('team:'.auth()->user()->id, 3600, function () use ($team) {
|
||||
Cache::forget('team:'.Auth::id());
|
||||
Cache::remember('team:'.Auth::id(), 3600, function () use ($team) {
|
||||
return $team;
|
||||
});
|
||||
session(['currentTeam' => $team]);
|
||||
@@ -357,7 +383,7 @@ function isDev(): bool
|
||||
|
||||
function isCloud(): bool
|
||||
{
|
||||
return ! config('coolify.self_hosted');
|
||||
return ! config('constants.coolify.self_hosted');
|
||||
}
|
||||
|
||||
function translate_cron_expression($expression_to_validate): string
|
||||
@@ -383,6 +409,11 @@ function validate_cron_expression($expression_to_validate): bool
|
||||
|
||||
return $isValid;
|
||||
}
|
||||
|
||||
function validate_timezone(string $timezone): bool
|
||||
{
|
||||
return in_array($timezone, timezone_identifiers_list());
|
||||
}
|
||||
function send_internal_notification(string $message): void
|
||||
{
|
||||
try {
|
||||
@@ -439,11 +470,13 @@ function setNotificationChannels($notifiable, $event)
|
||||
{
|
||||
$channels = [];
|
||||
$isEmailEnabled = isEmailEnabled($notifiable);
|
||||
$isSlackEnabled = data_get($notifiable, 'slack_enabled');
|
||||
$isDiscordEnabled = data_get($notifiable, 'discord_enabled');
|
||||
$isTelegramEnabled = data_get($notifiable, 'telegram_enabled');
|
||||
$isSubscribedToEmailEvent = data_get($notifiable, "smtp_notifications_$event");
|
||||
$isSubscribedToDiscordEvent = data_get($notifiable, "discord_notifications_$event");
|
||||
$isSubscribedToTelegramEvent = data_get($notifiable, "telegram_notifications_$event");
|
||||
$isSubscribedToSlackEvent = data_get($notifiable, "slack_notifications_$event");
|
||||
|
||||
if ($isDiscordEnabled && $isSubscribedToDiscordEvent) {
|
||||
$channels[] = DiscordChannel::class;
|
||||
@@ -454,6 +487,9 @@ function setNotificationChannels($notifiable, $event)
|
||||
if ($isTelegramEnabled && $isSubscribedToTelegramEvent) {
|
||||
$channels[] = TelegramChannel::class;
|
||||
}
|
||||
if ($isSlackEnabled && $isSubscribedToSlackEvent) {
|
||||
$channels[] = SlackChannel::class;
|
||||
}
|
||||
|
||||
return $channels;
|
||||
}
|
||||
@@ -933,6 +969,15 @@ function generateEnvValue(string $command, Service|Application|null $service = n
|
||||
case 'REALBASE64_32':
|
||||
$generatedValue = base64_encode(Str::random(32));
|
||||
break;
|
||||
case 'HEX_32':
|
||||
$generatedValue = bin2hex(Str::random(32));
|
||||
break;
|
||||
case 'HEX_64':
|
||||
$generatedValue = bin2hex(Str::random(64));
|
||||
break;
|
||||
case 'HEX_128':
|
||||
$generatedValue = bin2hex(Str::random(128));
|
||||
break;
|
||||
case 'USER':
|
||||
$generatedValue = Str::random(16);
|
||||
break;
|
||||
@@ -987,7 +1032,7 @@ function generateEnvValue(string $command, Service|Application|null $service = n
|
||||
|
||||
function getRealtime()
|
||||
{
|
||||
$envDefined = env('PUSHER_PORT');
|
||||
$envDefined = config('constants.pusher.port');
|
||||
if (empty($envDefined)) {
|
||||
$url = Url::fromString(Request::getSchemeAndHttpHost());
|
||||
$port = $url->getPort();
|
||||
@@ -4061,3 +4106,83 @@ function isEmailRateLimited(string $limiterKey, int $decaySeconds = 3600, ?calla
|
||||
|
||||
return $rateLimited;
|
||||
}
|
||||
|
||||
function defaultNginxConfiguration(): string
|
||||
{
|
||||
return 'server {
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
try_files $uri $uri.html $uri/index.html $uri/index.htm $uri/ /index.html /index.htm =404;
|
||||
}
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
try_files $uri @redirect_to_index;
|
||||
internal;
|
||||
}
|
||||
|
||||
error_page 404 = @handle_404;
|
||||
|
||||
location @handle_404 {
|
||||
root /usr/share/nginx/html;
|
||||
try_files /404.html @redirect_to_index;
|
||||
internal;
|
||||
}
|
||||
|
||||
location @redirect_to_index {
|
||||
return 302 /;
|
||||
}
|
||||
}';
|
||||
}
|
||||
|
||||
function convertGitUrl(string $gitRepository, string $deploymentType, ?GithubApp $source = null): array
|
||||
{
|
||||
$repository = $gitRepository;
|
||||
$providerInfo = [
|
||||
'host' => null,
|
||||
'user' => 'git',
|
||||
'port' => 22,
|
||||
'repository' => $gitRepository,
|
||||
];
|
||||
$sshMatches = [];
|
||||
$matches = [];
|
||||
|
||||
// Let's try and parse the string to detect if it's a valid SSH string or not
|
||||
preg_match('/((.*?)\:\/\/)?(.*@.*:.*)/', $gitRepository, $sshMatches);
|
||||
|
||||
if ($deploymentType === 'deploy_key' && empty($sshMatches) && $source) {
|
||||
// If this happens, the user may have provided an HTTP URL when they needed an SSH one
|
||||
// Let's try and fix that for known Git providers
|
||||
switch ($source->getMorphClass()) {
|
||||
case \App\Models\GithubApp::class:
|
||||
$providerInfo['host'] = Url::fromString($source->html_url)->getHost();
|
||||
$providerInfo['port'] = $source->custom_port;
|
||||
$providerInfo['user'] = $source->custom_user;
|
||||
break;
|
||||
}
|
||||
if (! empty($providerInfo['host'])) {
|
||||
// Until we do not support more providers with App (like GithubApp), this will be always true, port will be 22
|
||||
if ($providerInfo['port'] === 22) {
|
||||
$repository = "{$providerInfo['user']}@{$providerInfo['host']}:{$providerInfo['repository']}";
|
||||
} else {
|
||||
$repository = "ssh://{$providerInfo['user']}@{$providerInfo['host']}:{$providerInfo['port']}/{$providerInfo['repository']}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
preg_match('/(?<=:)\d+(?=\/)/', $gitRepository, $matches);
|
||||
|
||||
if (count($matches) === 1) {
|
||||
$providerInfo['port'] = $matches[0];
|
||||
$gitHost = str($gitRepository)->before(':');
|
||||
$gitRepo = str($gitRepository)->after('/');
|
||||
$repository = "$gitHost:$gitRepo";
|
||||
}
|
||||
|
||||
return [
|
||||
'repository' => $repository,
|
||||
'port' => $providerInfo['port'],
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user