diff --git a/app/Http/Controllers/Api/ApplicationsController.php b/app/Http/Controllers/Api/ApplicationsController.php index 74542ac67..143ba64d3 100644 --- a/app/Http/Controllers/Api/ApplicationsController.php +++ b/app/Http/Controllers/Api/ApplicationsController.php @@ -158,6 +158,9 @@ public function applications(Request $request) 'docker_registry_image_name' => ['type' => 'string', 'description' => 'The docker registry image name.'], 'docker_registry_image_tag' => ['type' => 'string', 'description' => 'The docker registry image tag.'], 'is_static' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application is static.'], + 'is_spa' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application is a single-page application (SPA). Only relevant when is_static is true.'], + 'is_auto_deploy_enabled' => ['type' => 'boolean', 'description' => 'The flag to indicate if auto-deploy is enabled on git push. Defaults to true.'], + 'is_force_https_enabled' => ['type' => 'boolean', 'description' => 'The flag to indicate if HTTPS is forced. Defaults to true.'], 'static_image' => ['type' => 'string', 'enum' => ['nginx:alpine'], 'description' => 'The static image.'], 'install_command' => ['type' => 'string', 'description' => 'The install command.'], 'build_command' => ['type' => 'string', 'description' => 'The build command.'], @@ -198,6 +201,7 @@ public function applications(Request $request) // 'github_app_uuid' => ['type' => 'string', 'description' => 'The Github App UUID.'], 'instant_deploy' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application should be deployed instantly.'], 'dockerfile' => ['type' => 'string', 'description' => 'The Dockerfile content.'], + 'dockerfile_location' => ['type' => 'string', 'description' => 'The Dockerfile location in the repository.'], 'docker_compose_location' => ['type' => 'string', 'description' => 'The Docker Compose location.'], 'docker_compose_custom_start_command' => ['type' => 'string', 'description' => 'The Docker Compose custom start command.'], 'docker_compose_custom_build_command' => ['type' => 'string', 'description' => 'The Docker Compose custom build command.'], @@ -320,6 +324,9 @@ public function create_public_application(Request $request) 'docker_registry_image_name' => ['type' => 'string', 'description' => 'The docker registry image name.'], 'docker_registry_image_tag' => ['type' => 'string', 'description' => 'The docker registry image tag.'], 'is_static' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application is static.'], + 'is_spa' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application is a single-page application (SPA). Only relevant when is_static is true.'], + 'is_auto_deploy_enabled' => ['type' => 'boolean', 'description' => 'The flag to indicate if auto-deploy is enabled on git push. Defaults to true.'], + 'is_force_https_enabled' => ['type' => 'boolean', 'description' => 'The flag to indicate if HTTPS is forced. Defaults to true.'], 'static_image' => ['type' => 'string', 'enum' => ['nginx:alpine'], 'description' => 'The static image.'], 'install_command' => ['type' => 'string', 'description' => 'The install command.'], 'build_command' => ['type' => 'string', 'description' => 'The build command.'], @@ -359,6 +366,7 @@ public function create_public_application(Request $request) 'redirect' => ['type' => 'string', 'nullable' => true, 'description' => 'How to set redirect with Traefik / Caddy. www<->non-www.', 'enum' => ['www', 'non-www', 'both']], 'instant_deploy' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application should be deployed instantly.'], 'dockerfile' => ['type' => 'string', 'description' => 'The Dockerfile content.'], + 'dockerfile_location' => ['type' => 'string', 'description' => 'The Dockerfile location in the repository'], 'docker_compose_location' => ['type' => 'string', 'description' => 'The Docker Compose location.'], 'docker_compose_custom_start_command' => ['type' => 'string', 'description' => 'The Docker Compose custom start command.'], 'docker_compose_custom_build_command' => ['type' => 'string', 'description' => 'The Docker Compose custom build command.'], @@ -481,6 +489,9 @@ public function create_private_gh_app_application(Request $request) 'docker_registry_image_name' => ['type' => 'string', 'description' => 'The docker registry image name.'], 'docker_registry_image_tag' => ['type' => 'string', 'description' => 'The docker registry image tag.'], 'is_static' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application is static.'], + 'is_spa' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application is a single-page application (SPA). Only relevant when is_static is true.'], + 'is_auto_deploy_enabled' => ['type' => 'boolean', 'description' => 'The flag to indicate if auto-deploy is enabled on git push. Defaults to true.'], + 'is_force_https_enabled' => ['type' => 'boolean', 'description' => 'The flag to indicate if HTTPS is forced. Defaults to true.'], 'static_image' => ['type' => 'string', 'enum' => ['nginx:alpine'], 'description' => 'The static image.'], 'install_command' => ['type' => 'string', 'description' => 'The install command.'], 'build_command' => ['type' => 'string', 'description' => 'The build command.'], @@ -520,6 +531,7 @@ public function create_private_gh_app_application(Request $request) 'redirect' => ['type' => 'string', 'nullable' => true, 'description' => 'How to set redirect with Traefik / Caddy. www<->non-www.', 'enum' => ['www', 'non-www', 'both']], 'instant_deploy' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application should be deployed instantly.'], 'dockerfile' => ['type' => 'string', 'description' => 'The Dockerfile content.'], + 'dockerfile_location' => ['type' => 'string', 'description' => 'The Dockerfile location in the repository.'], 'docker_compose_location' => ['type' => 'string', 'description' => 'The Docker Compose location.'], 'docker_compose_custom_start_command' => ['type' => 'string', 'description' => 'The Docker Compose custom start command.'], 'docker_compose_custom_build_command' => ['type' => 'string', 'description' => 'The Docker Compose custom build command.'], @@ -671,6 +683,7 @@ public function create_private_deploy_key_application(Request $request) 'manual_webhook_secret_gitea' => ['type' => 'string', 'description' => 'Manual webhook secret for Gitea.'], 'redirect' => ['type' => 'string', 'nullable' => true, 'description' => 'How to set redirect with Traefik / Caddy. www<->non-www.', 'enum' => ['www', 'non-www', 'both']], 'instant_deploy' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application should be deployed instantly.'], + 'is_force_https_enabled' => ['type' => 'boolean', 'description' => 'The flag to indicate if HTTPS is forced. Defaults to true.'], 'use_build_server' => ['type' => 'boolean', 'nullable' => true, 'description' => 'Use build server.'], 'is_http_basic_auth_enabled' => ['type' => 'boolean', 'description' => 'HTTP Basic Authentication enabled.'], 'http_basic_auth_username' => ['type' => 'string', 'nullable' => true, 'description' => 'Username for HTTP Basic Authentication'], @@ -804,6 +817,7 @@ public function create_dockerfile_application(Request $request) 'manual_webhook_secret_gitea' => ['type' => 'string', 'description' => 'Manual webhook secret for Gitea.'], 'redirect' => ['type' => 'string', 'nullable' => true, 'description' => 'How to set redirect with Traefik / Caddy. www<->non-www.', 'enum' => ['www', 'non-www', 'both']], 'instant_deploy' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application should be deployed instantly.'], + 'is_force_https_enabled' => ['type' => 'boolean', 'description' => 'The flag to indicate if HTTPS is forced. Defaults to true.'], 'use_build_server' => ['type' => 'boolean', 'nullable' => true, 'description' => 'Use build server.'], 'is_http_basic_auth_enabled' => ['type' => 'boolean', 'description' => 'HTTP Basic Authentication enabled.'], 'http_basic_auth_username' => ['type' => 'string', 'nullable' => true, 'description' => 'Username for HTTP Basic Authentication'], @@ -987,7 +1001,7 @@ private function create_application(Request $request, $type) if ($return instanceof \Illuminate\Http\JsonResponse) { return $return; } - $allowedFields = ['project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'type', 'name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'private_key_uuid', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'custom_network_aliases', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'redirect', 'github_app_uuid', 'instant_deploy', 'dockerfile', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'watch_paths', 'use_build_server', 'static_image', 'custom_nginx_configuration', 'is_http_basic_auth_enabled', 'http_basic_auth_username', 'http_basic_auth_password', 'connect_to_docker_network', 'force_domain_override', 'autogenerate_domain', 'is_container_label_escape_enabled']; + $allowedFields = ['project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'type', 'name', 'description', 'is_static', 'is_spa', 'is_auto_deploy_enabled', 'is_force_https_enabled', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'private_key_uuid', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'custom_network_aliases', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'redirect', 'github_app_uuid', 'instant_deploy', 'dockerfile', 'dockerfile_location', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'watch_paths', 'use_build_server', 'static_image', 'custom_nginx_configuration', 'is_http_basic_auth_enabled', 'http_basic_auth_username', 'http_basic_auth_password', 'connect_to_docker_network', 'force_domain_override', 'autogenerate_domain', 'is_container_label_escape_enabled']; $validator = customApiValidator($request->all(), [ 'name' => 'string|max:255', @@ -1030,6 +1044,9 @@ private function create_application(Request $request, $type) $githubAppUuid = $request->github_app_uuid; $useBuildServer = $request->use_build_server; $isStatic = $request->is_static; + $isSpa = $request->is_spa; + $isAutoDeployEnabled = $request->is_auto_deploy_enabled; + $isForceHttpsEnabled = $request->is_force_https_enabled; $connectToDockerNetwork = $request->connect_to_docker_network; $customNginxConfiguration = $request->custom_nginx_configuration; $isContainerLabelEscapeEnabled = $request->boolean('is_container_label_escape_enabled', true); @@ -1211,6 +1228,18 @@ private function create_application(Request $request, $type) $application->settings->is_static = $isStatic; $application->settings->save(); } + if (isset($isSpa)) { + $application->settings->is_spa = $isSpa; + $application->settings->save(); + } + if (isset($isAutoDeployEnabled)) { + $application->settings->is_auto_deploy_enabled = $isAutoDeployEnabled; + $application->settings->save(); + } + if (isset($isForceHttpsEnabled)) { + $application->settings->is_force_https_enabled = $isForceHttpsEnabled; + $application->settings->save(); + } if (isset($connectToDockerNetwork)) { $application->settings->connect_to_docker_network = $connectToDockerNetwork; $application->settings->save(); @@ -1428,6 +1457,18 @@ private function create_application(Request $request, $type) $application->settings->is_static = $isStatic; $application->settings->save(); } + if (isset($isSpa)) { + $application->settings->is_spa = $isSpa; + $application->settings->save(); + } + if (isset($isAutoDeployEnabled)) { + $application->settings->is_auto_deploy_enabled = $isAutoDeployEnabled; + $application->settings->save(); + } + if (isset($isForceHttpsEnabled)) { + $application->settings->is_force_https_enabled = $isForceHttpsEnabled; + $application->settings->save(); + } if (isset($connectToDockerNetwork)) { $application->settings->connect_to_docker_network = $connectToDockerNetwork; $application->settings->save(); @@ -1613,6 +1654,18 @@ private function create_application(Request $request, $type) $application->settings->is_static = $isStatic; $application->settings->save(); } + if (isset($isSpa)) { + $application->settings->is_spa = $isSpa; + $application->settings->save(); + } + if (isset($isAutoDeployEnabled)) { + $application->settings->is_auto_deploy_enabled = $isAutoDeployEnabled; + $application->settings->save(); + } + if (isset($isForceHttpsEnabled)) { + $application->settings->is_force_https_enabled = $isForceHttpsEnabled; + $application->settings->save(); + } if (isset($connectToDockerNetwork)) { $application->settings->connect_to_docker_network = $connectToDockerNetwork; $application->settings->save(); @@ -1719,6 +1772,11 @@ private function create_application(Request $request, $type) if ($autogenerateDomain && blank($fqdn)) { $application->fqdn = generateUrl(server: $server, random: $application->uuid); $application->save(); + } + if (isset($isForceHttpsEnabled)) { + $application->settings->is_force_https_enabled = $isForceHttpsEnabled; + $application->settings->save(); + } if (isset($connectToDockerNetwork)) { $application->settings->connect_to_docker_network = $connectToDockerNetwork; $application->settings->save(); @@ -1824,6 +1882,11 @@ private function create_application(Request $request, $type) if ($autogenerateDomain && blank($fqdn)) { $application->fqdn = generateUrl(server: $server, random: $application->uuid); $application->save(); + } + if (isset($isForceHttpsEnabled)) { + $application->settings->is_force_https_enabled = $isForceHttpsEnabled; + $application->settings->save(); + } if (isset($connectToDockerNetwork)) { $application->settings->connect_to_docker_network = $connectToDockerNetwork; $application->settings->save(); @@ -2249,6 +2312,9 @@ public function delete_by_uuid(Request $request) 'docker_registry_image_name' => ['type' => 'string', 'description' => 'The docker registry image name.'], 'docker_registry_image_tag' => ['type' => 'string', 'description' => 'The docker registry image tag.'], 'is_static' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application is static.'], + 'is_spa' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application is a single-page application (SPA). Only relevant when is_static is true.'], + 'is_auto_deploy_enabled' => ['type' => 'boolean', 'description' => 'The flag to indicate if auto-deploy is enabled on git push. Defaults to true.'], + 'is_force_https_enabled' => ['type' => 'boolean', 'description' => 'The flag to indicate if HTTPS is forced. Defaults to true.'], 'install_command' => ['type' => 'string', 'description' => 'The install command.'], 'build_command' => ['type' => 'string', 'description' => 'The build command.'], 'start_command' => ['type' => 'string', 'description' => 'The start command.'], @@ -2287,6 +2353,7 @@ public function delete_by_uuid(Request $request) 'redirect' => ['type' => 'string', 'nullable' => true, 'description' => 'How to set redirect with Traefik / Caddy. www<->non-www.', 'enum' => ['www', 'non-www', 'both']], 'instant_deploy' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application should be deployed instantly.'], 'dockerfile' => ['type' => 'string', 'description' => 'The Dockerfile content.'], + 'dockerfile_location' => ['type' => 'string', 'description' => 'The Dockerfile location in the repository.'], 'docker_compose_location' => ['type' => 'string', 'description' => 'The Docker Compose location.'], 'docker_compose_custom_start_command' => ['type' => 'string', 'description' => 'The Docker Compose custom start command.'], 'docker_compose_custom_build_command' => ['type' => 'string', 'description' => 'The Docker Compose custom build command.'], @@ -2391,7 +2458,7 @@ public function update_by_uuid(Request $request) $this->authorize('update', $application); $server = $application->destination->server; - $allowedFields = ['name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'static_image', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings','custom_network_aliases', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'watch_paths', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'docker_compose_location', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'redirect', 'instant_deploy', 'use_build_server', 'custom_nginx_configuration', 'is_http_basic_auth_enabled', 'http_basic_auth_username', 'http_basic_auth_password', 'connect_to_docker_network', 'force_domain_override', 'is_container_label_escape_enabled']; + $allowedFields = ['name', 'description', 'is_static', 'is_spa', 'is_auto_deploy_enabled', 'is_force_https_enabled', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'static_image', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'custom_network_aliases', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'watch_paths', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'dockerfile_location', 'docker_compose_location', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'redirect', 'instant_deploy', 'use_build_server', 'custom_nginx_configuration', 'is_http_basic_auth_enabled', 'http_basic_auth_username', 'http_basic_auth_password', 'connect_to_docker_network', 'force_domain_override', 'is_container_label_escape_enabled']; $validationRules = [ 'name' => 'string|max:255', @@ -2629,6 +2696,9 @@ public function update_by_uuid(Request $request) } $instantDeploy = $request->instant_deploy; $isStatic = $request->is_static; + $isSpa = $request->is_spa; + $isAutoDeployEnabled = $request->is_auto_deploy_enabled; + $isForceHttpsEnabled = $request->is_force_https_enabled; $connectToDockerNetwork = $request->connect_to_docker_network; $useBuildServer = $request->use_build_server; $isContainerLabelEscapeEnabled = $request->boolean('is_container_label_escape_enabled'); @@ -2643,6 +2713,21 @@ public function update_by_uuid(Request $request) $application->settings->save(); } + if (isset($isSpa)) { + $application->settings->is_spa = $isSpa; + $application->settings->save(); + } + + if (isset($isAutoDeployEnabled)) { + $application->settings->is_auto_deploy_enabled = $isAutoDeployEnabled; + $application->settings->save(); + } + + if (isset($isForceHttpsEnabled)) { + $application->settings->is_force_https_enabled = $isForceHttpsEnabled; + $application->settings->save(); + } + if (isset($connectToDockerNetwork)) { $application->settings->connect_to_docker_network = $connectToDockerNetwork; $application->settings->save(); diff --git a/bootstrap/helpers/api.php b/bootstrap/helpers/api.php index 55cff42d0..c23f55c12 100644 --- a/bootstrap/helpers/api.php +++ b/bootstrap/helpers/api.php @@ -86,6 +86,9 @@ function sharedDataApplications() 'git_branch' => 'string', 'build_pack' => Rule::enum(BuildPackTypes::class), 'is_static' => 'boolean', + 'is_spa' => 'boolean', + 'is_auto_deploy_enabled' => 'boolean', + 'is_force_https_enabled' => 'boolean', 'static_image' => Rule::enum(StaticImageTypes::class), 'domains' => 'string', 'redirect' => Rule::enum(RedirectTypes::class), @@ -129,6 +132,7 @@ function sharedDataApplications() 'manual_webhook_secret_gitlab' => 'string|nullable', 'manual_webhook_secret_bitbucket' => 'string|nullable', 'manual_webhook_secret_gitea' => 'string|nullable', + 'dockerfile_location' => 'string|nullable', 'docker_compose_location' => 'string', 'docker_compose' => 'string|nullable', 'docker_compose_domains' => 'array|nullable', @@ -177,6 +181,10 @@ function removeUnnecessaryFieldsFromRequest(Request $request) $request->offsetUnset('private_key_uuid'); $request->offsetUnset('use_build_server'); $request->offsetUnset('is_static'); + $request->offsetUnset('is_spa'); + $request->offsetUnset('is_auto_deploy_enabled'); + $request->offsetUnset('is_force_https_enabled'); + $request->offsetUnset('connect_to_docker_network'); $request->offsetUnset('force_domain_override'); $request->offsetUnset('autogenerate_domain'); $request->offsetUnset('is_container_label_escape_enabled');