feat(api): add application settings to application endpoints
This commit is contained in:
parent
99e255a572
commit
34e6a6dd5d
8 changed files with 1594 additions and 12 deletions
|
|
@ -35,6 +35,36 @@ class ApplicationsController extends Controller
|
|||
{
|
||||
use Concerns\HandlesTagsApi;
|
||||
|
||||
private const APPLICATION_SETTING_FIELDS = [
|
||||
'is_git_submodules_enabled',
|
||||
'is_git_lfs_enabled',
|
||||
'is_git_shallow_clone_enabled',
|
||||
'disable_build_cache',
|
||||
'inject_build_args_to_dockerfile',
|
||||
'include_source_commit_in_build',
|
||||
'is_env_sorting_enabled',
|
||||
'is_pr_deployments_public_enabled',
|
||||
'stop_grace_period',
|
||||
'docker_images_to_keep',
|
||||
'is_gzip_enabled',
|
||||
'is_stripprefix_enabled',
|
||||
'is_raw_compose_deployment_enabled',
|
||||
];
|
||||
|
||||
private const BOOLEAN_APPLICATION_SETTING_FIELDS = [
|
||||
'is_git_submodules_enabled',
|
||||
'is_git_lfs_enabled',
|
||||
'is_git_shallow_clone_enabled',
|
||||
'disable_build_cache',
|
||||
'inject_build_args_to_dockerfile',
|
||||
'include_source_commit_in_build',
|
||||
'is_env_sorting_enabled',
|
||||
'is_pr_deployments_public_enabled',
|
||||
'is_gzip_enabled',
|
||||
'is_stripprefix_enabled',
|
||||
'is_raw_compose_deployment_enabled',
|
||||
];
|
||||
|
||||
protected function findTaggableResource(string $uuid, int|string $teamId): mixed
|
||||
{
|
||||
return Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $uuid)->first();
|
||||
|
|
@ -87,9 +117,48 @@ private function removeSensitiveData($application)
|
|||
$application->makeHidden(['value', 'real_value']);
|
||||
}
|
||||
|
||||
if ($application->relationLoaded('settings')) {
|
||||
$application->settings?->makeHidden(['id', 'application_id', 'created_at', 'updated_at']);
|
||||
}
|
||||
|
||||
return serializeApiResponse($application);
|
||||
}
|
||||
|
||||
private function applicationSettingsFromRequest(Request $request): array
|
||||
{
|
||||
$settings = [];
|
||||
|
||||
foreach (self::APPLICATION_SETTING_FIELDS as $field) {
|
||||
if (! array_key_exists($field, $request->all())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$settings[$field] = in_array($field, self::BOOLEAN_APPLICATION_SETTING_FIELDS, true)
|
||||
? $request->boolean($field)
|
||||
: $request->input($field);
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
private function applyApplicationSettings(Application $application, array $settings): void
|
||||
{
|
||||
if ($settings === []) {
|
||||
return;
|
||||
}
|
||||
|
||||
$regenerateLabels = ! $application->wasRecentlyCreated
|
||||
&& $application->settings->is_container_label_readonly_enabled
|
||||
&& (array_key_exists('is_gzip_enabled', $settings) || array_key_exists('is_stripprefix_enabled', $settings));
|
||||
|
||||
$application->settings->fill($settings)->save();
|
||||
|
||||
if ($regenerateLabels) {
|
||||
$application->custom_labels = str(implode('|coolify|', generateLabelsApplication($application)))->replace('|coolify|', "\n");
|
||||
$application->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose sensitive fields on eager-loaded nested Server + ServerSetting
|
||||
* relations for callers with the `read:sensitive` or `root` token ability.
|
||||
|
|
@ -285,6 +354,20 @@ public function applications(Request $request)
|
|||
],
|
||||
'watch_paths' => ['type' => 'string', 'description' => 'The watch paths.'],
|
||||
'use_build_server' => ['type' => 'boolean', 'nullable' => true, 'description' => 'Use build server.'],
|
||||
'use_build_secrets' => ['type' => 'boolean', 'default' => false, 'description' => 'Use Docker Build Secrets for build-time environment variables.'],
|
||||
'is_git_submodules_enabled' => ['type' => 'boolean', 'description' => 'Clone Git submodules.'],
|
||||
'is_git_lfs_enabled' => ['type' => 'boolean', 'description' => 'Enable Git LFS.'],
|
||||
'is_git_shallow_clone_enabled' => ['type' => 'boolean', 'description' => 'Use a shallow Git clone.'],
|
||||
'disable_build_cache' => ['type' => 'boolean', 'description' => 'Disable the build cache.'],
|
||||
'inject_build_args_to_dockerfile' => ['type' => 'boolean', 'description' => 'Inject build arguments into the Dockerfile build.'],
|
||||
'include_source_commit_in_build' => ['type' => 'boolean', 'description' => 'Include the source commit in the build.'],
|
||||
'is_env_sorting_enabled' => ['type' => 'boolean', 'description' => 'Sort environment variables.'],
|
||||
'is_pr_deployments_public_enabled' => ['type' => 'boolean', 'description' => 'Make pull request deployments public.'],
|
||||
'stop_grace_period' => ['type' => 'integer', 'nullable' => true, 'minimum' => 1, 'maximum' => 3600, 'description' => 'Container stop grace period in seconds.'],
|
||||
'docker_images_to_keep' => ['type' => 'integer', 'minimum' => 0, 'maximum' => 100, 'description' => 'Number of Docker images to retain.'],
|
||||
'is_gzip_enabled' => ['type' => 'boolean', 'description' => 'Enable gzip compression.'],
|
||||
'is_stripprefix_enabled' => ['type' => 'boolean', 'description' => 'Enable path prefix stripping.'],
|
||||
'is_raw_compose_deployment_enabled' => ['type' => 'boolean', 'description' => 'Deploy the raw Docker Compose definition.'],
|
||||
'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'],
|
||||
'http_basic_auth_password' => ['type' => 'string', 'nullable' => true, 'description' => 'Password for HTTP Basic Authentication'],
|
||||
|
|
@ -453,6 +536,20 @@ public function create_public_application(Request $request)
|
|||
],
|
||||
'watch_paths' => ['type' => 'string', 'description' => 'The watch paths.'],
|
||||
'use_build_server' => ['type' => 'boolean', 'nullable' => true, 'description' => 'Use build server.'],
|
||||
'use_build_secrets' => ['type' => 'boolean', 'default' => false, 'description' => 'Use Docker Build Secrets for build-time environment variables.'],
|
||||
'is_git_submodules_enabled' => ['type' => 'boolean', 'description' => 'Clone Git submodules.'],
|
||||
'is_git_lfs_enabled' => ['type' => 'boolean', 'description' => 'Enable Git LFS.'],
|
||||
'is_git_shallow_clone_enabled' => ['type' => 'boolean', 'description' => 'Use a shallow Git clone.'],
|
||||
'disable_build_cache' => ['type' => 'boolean', 'description' => 'Disable the build cache.'],
|
||||
'inject_build_args_to_dockerfile' => ['type' => 'boolean', 'description' => 'Inject build arguments into the Dockerfile build.'],
|
||||
'include_source_commit_in_build' => ['type' => 'boolean', 'description' => 'Include the source commit in the build.'],
|
||||
'is_env_sorting_enabled' => ['type' => 'boolean', 'description' => 'Sort environment variables.'],
|
||||
'is_pr_deployments_public_enabled' => ['type' => 'boolean', 'description' => 'Make pull request deployments public.'],
|
||||
'stop_grace_period' => ['type' => 'integer', 'nullable' => true, 'minimum' => 1, 'maximum' => 3600, 'description' => 'Container stop grace period in seconds.'],
|
||||
'docker_images_to_keep' => ['type' => 'integer', 'minimum' => 0, 'maximum' => 100, 'description' => 'Number of Docker images to retain.'],
|
||||
'is_gzip_enabled' => ['type' => 'boolean', 'description' => 'Enable gzip compression.'],
|
||||
'is_stripprefix_enabled' => ['type' => 'boolean', 'description' => 'Enable path prefix stripping.'],
|
||||
'is_raw_compose_deployment_enabled' => ['type' => 'boolean', 'description' => 'Deploy the raw Docker Compose definition.'],
|
||||
'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'],
|
||||
'http_basic_auth_password' => ['type' => 'string', 'nullable' => true, 'description' => 'Password for HTTP Basic Authentication'],
|
||||
|
|
@ -621,6 +718,20 @@ public function create_private_gh_app_application(Request $request)
|
|||
],
|
||||
'watch_paths' => ['type' => 'string', 'description' => 'The watch paths.'],
|
||||
'use_build_server' => ['type' => 'boolean', 'nullable' => true, 'description' => 'Use build server.'],
|
||||
'use_build_secrets' => ['type' => 'boolean', 'default' => false, 'description' => 'Use Docker Build Secrets for build-time environment variables.'],
|
||||
'is_git_submodules_enabled' => ['type' => 'boolean', 'description' => 'Clone Git submodules.'],
|
||||
'is_git_lfs_enabled' => ['type' => 'boolean', 'description' => 'Enable Git LFS.'],
|
||||
'is_git_shallow_clone_enabled' => ['type' => 'boolean', 'description' => 'Use a shallow Git clone.'],
|
||||
'disable_build_cache' => ['type' => 'boolean', 'description' => 'Disable the build cache.'],
|
||||
'inject_build_args_to_dockerfile' => ['type' => 'boolean', 'description' => 'Inject build arguments into the Dockerfile build.'],
|
||||
'include_source_commit_in_build' => ['type' => 'boolean', 'description' => 'Include the source commit in the build.'],
|
||||
'is_env_sorting_enabled' => ['type' => 'boolean', 'description' => 'Sort environment variables.'],
|
||||
'is_pr_deployments_public_enabled' => ['type' => 'boolean', 'description' => 'Make pull request deployments public.'],
|
||||
'stop_grace_period' => ['type' => 'integer', 'nullable' => true, 'minimum' => 1, 'maximum' => 3600, 'description' => 'Container stop grace period in seconds.'],
|
||||
'docker_images_to_keep' => ['type' => 'integer', 'minimum' => 0, 'maximum' => 100, 'description' => 'Number of Docker images to retain.'],
|
||||
'is_gzip_enabled' => ['type' => 'boolean', 'description' => 'Enable gzip compression.'],
|
||||
'is_stripprefix_enabled' => ['type' => 'boolean', 'description' => 'Enable path prefix stripping.'],
|
||||
'is_raw_compose_deployment_enabled' => ['type' => 'boolean', 'description' => 'Deploy the raw Docker Compose definition.'],
|
||||
'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'],
|
||||
'http_basic_auth_password' => ['type' => 'string', 'nullable' => true, 'description' => 'Password for HTTP Basic Authentication'],
|
||||
|
|
@ -761,6 +872,20 @@ public function create_private_deploy_key_application(Request $request)
|
|||
'is_force_https_enabled' => ['type' => 'boolean', 'description' => 'The flag to indicate if HTTPS is forced. Defaults to true.'],
|
||||
'is_preview_deployments_enabled' => ['type' => 'boolean', 'description' => 'Enable preview deployments for pull requests.'],
|
||||
'use_build_server' => ['type' => 'boolean', 'nullable' => true, 'description' => 'Use build server.'],
|
||||
'use_build_secrets' => ['type' => 'boolean', 'default' => false, 'description' => 'Use Docker Build Secrets for build-time environment variables.'],
|
||||
'is_git_submodules_enabled' => ['type' => 'boolean', 'description' => 'Clone Git submodules.'],
|
||||
'is_git_lfs_enabled' => ['type' => 'boolean', 'description' => 'Enable Git LFS.'],
|
||||
'is_git_shallow_clone_enabled' => ['type' => 'boolean', 'description' => 'Use a shallow Git clone.'],
|
||||
'disable_build_cache' => ['type' => 'boolean', 'description' => 'Disable the build cache.'],
|
||||
'inject_build_args_to_dockerfile' => ['type' => 'boolean', 'description' => 'Inject build arguments into the Dockerfile build.'],
|
||||
'include_source_commit_in_build' => ['type' => 'boolean', 'description' => 'Include the source commit in the build.'],
|
||||
'is_env_sorting_enabled' => ['type' => 'boolean', 'description' => 'Sort environment variables.'],
|
||||
'is_pr_deployments_public_enabled' => ['type' => 'boolean', 'description' => 'Make pull request deployments public.'],
|
||||
'stop_grace_period' => ['type' => 'integer', 'nullable' => true, 'minimum' => 1, 'maximum' => 3600, 'description' => 'Container stop grace period in seconds.'],
|
||||
'docker_images_to_keep' => ['type' => 'integer', 'minimum' => 0, 'maximum' => 100, 'description' => 'Number of Docker images to retain.'],
|
||||
'is_gzip_enabled' => ['type' => 'boolean', 'description' => 'Enable gzip compression.'],
|
||||
'is_stripprefix_enabled' => ['type' => 'boolean', 'description' => 'Enable path prefix stripping.'],
|
||||
'is_raw_compose_deployment_enabled' => ['type' => 'boolean', 'description' => 'Deploy the raw Docker Compose definition.'],
|
||||
'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'],
|
||||
'http_basic_auth_password' => ['type' => 'string', 'nullable' => true, 'description' => 'Password for HTTP Basic Authentication'],
|
||||
|
|
@ -897,6 +1022,20 @@ public function create_dockerfile_application(Request $request)
|
|||
'is_force_https_enabled' => ['type' => 'boolean', 'description' => 'The flag to indicate if HTTPS is forced. Defaults to true.'],
|
||||
'is_preview_deployments_enabled' => ['type' => 'boolean', 'description' => 'Enable preview deployments for pull requests.'],
|
||||
'use_build_server' => ['type' => 'boolean', 'nullable' => true, 'description' => 'Use build server.'],
|
||||
'use_build_secrets' => ['type' => 'boolean', 'default' => false, 'description' => 'Use Docker Build Secrets for build-time environment variables.'],
|
||||
'is_git_submodules_enabled' => ['type' => 'boolean', 'description' => 'Clone Git submodules.'],
|
||||
'is_git_lfs_enabled' => ['type' => 'boolean', 'description' => 'Enable Git LFS.'],
|
||||
'is_git_shallow_clone_enabled' => ['type' => 'boolean', 'description' => 'Use a shallow Git clone.'],
|
||||
'disable_build_cache' => ['type' => 'boolean', 'description' => 'Disable the build cache.'],
|
||||
'inject_build_args_to_dockerfile' => ['type' => 'boolean', 'description' => 'Inject build arguments into the Dockerfile build.'],
|
||||
'include_source_commit_in_build' => ['type' => 'boolean', 'description' => 'Include the source commit in the build.'],
|
||||
'is_env_sorting_enabled' => ['type' => 'boolean', 'description' => 'Sort environment variables.'],
|
||||
'is_pr_deployments_public_enabled' => ['type' => 'boolean', 'description' => 'Make pull request deployments public.'],
|
||||
'stop_grace_period' => ['type' => 'integer', 'nullable' => true, 'minimum' => 1, 'maximum' => 3600, 'description' => 'Container stop grace period in seconds.'],
|
||||
'docker_images_to_keep' => ['type' => 'integer', 'minimum' => 0, 'maximum' => 100, 'description' => 'Number of Docker images to retain.'],
|
||||
'is_gzip_enabled' => ['type' => 'boolean', 'description' => 'Enable gzip compression.'],
|
||||
'is_stripprefix_enabled' => ['type' => 'boolean', 'description' => 'Enable path prefix stripping.'],
|
||||
'is_raw_compose_deployment_enabled' => ['type' => 'boolean', 'description' => 'Deploy the raw Docker Compose definition.'],
|
||||
'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'],
|
||||
'http_basic_auth_password' => ['type' => 'string', 'nullable' => true, 'description' => 'Password for HTTP Basic Authentication'],
|
||||
|
|
@ -981,7 +1120,7 @@ private function create_application(Request $request, $type)
|
|||
if ($return instanceof JsonResponse) {
|
||||
return $return;
|
||||
}
|
||||
$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', 'is_preview_deployments_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_type', 'health_check_command', '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', 'tags', 'is_preserve_repository_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', 'is_preview_deployments_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_type', 'health_check_command', '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', 'use_build_secrets', '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', 'tags', 'is_preserve_repository_enabled', ...self::APPLICATION_SETTING_FIELDS];
|
||||
|
||||
$validator = customApiValidator($request->all(), [
|
||||
'name' => 'string|max:255',
|
||||
|
|
@ -1036,6 +1175,7 @@ private function create_application(Request $request, $type)
|
|||
$instantDeploy = $request->instant_deploy;
|
||||
$githubAppUuid = $request->github_app_uuid;
|
||||
$useBuildServer = $request->use_build_server;
|
||||
$useBuildSecrets = $request->use_build_secrets;
|
||||
$isStatic = $request->is_static;
|
||||
$isSpa = $request->is_spa;
|
||||
$isAutoDeployEnabled = $request->is_auto_deploy_enabled;
|
||||
|
|
@ -1045,6 +1185,19 @@ private function create_application(Request $request, $type)
|
|||
$customNginxConfiguration = $request->custom_nginx_configuration;
|
||||
$isContainerLabelEscapeEnabled = $request->boolean('is_container_label_escape_enabled', true);
|
||||
$isPreserveRepositoryEnabled = $request->boolean('is_preserve_repository_enabled', false);
|
||||
$applicationSettings = $this->applicationSettingsFromRequest($request);
|
||||
|
||||
$requestedBuildPack = in_array($type, ['public', 'private-gh-app', 'private-deploy-key'], true)
|
||||
? $request->input('build_pack')
|
||||
: $type;
|
||||
if (($applicationSettings['is_raw_compose_deployment_enabled'] ?? false) && $requestedBuildPack !== 'dockercompose') {
|
||||
return response()->json([
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => [
|
||||
'is_raw_compose_deployment_enabled' => 'Raw compose deployment can only be enabled for Docker Compose applications.',
|
||||
],
|
||||
], 422);
|
||||
}
|
||||
|
||||
if (! is_null($customNginxConfiguration)) {
|
||||
if (! isBase64Encoded($customNginxConfiguration)) {
|
||||
|
|
@ -1232,6 +1385,7 @@ private function create_application(Request $request, $type)
|
|||
$application->destination_type = $destination->getMorphClass();
|
||||
$application->environment_id = $environment->id;
|
||||
$application->save();
|
||||
$this->applyApplicationSettings($application, $applicationSettings);
|
||||
if (isset($isStatic)) {
|
||||
$application->settings->is_static = $isStatic;
|
||||
$application->settings->save();
|
||||
|
|
@ -1260,6 +1414,10 @@ private function create_application(Request $request, $type)
|
|||
$application->settings->is_build_server_enabled = $useBuildServer;
|
||||
$application->settings->save();
|
||||
}
|
||||
if (isset($useBuildSecrets)) {
|
||||
$application->settings->use_build_secrets = $useBuildSecrets;
|
||||
$application->settings->save();
|
||||
}
|
||||
if (isset($isContainerLabelEscapeEnabled)) {
|
||||
$application->settings->is_container_label_escape_enabled = $isContainerLabelEscapeEnabled;
|
||||
$application->settings->save();
|
||||
|
|
@ -1478,6 +1636,7 @@ private function create_application(Request $request, $type)
|
|||
$application->repository_project_id = $repository_project_id;
|
||||
|
||||
$application->save();
|
||||
$this->applyApplicationSettings($application, $applicationSettings);
|
||||
$application->refresh();
|
||||
// Auto-generate domain if requested and no custom domain provided
|
||||
if ($autogenerateDomain && blank($fqdn)) {
|
||||
|
|
@ -1512,6 +1671,10 @@ private function create_application(Request $request, $type)
|
|||
$application->settings->is_build_server_enabled = $useBuildServer;
|
||||
$application->settings->save();
|
||||
}
|
||||
if (isset($useBuildSecrets)) {
|
||||
$application->settings->use_build_secrets = $useBuildSecrets;
|
||||
$application->settings->save();
|
||||
}
|
||||
if (isset($isContainerLabelEscapeEnabled)) {
|
||||
$application->settings->is_container_label_escape_enabled = $isContainerLabelEscapeEnabled;
|
||||
$application->settings->save();
|
||||
|
|
@ -1694,6 +1857,7 @@ private function create_application(Request $request, $type)
|
|||
$application->destination_type = $destination->getMorphClass();
|
||||
$application->environment_id = $environment->id;
|
||||
$application->save();
|
||||
$this->applyApplicationSettings($application, $applicationSettings);
|
||||
$application->refresh();
|
||||
// Auto-generate domain if requested and no custom domain provided
|
||||
if ($autogenerateDomain && blank($fqdn)) {
|
||||
|
|
@ -1728,6 +1892,10 @@ private function create_application(Request $request, $type)
|
|||
$application->settings->is_build_server_enabled = $useBuildServer;
|
||||
$application->settings->save();
|
||||
}
|
||||
if (isset($useBuildSecrets)) {
|
||||
$application->settings->use_build_secrets = $useBuildSecrets;
|
||||
$application->settings->save();
|
||||
}
|
||||
if (isset($isContainerLabelEscapeEnabled)) {
|
||||
$application->settings->is_container_label_escape_enabled = $isContainerLabelEscapeEnabled;
|
||||
$application->settings->save();
|
||||
|
|
@ -1837,6 +2005,7 @@ private function create_application(Request $request, $type)
|
|||
$application->git_repository = 'coollabsio/coolify';
|
||||
$application->git_branch = 'main';
|
||||
$application->save();
|
||||
$this->applyApplicationSettings($application, $applicationSettings);
|
||||
$application->refresh();
|
||||
// Auto-generate domain if requested and no custom domain provided
|
||||
if ($autogenerateDomain && blank($fqdn)) {
|
||||
|
|
@ -1859,6 +2028,10 @@ private function create_application(Request $request, $type)
|
|||
$application->settings->is_build_server_enabled = $useBuildServer;
|
||||
$application->settings->save();
|
||||
}
|
||||
if (isset($useBuildSecrets)) {
|
||||
$application->settings->use_build_secrets = $useBuildSecrets;
|
||||
$application->settings->save();
|
||||
}
|
||||
if (isset($isContainerLabelEscapeEnabled)) {
|
||||
$application->settings->is_container_label_escape_enabled = $isContainerLabelEscapeEnabled;
|
||||
$application->settings->save();
|
||||
|
|
@ -1963,6 +2136,7 @@ private function create_application(Request $request, $type)
|
|||
$application->git_repository = 'coollabsio/coolify';
|
||||
$application->git_branch = 'main';
|
||||
$application->save();
|
||||
$this->applyApplicationSettings($application, $applicationSettings);
|
||||
$application->refresh();
|
||||
// Auto-generate domain if requested and no custom domain provided
|
||||
if ($autogenerateDomain && blank($fqdn)) {
|
||||
|
|
@ -1985,6 +2159,10 @@ private function create_application(Request $request, $type)
|
|||
$application->settings->is_build_server_enabled = $useBuildServer;
|
||||
$application->settings->save();
|
||||
}
|
||||
if (isset($useBuildSecrets)) {
|
||||
$application->settings->use_build_secrets = $useBuildSecrets;
|
||||
$application->settings->save();
|
||||
}
|
||||
if (isset($isContainerLabelEscapeEnabled)) {
|
||||
$application->settings->is_container_label_escape_enabled = $isContainerLabelEscapeEnabled;
|
||||
$application->settings->save();
|
||||
|
|
@ -2090,7 +2268,7 @@ public function application_by_uuid(Request $request)
|
|||
if (! $uuid) {
|
||||
return response()->json(['message' => 'UUID is required.'], 400);
|
||||
}
|
||||
$application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->route('uuid'))->first();
|
||||
$application = Application::ownedByCurrentTeamAPI($teamId)->with('settings')->where('uuid', $request->route('uuid'))->first();
|
||||
if (! $application) {
|
||||
return response()->json(['message' => 'Application not found.'], 404);
|
||||
}
|
||||
|
|
@ -2405,11 +2583,24 @@ public function delete_by_uuid(Request $request)
|
|||
],
|
||||
'watch_paths' => ['type' => 'string', 'description' => 'The watch paths.'],
|
||||
'use_build_server' => ['type' => 'boolean', 'nullable' => true, 'description' => 'Use build server.'],
|
||||
'use_build_secrets' => ['type' => 'boolean', 'description' => 'Use Docker Build Secrets for build-time environment variables.'],
|
||||
'is_git_submodules_enabled' => ['type' => 'boolean', 'description' => 'Clone Git submodules.'],
|
||||
'is_git_lfs_enabled' => ['type' => 'boolean', 'description' => 'Enable Git LFS.'],
|
||||
'is_git_shallow_clone_enabled' => ['type' => 'boolean', 'description' => 'Use a shallow Git clone.'],
|
||||
'disable_build_cache' => ['type' => 'boolean', 'description' => 'Disable the build cache.'],
|
||||
'inject_build_args_to_dockerfile' => ['type' => 'boolean', 'description' => 'Inject build arguments into the Dockerfile build.'],
|
||||
'include_source_commit_in_build' => ['type' => 'boolean', 'description' => 'Include the source commit in the build.'],
|
||||
'is_env_sorting_enabled' => ['type' => 'boolean', 'description' => 'Sort environment variables.'],
|
||||
'is_pr_deployments_public_enabled' => ['type' => 'boolean', 'description' => 'Make pull request deployments public.'],
|
||||
'stop_grace_period' => ['type' => 'integer', 'nullable' => true, 'minimum' => 1, 'maximum' => 3600, 'description' => 'Container stop grace period in seconds.'],
|
||||
'docker_images_to_keep' => ['type' => 'integer', 'minimum' => 0, 'maximum' => 100, 'description' => 'Number of Docker images to retain.'],
|
||||
'is_gzip_enabled' => ['type' => 'boolean', 'description' => 'Enable gzip compression.'],
|
||||
'is_stripprefix_enabled' => ['type' => 'boolean', 'description' => 'Enable path prefix stripping.'],
|
||||
'is_raw_compose_deployment_enabled' => ['type' => 'boolean', 'description' => 'Deploy the raw Docker Compose definition.'],
|
||||
'connect_to_docker_network' => ['type' => 'boolean', 'description' => 'The flag to connect the service to the predefined Docker network.'],
|
||||
'force_domain_override' => ['type' => 'boolean', 'description' => 'Force domain usage even if conflicts are detected. Default is false.'],
|
||||
'is_container_label_escape_enabled' => ['type' => 'boolean', 'default' => true, 'description' => 'Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off.'],
|
||||
'is_preserve_repository_enabled' => ['type' => 'boolean', 'description' => 'Preserve git repository during application update. If false, the existing repository will be removed and replaced with the new one. If true, the existing repository will be kept and the new one will be ignored. Default is false.'],
|
||||
'include_source_commit_in_build' => ['type' => 'boolean', 'description' => 'Include source commit information in the build. Default is false.'],
|
||||
],
|
||||
)
|
||||
),
|
||||
|
|
@ -2495,7 +2686,7 @@ public function update_by_uuid(Request $request)
|
|||
$this->authorize('update', $application);
|
||||
|
||||
$server = $application->destination->server;
|
||||
$allowedFields = ['name', 'description', 'is_static', 'is_spa', 'is_auto_deploy_enabled', 'is_force_https_enabled', 'is_preview_deployments_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_type', 'health_check_command', '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', 'dockerfile_target_build', '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', 'is_preserve_repository_enabled', 'include_source_commit_in_build'];
|
||||
$allowedFields = ['name', 'description', 'is_static', 'is_spa', 'is_auto_deploy_enabled', 'is_force_https_enabled', 'is_preview_deployments_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_type', 'health_check_command', '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', 'dockerfile_target_build', 'docker_compose_location', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'redirect', 'instant_deploy', 'use_build_server', 'use_build_secrets', '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', 'is_preserve_repository_enabled', ...self::APPLICATION_SETTING_FIELDS];
|
||||
|
||||
$validationRules = [
|
||||
'name' => 'string|max:255',
|
||||
|
|
@ -2574,6 +2765,17 @@ public function update_by_uuid(Request $request)
|
|||
], 422);
|
||||
}
|
||||
|
||||
$applicationSettings = $this->applicationSettingsFromRequest($request);
|
||||
$requestedBuildPack = $request->input('build_pack', $application->build_pack);
|
||||
if (($applicationSettings['is_raw_compose_deployment_enabled'] ?? false) && $requestedBuildPack !== 'dockercompose') {
|
||||
return response()->json([
|
||||
'message' => 'Validation failed.',
|
||||
'errors' => [
|
||||
'is_raw_compose_deployment_enabled' => 'Raw compose deployment can only be enabled for Docker Compose applications.',
|
||||
],
|
||||
], 422);
|
||||
}
|
||||
|
||||
if ($request->has('is_http_basic_auth_enabled') && $request->is_http_basic_auth_enabled === true) {
|
||||
if (blank($application->http_basic_auth_username) || blank($application->http_basic_auth_password)) {
|
||||
$validationErrors = [];
|
||||
|
|
@ -2728,6 +2930,7 @@ public function update_by_uuid(Request $request)
|
|||
$isPreviewDeploymentsEnabled = $request->is_preview_deployments_enabled;
|
||||
$connectToDockerNetwork = $request->connect_to_docker_network;
|
||||
$useBuildServer = $request->use_build_server;
|
||||
$useBuildSecrets = $request->use_build_secrets;
|
||||
$isContainerLabelEscapeEnabled = $request->boolean('is_container_label_escape_enabled');
|
||||
$isPreserveRepositoryEnabled = $request->boolean('is_preserve_repository_enabled');
|
||||
$includeSourceCommitInBuild = $request->boolean('include_source_commit_in_build');
|
||||
|
|
@ -2735,6 +2938,10 @@ public function update_by_uuid(Request $request)
|
|||
$application->settings->is_build_server_enabled = $useBuildServer;
|
||||
$application->settings->save();
|
||||
}
|
||||
if (isset($useBuildSecrets)) {
|
||||
$application->settings->use_build_secrets = $useBuildSecrets;
|
||||
$application->settings->save();
|
||||
}
|
||||
|
||||
if (isset($isStatic)) {
|
||||
$application->settings->is_static = $isStatic;
|
||||
|
|
@ -2778,6 +2985,7 @@ public function update_by_uuid(Request $request)
|
|||
$application->settings->include_source_commit_in_build = $includeSourceCommitInBuild;
|
||||
$application->settings->save();
|
||||
}
|
||||
$this->applyApplicationSettings($application, $applicationSettings);
|
||||
removeUnnecessaryFieldsFromRequest($request);
|
||||
|
||||
$data = $request->only($allowedFields);
|
||||
|
|
@ -4023,7 +4231,7 @@ public function action_restart(Request $request)
|
|||
),
|
||||
]
|
||||
)]
|
||||
public function move_by_uuid(Request $request): \Illuminate\Http\JsonResponse
|
||||
public function move_by_uuid(Request $request): JsonResponse
|
||||
{
|
||||
$teamId = getTeamIdFromToken();
|
||||
if (is_null($teamId)) {
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@
|
|||
'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'],
|
||||
'http_basic_auth_password' => ['type' => 'string', 'nullable' => true, 'description' => 'Password for HTTP Basic Authentication'],
|
||||
'settings' => new OA\Property(ref: '#/components/schemas/ApplicationSetting'),
|
||||
]
|
||||
)]
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,49 @@
|
|||
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use OpenApi\Attributes as OA;
|
||||
|
||||
#[OA\Schema(
|
||||
description: 'Application settings.',
|
||||
type: 'object',
|
||||
properties: [
|
||||
'is_static' => ['type' => 'boolean'],
|
||||
'is_git_submodules_enabled' => ['type' => 'boolean'],
|
||||
'is_git_lfs_enabled' => ['type' => 'boolean'],
|
||||
'is_auto_deploy_enabled' => ['type' => 'boolean'],
|
||||
'is_force_https_enabled' => ['type' => 'boolean'],
|
||||
'is_debug_enabled' => ['type' => 'boolean'],
|
||||
'is_preview_deployments_enabled' => ['type' => 'boolean'],
|
||||
'is_log_drain_enabled' => ['type' => 'boolean'],
|
||||
'is_gpu_enabled' => ['type' => 'boolean'],
|
||||
'gpu_driver' => ['type' => 'string', 'nullable' => true],
|
||||
'gpu_count' => ['type' => 'string', 'nullable' => true],
|
||||
'gpu_device_ids' => ['type' => 'string', 'nullable' => true],
|
||||
'gpu_options' => ['type' => 'string', 'nullable' => true],
|
||||
'is_include_timestamps' => ['type' => 'boolean'],
|
||||
'is_swarm_only_worker_nodes' => ['type' => 'boolean'],
|
||||
'is_raw_compose_deployment_enabled' => ['type' => 'boolean'],
|
||||
'is_build_server_enabled' => ['type' => 'boolean'],
|
||||
'is_consistent_container_name_enabled' => ['type' => 'boolean'],
|
||||
'is_gzip_enabled' => ['type' => 'boolean'],
|
||||
'is_stripprefix_enabled' => ['type' => 'boolean'],
|
||||
'connect_to_docker_network' => ['type' => 'boolean'],
|
||||
'custom_internal_name' => ['type' => 'string', 'nullable' => true],
|
||||
'is_container_label_escape_enabled' => ['type' => 'boolean'],
|
||||
'is_env_sorting_enabled' => ['type' => 'boolean'],
|
||||
'is_container_label_readonly_enabled' => ['type' => 'boolean'],
|
||||
'is_preserve_repository_enabled' => ['type' => 'boolean'],
|
||||
'disable_build_cache' => ['type' => 'boolean'],
|
||||
'is_spa' => ['type' => 'boolean'],
|
||||
'is_git_shallow_clone_enabled' => ['type' => 'boolean'],
|
||||
'is_pr_deployments_public_enabled' => ['type' => 'boolean'],
|
||||
'use_build_secrets' => ['type' => 'boolean'],
|
||||
'inject_build_args_to_dockerfile' => ['type' => 'boolean'],
|
||||
'include_source_commit_in_build' => ['type' => 'boolean'],
|
||||
'docker_images_to_keep' => ['type' => 'integer'],
|
||||
'stop_grace_period' => ['type' => 'integer', 'nullable' => true],
|
||||
]
|
||||
)]
|
||||
class ApplicationSetting extends Model
|
||||
{
|
||||
protected $casts = [
|
||||
|
|
@ -27,6 +69,17 @@ class ApplicationSetting extends Model
|
|||
'is_git_shallow_clone_enabled' => 'boolean',
|
||||
'docker_images_to_keep' => 'integer',
|
||||
'stop_grace_period' => 'integer',
|
||||
'is_log_drain_enabled' => 'boolean',
|
||||
'is_gpu_enabled' => 'boolean',
|
||||
'is_include_timestamps' => 'boolean',
|
||||
'is_swarm_only_worker_nodes' => 'boolean',
|
||||
'is_raw_compose_deployment_enabled' => 'boolean',
|
||||
'is_consistent_container_name_enabled' => 'boolean',
|
||||
'is_gzip_enabled' => 'boolean',
|
||||
'is_stripprefix_enabled' => 'boolean',
|
||||
'connect_to_docker_network' => 'boolean',
|
||||
'is_env_sorting_enabled' => 'boolean',
|
||||
'disable_build_cache' => 'boolean',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
|
|
|
|||
|
|
@ -117,6 +117,20 @@ function sharedDataApplications()
|
|||
'is_auto_deploy_enabled' => 'boolean',
|
||||
'is_force_https_enabled' => 'boolean',
|
||||
'is_preview_deployments_enabled' => 'boolean',
|
||||
'use_build_secrets' => 'boolean',
|
||||
'is_git_submodules_enabled' => 'boolean',
|
||||
'is_git_lfs_enabled' => 'boolean',
|
||||
'is_git_shallow_clone_enabled' => 'boolean',
|
||||
'disable_build_cache' => 'boolean',
|
||||
'inject_build_args_to_dockerfile' => 'boolean',
|
||||
'include_source_commit_in_build' => 'boolean',
|
||||
'is_env_sorting_enabled' => 'boolean',
|
||||
'is_pr_deployments_public_enabled' => 'boolean',
|
||||
'is_gzip_enabled' => 'boolean',
|
||||
'is_stripprefix_enabled' => 'boolean',
|
||||
'is_raw_compose_deployment_enabled' => 'boolean',
|
||||
'stop_grace_period' => 'nullable|integer|min:'.MIN_STOP_GRACE_PERIOD_SECONDS.'|max:'.MAX_STOP_GRACE_PERIOD_SECONDS,
|
||||
'docker_images_to_keep' => 'integer|min:0|max:100',
|
||||
'static_image' => Rule::enum(StaticImageTypes::class),
|
||||
'domains' => ValidationPatterns::applicationDomainRules(),
|
||||
'redirect' => Rule::enum(RedirectTypes::class),
|
||||
|
|
@ -272,6 +286,7 @@ function removeUnnecessaryFieldsFromRequest(Request $request)
|
|||
$request->offsetUnset('github_app_uuid');
|
||||
$request->offsetUnset('private_key_uuid');
|
||||
$request->offsetUnset('use_build_server');
|
||||
$request->offsetUnset('use_build_secrets');
|
||||
$request->offsetUnset('is_static');
|
||||
$request->offsetUnset('is_spa');
|
||||
$request->offsetUnset('is_auto_deploy_enabled');
|
||||
|
|
@ -283,6 +298,18 @@ function removeUnnecessaryFieldsFromRequest(Request $request)
|
|||
$request->offsetUnset('is_container_label_escape_enabled');
|
||||
$request->offsetUnset('is_preserve_repository_enabled');
|
||||
$request->offsetUnset('include_source_commit_in_build');
|
||||
$request->offsetUnset('is_git_submodules_enabled');
|
||||
$request->offsetUnset('is_git_lfs_enabled');
|
||||
$request->offsetUnset('is_git_shallow_clone_enabled');
|
||||
$request->offsetUnset('disable_build_cache');
|
||||
$request->offsetUnset('inject_build_args_to_dockerfile');
|
||||
$request->offsetUnset('is_env_sorting_enabled');
|
||||
$request->offsetUnset('is_pr_deployments_public_enabled');
|
||||
$request->offsetUnset('stop_grace_period');
|
||||
$request->offsetUnset('docker_images_to_keep');
|
||||
$request->offsetUnset('is_gzip_enabled');
|
||||
$request->offsetUnset('is_stripprefix_enabled');
|
||||
$request->offsetUnset('is_raw_compose_deployment_enabled');
|
||||
$request->offsetUnset('docker_compose_raw');
|
||||
$request->offsetUnset('tags');
|
||||
}
|
||||
|
|
|
|||
495
openapi.json
495
openapi.json
|
|
@ -380,6 +380,68 @@
|
|||
"nullable": true,
|
||||
"description": "Use build server."
|
||||
},
|
||||
"use_build_secrets": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Use Docker Build Secrets for build-time environment variables."
|
||||
},
|
||||
"is_git_submodules_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Clone Git submodules."
|
||||
},
|
||||
"is_git_lfs_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable Git LFS."
|
||||
},
|
||||
"is_git_shallow_clone_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Use a shallow Git clone."
|
||||
},
|
||||
"disable_build_cache": {
|
||||
"type": "boolean",
|
||||
"description": "Disable the build cache."
|
||||
},
|
||||
"inject_build_args_to_dockerfile": {
|
||||
"type": "boolean",
|
||||
"description": "Inject build arguments into the Dockerfile build."
|
||||
},
|
||||
"include_source_commit_in_build": {
|
||||
"type": "boolean",
|
||||
"description": "Include the source commit in the build."
|
||||
},
|
||||
"is_env_sorting_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Sort environment variables."
|
||||
},
|
||||
"is_pr_deployments_public_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Make pull request deployments public."
|
||||
},
|
||||
"stop_grace_period": {
|
||||
"type": "integer",
|
||||
"nullable": true,
|
||||
"minimum": 1,
|
||||
"maximum": 3600,
|
||||
"description": "Container stop grace period in seconds."
|
||||
},
|
||||
"docker_images_to_keep": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 100,
|
||||
"description": "Number of Docker images to retain."
|
||||
},
|
||||
"is_gzip_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable gzip compression."
|
||||
},
|
||||
"is_stripprefix_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable path prefix stripping."
|
||||
},
|
||||
"is_raw_compose_deployment_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Deploy the raw Docker Compose definition."
|
||||
},
|
||||
"is_http_basic_auth_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "HTTP Basic Authentication enabled."
|
||||
|
|
@ -841,6 +903,68 @@
|
|||
"nullable": true,
|
||||
"description": "Use build server."
|
||||
},
|
||||
"use_build_secrets": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Use Docker Build Secrets for build-time environment variables."
|
||||
},
|
||||
"is_git_submodules_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Clone Git submodules."
|
||||
},
|
||||
"is_git_lfs_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable Git LFS."
|
||||
},
|
||||
"is_git_shallow_clone_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Use a shallow Git clone."
|
||||
},
|
||||
"disable_build_cache": {
|
||||
"type": "boolean",
|
||||
"description": "Disable the build cache."
|
||||
},
|
||||
"inject_build_args_to_dockerfile": {
|
||||
"type": "boolean",
|
||||
"description": "Inject build arguments into the Dockerfile build."
|
||||
},
|
||||
"include_source_commit_in_build": {
|
||||
"type": "boolean",
|
||||
"description": "Include the source commit in the build."
|
||||
},
|
||||
"is_env_sorting_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Sort environment variables."
|
||||
},
|
||||
"is_pr_deployments_public_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Make pull request deployments public."
|
||||
},
|
||||
"stop_grace_period": {
|
||||
"type": "integer",
|
||||
"nullable": true,
|
||||
"minimum": 1,
|
||||
"maximum": 3600,
|
||||
"description": "Container stop grace period in seconds."
|
||||
},
|
||||
"docker_images_to_keep": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 100,
|
||||
"description": "Number of Docker images to retain."
|
||||
},
|
||||
"is_gzip_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable gzip compression."
|
||||
},
|
||||
"is_stripprefix_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable path prefix stripping."
|
||||
},
|
||||
"is_raw_compose_deployment_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Deploy the raw Docker Compose definition."
|
||||
},
|
||||
"is_http_basic_auth_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "HTTP Basic Authentication enabled."
|
||||
|
|
@ -1302,6 +1426,68 @@
|
|||
"nullable": true,
|
||||
"description": "Use build server."
|
||||
},
|
||||
"use_build_secrets": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Use Docker Build Secrets for build-time environment variables."
|
||||
},
|
||||
"is_git_submodules_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Clone Git submodules."
|
||||
},
|
||||
"is_git_lfs_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable Git LFS."
|
||||
},
|
||||
"is_git_shallow_clone_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Use a shallow Git clone."
|
||||
},
|
||||
"disable_build_cache": {
|
||||
"type": "boolean",
|
||||
"description": "Disable the build cache."
|
||||
},
|
||||
"inject_build_args_to_dockerfile": {
|
||||
"type": "boolean",
|
||||
"description": "Inject build arguments into the Dockerfile build."
|
||||
},
|
||||
"include_source_commit_in_build": {
|
||||
"type": "boolean",
|
||||
"description": "Include the source commit in the build."
|
||||
},
|
||||
"is_env_sorting_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Sort environment variables."
|
||||
},
|
||||
"is_pr_deployments_public_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Make pull request deployments public."
|
||||
},
|
||||
"stop_grace_period": {
|
||||
"type": "integer",
|
||||
"nullable": true,
|
||||
"minimum": 1,
|
||||
"maximum": 3600,
|
||||
"description": "Container stop grace period in seconds."
|
||||
},
|
||||
"docker_images_to_keep": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 100,
|
||||
"description": "Number of Docker images to retain."
|
||||
},
|
||||
"is_gzip_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable gzip compression."
|
||||
},
|
||||
"is_stripprefix_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable path prefix stripping."
|
||||
},
|
||||
"is_raw_compose_deployment_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Deploy the raw Docker Compose definition."
|
||||
},
|
||||
"is_http_basic_auth_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "HTTP Basic Authentication enabled."
|
||||
|
|
@ -1668,6 +1854,68 @@
|
|||
"nullable": true,
|
||||
"description": "Use build server."
|
||||
},
|
||||
"use_build_secrets": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Use Docker Build Secrets for build-time environment variables."
|
||||
},
|
||||
"is_git_submodules_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Clone Git submodules."
|
||||
},
|
||||
"is_git_lfs_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable Git LFS."
|
||||
},
|
||||
"is_git_shallow_clone_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Use a shallow Git clone."
|
||||
},
|
||||
"disable_build_cache": {
|
||||
"type": "boolean",
|
||||
"description": "Disable the build cache."
|
||||
},
|
||||
"inject_build_args_to_dockerfile": {
|
||||
"type": "boolean",
|
||||
"description": "Inject build arguments into the Dockerfile build."
|
||||
},
|
||||
"include_source_commit_in_build": {
|
||||
"type": "boolean",
|
||||
"description": "Include the source commit in the build."
|
||||
},
|
||||
"is_env_sorting_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Sort environment variables."
|
||||
},
|
||||
"is_pr_deployments_public_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Make pull request deployments public."
|
||||
},
|
||||
"stop_grace_period": {
|
||||
"type": "integer",
|
||||
"nullable": true,
|
||||
"minimum": 1,
|
||||
"maximum": 3600,
|
||||
"description": "Container stop grace period in seconds."
|
||||
},
|
||||
"docker_images_to_keep": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 100,
|
||||
"description": "Number of Docker images to retain."
|
||||
},
|
||||
"is_gzip_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable gzip compression."
|
||||
},
|
||||
"is_stripprefix_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable path prefix stripping."
|
||||
},
|
||||
"is_raw_compose_deployment_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Deploy the raw Docker Compose definition."
|
||||
},
|
||||
"is_http_basic_auth_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "HTTP Basic Authentication enabled."
|
||||
|
|
@ -2014,6 +2262,68 @@
|
|||
"nullable": true,
|
||||
"description": "Use build server."
|
||||
},
|
||||
"use_build_secrets": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Use Docker Build Secrets for build-time environment variables."
|
||||
},
|
||||
"is_git_submodules_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Clone Git submodules."
|
||||
},
|
||||
"is_git_lfs_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable Git LFS."
|
||||
},
|
||||
"is_git_shallow_clone_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Use a shallow Git clone."
|
||||
},
|
||||
"disable_build_cache": {
|
||||
"type": "boolean",
|
||||
"description": "Disable the build cache."
|
||||
},
|
||||
"inject_build_args_to_dockerfile": {
|
||||
"type": "boolean",
|
||||
"description": "Inject build arguments into the Dockerfile build."
|
||||
},
|
||||
"include_source_commit_in_build": {
|
||||
"type": "boolean",
|
||||
"description": "Include the source commit in the build."
|
||||
},
|
||||
"is_env_sorting_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Sort environment variables."
|
||||
},
|
||||
"is_pr_deployments_public_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Make pull request deployments public."
|
||||
},
|
||||
"stop_grace_period": {
|
||||
"type": "integer",
|
||||
"nullable": true,
|
||||
"minimum": 1,
|
||||
"maximum": 3600,
|
||||
"description": "Container stop grace period in seconds."
|
||||
},
|
||||
"docker_images_to_keep": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 100,
|
||||
"description": "Number of Docker images to retain."
|
||||
},
|
||||
"is_gzip_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable gzip compression."
|
||||
},
|
||||
"is_stripprefix_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable path prefix stripping."
|
||||
},
|
||||
"is_raw_compose_deployment_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Deploy the raw Docker Compose definition."
|
||||
},
|
||||
"is_http_basic_auth_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "HTTP Basic Authentication enabled."
|
||||
|
|
@ -2596,6 +2906,67 @@
|
|||
"nullable": true,
|
||||
"description": "Use build server."
|
||||
},
|
||||
"use_build_secrets": {
|
||||
"type": "boolean",
|
||||
"description": "Use Docker Build Secrets for build-time environment variables."
|
||||
},
|
||||
"is_git_submodules_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Clone Git submodules."
|
||||
},
|
||||
"is_git_lfs_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable Git LFS."
|
||||
},
|
||||
"is_git_shallow_clone_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Use a shallow Git clone."
|
||||
},
|
||||
"disable_build_cache": {
|
||||
"type": "boolean",
|
||||
"description": "Disable the build cache."
|
||||
},
|
||||
"inject_build_args_to_dockerfile": {
|
||||
"type": "boolean",
|
||||
"description": "Inject build arguments into the Dockerfile build."
|
||||
},
|
||||
"include_source_commit_in_build": {
|
||||
"type": "boolean",
|
||||
"description": "Include the source commit in the build."
|
||||
},
|
||||
"is_env_sorting_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Sort environment variables."
|
||||
},
|
||||
"is_pr_deployments_public_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Make pull request deployments public."
|
||||
},
|
||||
"stop_grace_period": {
|
||||
"type": "integer",
|
||||
"nullable": true,
|
||||
"minimum": 1,
|
||||
"maximum": 3600,
|
||||
"description": "Container stop grace period in seconds."
|
||||
},
|
||||
"docker_images_to_keep": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 100,
|
||||
"description": "Number of Docker images to retain."
|
||||
},
|
||||
"is_gzip_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable gzip compression."
|
||||
},
|
||||
"is_stripprefix_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enable path prefix stripping."
|
||||
},
|
||||
"is_raw_compose_deployment_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Deploy the raw Docker Compose definition."
|
||||
},
|
||||
"connect_to_docker_network": {
|
||||
"type": "boolean",
|
||||
"description": "The flag to connect the service to the predefined Docker network."
|
||||
|
|
@ -2612,10 +2983,6 @@
|
|||
"is_preserve_repository_enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Preserve git repository during application update. If false, the existing repository will be removed and replaced with the new one. If true, the existing repository will be kept and the new one will be ignored. Default is false."
|
||||
},
|
||||
"include_source_commit_in_build": {
|
||||
"type": "boolean",
|
||||
"description": "Include source commit information in the build. Default is false."
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
|
|
@ -15146,6 +15513,9 @@
|
|||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Password for HTTP Basic Authentication"
|
||||
},
|
||||
"": {
|
||||
"$ref": "#\/components\/schemas\/ApplicationSetting"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
|
|
@ -15241,6 +15611,123 @@
|
|||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ApplicationSetting": {
|
||||
"description": "Application settings.",
|
||||
"properties": {
|
||||
"is_static": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_git_submodules_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_git_lfs_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_auto_deploy_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_force_https_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_debug_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_preview_deployments_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_log_drain_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_gpu_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"gpu_driver": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"gpu_count": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"gpu_device_ids": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"gpu_options": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"is_include_timestamps": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_swarm_only_worker_nodes": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_raw_compose_deployment_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_build_server_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_consistent_container_name_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_gzip_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_stripprefix_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"connect_to_docker_network": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"custom_internal_name": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"is_container_label_escape_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_env_sorting_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_container_label_readonly_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_preserve_repository_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"disable_build_cache": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_spa": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_git_shallow_clone_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_pr_deployments_public_enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"use_build_secrets": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"inject_build_args_to_dockerfile": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"include_source_commit_in_build": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"docker_images_to_keep": {
|
||||
"type": "integer"
|
||||
},
|
||||
"stop_grace_period": {
|
||||
"type": "integer",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"Environment": {
|
||||
"description": "Environment model",
|
||||
"properties": {
|
||||
|
|
|
|||
372
openapi.yaml
372
openapi.yaml
|
|
@ -268,6 +268,54 @@ paths:
|
|||
type: boolean
|
||||
nullable: true
|
||||
description: 'Use build server.'
|
||||
use_build_secrets:
|
||||
type: boolean
|
||||
default: false
|
||||
description: 'Use Docker Build Secrets for build-time environment variables.'
|
||||
is_git_submodules_enabled:
|
||||
type: boolean
|
||||
description: 'Clone Git submodules.'
|
||||
is_git_lfs_enabled:
|
||||
type: boolean
|
||||
description: 'Enable Git LFS.'
|
||||
is_git_shallow_clone_enabled:
|
||||
type: boolean
|
||||
description: 'Use a shallow Git clone.'
|
||||
disable_build_cache:
|
||||
type: boolean
|
||||
description: 'Disable the build cache.'
|
||||
inject_build_args_to_dockerfile:
|
||||
type: boolean
|
||||
description: 'Inject build arguments into the Dockerfile build.'
|
||||
include_source_commit_in_build:
|
||||
type: boolean
|
||||
description: 'Include the source commit in the build.'
|
||||
is_env_sorting_enabled:
|
||||
type: boolean
|
||||
description: 'Sort environment variables.'
|
||||
is_pr_deployments_public_enabled:
|
||||
type: boolean
|
||||
description: 'Make pull request deployments public.'
|
||||
stop_grace_period:
|
||||
type: integer
|
||||
nullable: true
|
||||
minimum: 1
|
||||
maximum: 3600
|
||||
description: 'Container stop grace period in seconds.'
|
||||
docker_images_to_keep:
|
||||
type: integer
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
description: 'Number of Docker images to retain.'
|
||||
is_gzip_enabled:
|
||||
type: boolean
|
||||
description: 'Enable gzip compression.'
|
||||
is_stripprefix_enabled:
|
||||
type: boolean
|
||||
description: 'Enable path prefix stripping.'
|
||||
is_raw_compose_deployment_enabled:
|
||||
type: boolean
|
||||
description: 'Deploy the raw Docker Compose definition.'
|
||||
is_http_basic_auth_enabled:
|
||||
type: boolean
|
||||
description: 'HTTP Basic Authentication enabled.'
|
||||
|
|
@ -562,6 +610,54 @@ paths:
|
|||
type: boolean
|
||||
nullable: true
|
||||
description: 'Use build server.'
|
||||
use_build_secrets:
|
||||
type: boolean
|
||||
default: false
|
||||
description: 'Use Docker Build Secrets for build-time environment variables.'
|
||||
is_git_submodules_enabled:
|
||||
type: boolean
|
||||
description: 'Clone Git submodules.'
|
||||
is_git_lfs_enabled:
|
||||
type: boolean
|
||||
description: 'Enable Git LFS.'
|
||||
is_git_shallow_clone_enabled:
|
||||
type: boolean
|
||||
description: 'Use a shallow Git clone.'
|
||||
disable_build_cache:
|
||||
type: boolean
|
||||
description: 'Disable the build cache.'
|
||||
inject_build_args_to_dockerfile:
|
||||
type: boolean
|
||||
description: 'Inject build arguments into the Dockerfile build.'
|
||||
include_source_commit_in_build:
|
||||
type: boolean
|
||||
description: 'Include the source commit in the build.'
|
||||
is_env_sorting_enabled:
|
||||
type: boolean
|
||||
description: 'Sort environment variables.'
|
||||
is_pr_deployments_public_enabled:
|
||||
type: boolean
|
||||
description: 'Make pull request deployments public.'
|
||||
stop_grace_period:
|
||||
type: integer
|
||||
nullable: true
|
||||
minimum: 1
|
||||
maximum: 3600
|
||||
description: 'Container stop grace period in seconds.'
|
||||
docker_images_to_keep:
|
||||
type: integer
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
description: 'Number of Docker images to retain.'
|
||||
is_gzip_enabled:
|
||||
type: boolean
|
||||
description: 'Enable gzip compression.'
|
||||
is_stripprefix_enabled:
|
||||
type: boolean
|
||||
description: 'Enable path prefix stripping.'
|
||||
is_raw_compose_deployment_enabled:
|
||||
type: boolean
|
||||
description: 'Deploy the raw Docker Compose definition.'
|
||||
is_http_basic_auth_enabled:
|
||||
type: boolean
|
||||
description: 'HTTP Basic Authentication enabled.'
|
||||
|
|
@ -856,6 +952,54 @@ paths:
|
|||
type: boolean
|
||||
nullable: true
|
||||
description: 'Use build server.'
|
||||
use_build_secrets:
|
||||
type: boolean
|
||||
default: false
|
||||
description: 'Use Docker Build Secrets for build-time environment variables.'
|
||||
is_git_submodules_enabled:
|
||||
type: boolean
|
||||
description: 'Clone Git submodules.'
|
||||
is_git_lfs_enabled:
|
||||
type: boolean
|
||||
description: 'Enable Git LFS.'
|
||||
is_git_shallow_clone_enabled:
|
||||
type: boolean
|
||||
description: 'Use a shallow Git clone.'
|
||||
disable_build_cache:
|
||||
type: boolean
|
||||
description: 'Disable the build cache.'
|
||||
inject_build_args_to_dockerfile:
|
||||
type: boolean
|
||||
description: 'Inject build arguments into the Dockerfile build.'
|
||||
include_source_commit_in_build:
|
||||
type: boolean
|
||||
description: 'Include the source commit in the build.'
|
||||
is_env_sorting_enabled:
|
||||
type: boolean
|
||||
description: 'Sort environment variables.'
|
||||
is_pr_deployments_public_enabled:
|
||||
type: boolean
|
||||
description: 'Make pull request deployments public.'
|
||||
stop_grace_period:
|
||||
type: integer
|
||||
nullable: true
|
||||
minimum: 1
|
||||
maximum: 3600
|
||||
description: 'Container stop grace period in seconds.'
|
||||
docker_images_to_keep:
|
||||
type: integer
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
description: 'Number of Docker images to retain.'
|
||||
is_gzip_enabled:
|
||||
type: boolean
|
||||
description: 'Enable gzip compression.'
|
||||
is_stripprefix_enabled:
|
||||
type: boolean
|
||||
description: 'Enable path prefix stripping.'
|
||||
is_raw_compose_deployment_enabled:
|
||||
type: boolean
|
||||
description: 'Deploy the raw Docker Compose definition.'
|
||||
is_http_basic_auth_enabled:
|
||||
type: boolean
|
||||
description: 'HTTP Basic Authentication enabled.'
|
||||
|
|
@ -1091,6 +1235,54 @@ paths:
|
|||
type: boolean
|
||||
nullable: true
|
||||
description: 'Use build server.'
|
||||
use_build_secrets:
|
||||
type: boolean
|
||||
default: false
|
||||
description: 'Use Docker Build Secrets for build-time environment variables.'
|
||||
is_git_submodules_enabled:
|
||||
type: boolean
|
||||
description: 'Clone Git submodules.'
|
||||
is_git_lfs_enabled:
|
||||
type: boolean
|
||||
description: 'Enable Git LFS.'
|
||||
is_git_shallow_clone_enabled:
|
||||
type: boolean
|
||||
description: 'Use a shallow Git clone.'
|
||||
disable_build_cache:
|
||||
type: boolean
|
||||
description: 'Disable the build cache.'
|
||||
inject_build_args_to_dockerfile:
|
||||
type: boolean
|
||||
description: 'Inject build arguments into the Dockerfile build.'
|
||||
include_source_commit_in_build:
|
||||
type: boolean
|
||||
description: 'Include the source commit in the build.'
|
||||
is_env_sorting_enabled:
|
||||
type: boolean
|
||||
description: 'Sort environment variables.'
|
||||
is_pr_deployments_public_enabled:
|
||||
type: boolean
|
||||
description: 'Make pull request deployments public.'
|
||||
stop_grace_period:
|
||||
type: integer
|
||||
nullable: true
|
||||
minimum: 1
|
||||
maximum: 3600
|
||||
description: 'Container stop grace period in seconds.'
|
||||
docker_images_to_keep:
|
||||
type: integer
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
description: 'Number of Docker images to retain.'
|
||||
is_gzip_enabled:
|
||||
type: boolean
|
||||
description: 'Enable gzip compression.'
|
||||
is_stripprefix_enabled:
|
||||
type: boolean
|
||||
description: 'Enable path prefix stripping.'
|
||||
is_raw_compose_deployment_enabled:
|
||||
type: boolean
|
||||
description: 'Deploy the raw Docker Compose definition.'
|
||||
is_http_basic_auth_enabled:
|
||||
type: boolean
|
||||
description: 'HTTP Basic Authentication enabled.'
|
||||
|
|
@ -1312,6 +1504,54 @@ paths:
|
|||
type: boolean
|
||||
nullable: true
|
||||
description: 'Use build server.'
|
||||
use_build_secrets:
|
||||
type: boolean
|
||||
default: false
|
||||
description: 'Use Docker Build Secrets for build-time environment variables.'
|
||||
is_git_submodules_enabled:
|
||||
type: boolean
|
||||
description: 'Clone Git submodules.'
|
||||
is_git_lfs_enabled:
|
||||
type: boolean
|
||||
description: 'Enable Git LFS.'
|
||||
is_git_shallow_clone_enabled:
|
||||
type: boolean
|
||||
description: 'Use a shallow Git clone.'
|
||||
disable_build_cache:
|
||||
type: boolean
|
||||
description: 'Disable the build cache.'
|
||||
inject_build_args_to_dockerfile:
|
||||
type: boolean
|
||||
description: 'Inject build arguments into the Dockerfile build.'
|
||||
include_source_commit_in_build:
|
||||
type: boolean
|
||||
description: 'Include the source commit in the build.'
|
||||
is_env_sorting_enabled:
|
||||
type: boolean
|
||||
description: 'Sort environment variables.'
|
||||
is_pr_deployments_public_enabled:
|
||||
type: boolean
|
||||
description: 'Make pull request deployments public.'
|
||||
stop_grace_period:
|
||||
type: integer
|
||||
nullable: true
|
||||
minimum: 1
|
||||
maximum: 3600
|
||||
description: 'Container stop grace period in seconds.'
|
||||
docker_images_to_keep:
|
||||
type: integer
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
description: 'Number of Docker images to retain.'
|
||||
is_gzip_enabled:
|
||||
type: boolean
|
||||
description: 'Enable gzip compression.'
|
||||
is_stripprefix_enabled:
|
||||
type: boolean
|
||||
description: 'Enable path prefix stripping.'
|
||||
is_raw_compose_deployment_enabled:
|
||||
type: boolean
|
||||
description: 'Deploy the raw Docker Compose definition.'
|
||||
is_http_basic_auth_enabled:
|
||||
type: boolean
|
||||
description: 'HTTP Basic Authentication enabled.'
|
||||
|
|
@ -1688,6 +1928,53 @@ paths:
|
|||
type: boolean
|
||||
nullable: true
|
||||
description: 'Use build server.'
|
||||
use_build_secrets:
|
||||
type: boolean
|
||||
description: 'Use Docker Build Secrets for build-time environment variables.'
|
||||
is_git_submodules_enabled:
|
||||
type: boolean
|
||||
description: 'Clone Git submodules.'
|
||||
is_git_lfs_enabled:
|
||||
type: boolean
|
||||
description: 'Enable Git LFS.'
|
||||
is_git_shallow_clone_enabled:
|
||||
type: boolean
|
||||
description: 'Use a shallow Git clone.'
|
||||
disable_build_cache:
|
||||
type: boolean
|
||||
description: 'Disable the build cache.'
|
||||
inject_build_args_to_dockerfile:
|
||||
type: boolean
|
||||
description: 'Inject build arguments into the Dockerfile build.'
|
||||
include_source_commit_in_build:
|
||||
type: boolean
|
||||
description: 'Include the source commit in the build.'
|
||||
is_env_sorting_enabled:
|
||||
type: boolean
|
||||
description: 'Sort environment variables.'
|
||||
is_pr_deployments_public_enabled:
|
||||
type: boolean
|
||||
description: 'Make pull request deployments public.'
|
||||
stop_grace_period:
|
||||
type: integer
|
||||
nullable: true
|
||||
minimum: 1
|
||||
maximum: 3600
|
||||
description: 'Container stop grace period in seconds.'
|
||||
docker_images_to_keep:
|
||||
type: integer
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
description: 'Number of Docker images to retain.'
|
||||
is_gzip_enabled:
|
||||
type: boolean
|
||||
description: 'Enable gzip compression.'
|
||||
is_stripprefix_enabled:
|
||||
type: boolean
|
||||
description: 'Enable path prefix stripping.'
|
||||
is_raw_compose_deployment_enabled:
|
||||
type: boolean
|
||||
description: 'Deploy the raw Docker Compose definition.'
|
||||
connect_to_docker_network:
|
||||
type: boolean
|
||||
description: 'The flag to connect the service to the predefined Docker network.'
|
||||
|
|
@ -1701,9 +1988,6 @@ paths:
|
|||
is_preserve_repository_enabled:
|
||||
type: boolean
|
||||
description: 'Preserve git repository during application update. If false, the existing repository will be removed and replaced with the new one. If true, the existing repository will be kept and the new one will be ignored. Default is false.'
|
||||
include_source_commit_in_build:
|
||||
type: boolean
|
||||
description: 'Include source commit information in the build. Default is false.'
|
||||
type: object
|
||||
responses:
|
||||
'200':
|
||||
|
|
@ -9683,6 +9967,8 @@ components:
|
|||
type: string
|
||||
nullable: true
|
||||
description: 'Password for HTTP Basic Authentication'
|
||||
'':
|
||||
$ref: '#/components/schemas/ApplicationSetting'
|
||||
type: object
|
||||
ApplicationDeploymentQueue:
|
||||
description: 'Project model'
|
||||
|
|
@ -9746,6 +10032,86 @@ components:
|
|||
commit_message:
|
||||
type: string
|
||||
type: object
|
||||
ApplicationSetting:
|
||||
description: 'Application settings.'
|
||||
properties:
|
||||
is_static:
|
||||
type: boolean
|
||||
is_git_submodules_enabled:
|
||||
type: boolean
|
||||
is_git_lfs_enabled:
|
||||
type: boolean
|
||||
is_auto_deploy_enabled:
|
||||
type: boolean
|
||||
is_force_https_enabled:
|
||||
type: boolean
|
||||
is_debug_enabled:
|
||||
type: boolean
|
||||
is_preview_deployments_enabled:
|
||||
type: boolean
|
||||
is_log_drain_enabled:
|
||||
type: boolean
|
||||
is_gpu_enabled:
|
||||
type: boolean
|
||||
gpu_driver:
|
||||
type: string
|
||||
nullable: true
|
||||
gpu_count:
|
||||
type: string
|
||||
nullable: true
|
||||
gpu_device_ids:
|
||||
type: string
|
||||
nullable: true
|
||||
gpu_options:
|
||||
type: string
|
||||
nullable: true
|
||||
is_include_timestamps:
|
||||
type: boolean
|
||||
is_swarm_only_worker_nodes:
|
||||
type: boolean
|
||||
is_raw_compose_deployment_enabled:
|
||||
type: boolean
|
||||
is_build_server_enabled:
|
||||
type: boolean
|
||||
is_consistent_container_name_enabled:
|
||||
type: boolean
|
||||
is_gzip_enabled:
|
||||
type: boolean
|
||||
is_stripprefix_enabled:
|
||||
type: boolean
|
||||
connect_to_docker_network:
|
||||
type: boolean
|
||||
custom_internal_name:
|
||||
type: string
|
||||
nullable: true
|
||||
is_container_label_escape_enabled:
|
||||
type: boolean
|
||||
is_env_sorting_enabled:
|
||||
type: boolean
|
||||
is_container_label_readonly_enabled:
|
||||
type: boolean
|
||||
is_preserve_repository_enabled:
|
||||
type: boolean
|
||||
disable_build_cache:
|
||||
type: boolean
|
||||
is_spa:
|
||||
type: boolean
|
||||
is_git_shallow_clone_enabled:
|
||||
type: boolean
|
||||
is_pr_deployments_public_enabled:
|
||||
type: boolean
|
||||
use_build_secrets:
|
||||
type: boolean
|
||||
inject_build_args_to_dockerfile:
|
||||
type: boolean
|
||||
include_source_commit_in_build:
|
||||
type: boolean
|
||||
docker_images_to_keep:
|
||||
type: integer
|
||||
stop_grace_period:
|
||||
type: integer
|
||||
nullable: true
|
||||
type: object
|
||||
Environment:
|
||||
description: 'Environment model'
|
||||
properties:
|
||||
|
|
|
|||
257
tests/Feature/Api/ApplicationBuildSecretsSettingApiTest.php
Normal file
257
tests/Feature/Api/ApplicationBuildSecretsSettingApiTest.php
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\Environment;
|
||||
use App\Models\GithubApp;
|
||||
use App\Models\InstanceSettings;
|
||||
use App\Models\PrivateKey;
|
||||
use App\Models\Project;
|
||||
use App\Models\Server;
|
||||
use App\Models\StandaloneDocker;
|
||||
use App\Models\Team;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
Storage::fake('ssh-keys');
|
||||
InstanceSettings::unguarded(fn () => InstanceSettings::firstOrCreate(['id' => 0]));
|
||||
|
||||
$this->team = Team::factory()->create();
|
||||
$this->user = User::factory()->create();
|
||||
$this->team->members()->attach($this->user->id, ['role' => 'owner']);
|
||||
session(['currentTeam' => $this->team]);
|
||||
|
||||
$this->bearerToken = $this->user->createToken('build-secrets-api-test', ['*'])->plainTextToken;
|
||||
$this->server = Server::factory()->create(['team_id' => $this->team->id]);
|
||||
$this->destination = StandaloneDocker::where('server_id', $this->server->id)->first();
|
||||
$this->project = Project::factory()->create(['team_id' => $this->team->id]);
|
||||
$this->environment = Environment::factory()->create(['project_id' => $this->project->id]);
|
||||
$this->application = Application::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
]);
|
||||
});
|
||||
|
||||
function buildSecretsApiHeaders(string $bearerToken): array
|
||||
{
|
||||
return [
|
||||
'Authorization' => 'Bearer '.$bearerToken,
|
||||
'Content-Type' => 'application/json',
|
||||
];
|
||||
}
|
||||
|
||||
function buildSecretsGithubPrivateKey(): string
|
||||
{
|
||||
$key = openssl_pkey_new([
|
||||
'private_key_bits' => 2048,
|
||||
'private_key_type' => OPENSSL_KEYTYPE_RSA,
|
||||
]);
|
||||
|
||||
openssl_pkey_export($key, $privateKey);
|
||||
|
||||
return $privateKey;
|
||||
}
|
||||
|
||||
describe('PATCH /api/v1/applications/{uuid} use_build_secrets', function () {
|
||||
test('updates the application setting', function () {
|
||||
expect($this->application->settings->use_build_secrets)->toBeFalse();
|
||||
|
||||
$this->withHeaders(buildSecretsApiHeaders($this->bearerToken))
|
||||
->patchJson("/api/v1/applications/{$this->application->uuid}", [
|
||||
'use_build_secrets' => true,
|
||||
])
|
||||
->assertOk();
|
||||
|
||||
expect($this->application->fresh()->settings->use_build_secrets)->toBeTrue();
|
||||
|
||||
$this->withHeaders(buildSecretsApiHeaders($this->bearerToken))
|
||||
->patchJson("/api/v1/applications/{$this->application->uuid}", [
|
||||
'use_build_secrets' => false,
|
||||
])
|
||||
->assertOk();
|
||||
|
||||
expect($this->application->fresh()->settings->use_build_secrets)->toBeFalse();
|
||||
});
|
||||
|
||||
test('rejects non boolean values', function () {
|
||||
$this->withHeaders(buildSecretsApiHeaders($this->bearerToken))
|
||||
->patchJson("/api/v1/applications/{$this->application->uuid}", [
|
||||
'use_build_secrets' => 'not-a-boolean',
|
||||
])
|
||||
->assertUnprocessable()
|
||||
->assertJsonValidationErrors('use_build_secrets');
|
||||
});
|
||||
|
||||
test('does not change the setting when omitted', function () {
|
||||
$this->application->settings->update(['use_build_secrets' => true]);
|
||||
|
||||
$this->withHeaders(buildSecretsApiHeaders($this->bearerToken))
|
||||
->patchJson("/api/v1/applications/{$this->application->uuid}", [
|
||||
'name' => 'updated-name',
|
||||
])
|
||||
->assertOk();
|
||||
|
||||
expect($this->application->fresh()->settings->use_build_secrets)->toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api/v1/applications/public use_build_secrets', function () {
|
||||
test('creates an application with the requested build secrets setting', function (bool $useBuildSecrets) {
|
||||
$response = $this->withHeaders(buildSecretsApiHeaders($this->bearerToken))
|
||||
->postJson('/api/v1/applications/public', [
|
||||
'project_uuid' => $this->project->uuid,
|
||||
'environment_uuid' => $this->environment->uuid,
|
||||
'server_uuid' => $this->server->uuid,
|
||||
'git_repository' => 'https://gitlab.com/coolify/build-secrets-test',
|
||||
'git_branch' => 'main',
|
||||
'build_pack' => 'nixpacks',
|
||||
'ports_exposes' => '3000',
|
||||
'use_build_secrets' => $useBuildSecrets,
|
||||
'autogenerate_domain' => false,
|
||||
])
|
||||
->assertCreated();
|
||||
|
||||
$application = Application::where('uuid', $response->json('uuid'))->firstOrFail();
|
||||
|
||||
expect($application->settings->use_build_secrets)->toBe($useBuildSecrets);
|
||||
})->with([
|
||||
'enabled' => true,
|
||||
'disabled' => false,
|
||||
]);
|
||||
|
||||
test('rejects non boolean values', function () {
|
||||
$this->withHeaders(buildSecretsApiHeaders($this->bearerToken))
|
||||
->postJson('/api/v1/applications/public', [
|
||||
'project_uuid' => $this->project->uuid,
|
||||
'environment_uuid' => $this->environment->uuid,
|
||||
'server_uuid' => $this->server->uuid,
|
||||
'git_repository' => 'https://gitlab.com/coolify/build-secrets-test',
|
||||
'git_branch' => 'main',
|
||||
'build_pack' => 'nixpacks',
|
||||
'ports_exposes' => '3000',
|
||||
'use_build_secrets' => 'not-a-boolean',
|
||||
'autogenerate_domain' => false,
|
||||
])
|
||||
->assertUnprocessable()
|
||||
->assertJsonValidationErrors('use_build_secrets');
|
||||
});
|
||||
});
|
||||
|
||||
describe('other application creation endpoints use_build_secrets', function () {
|
||||
test('creates a Dockerfile application with build secrets enabled', function () {
|
||||
$response = $this->withHeaders(buildSecretsApiHeaders($this->bearerToken))
|
||||
->postJson('/api/v1/applications/dockerfile', [
|
||||
'project_uuid' => $this->project->uuid,
|
||||
'environment_uuid' => $this->environment->uuid,
|
||||
'server_uuid' => $this->server->uuid,
|
||||
'dockerfile' => base64_encode("FROM nginx:alpine\nEXPOSE 80"),
|
||||
'use_build_secrets' => true,
|
||||
'autogenerate_domain' => false,
|
||||
])
|
||||
->assertCreated();
|
||||
|
||||
$application = Application::where('uuid', $response->json('uuid'))->firstOrFail();
|
||||
|
||||
expect($application->settings->use_build_secrets)->toBeTrue();
|
||||
});
|
||||
|
||||
test('creates a Docker image application with build secrets enabled', function () {
|
||||
$response = $this->withHeaders(buildSecretsApiHeaders($this->bearerToken))
|
||||
->postJson('/api/v1/applications/dockerimage', [
|
||||
'project_uuid' => $this->project->uuid,
|
||||
'environment_uuid' => $this->environment->uuid,
|
||||
'server_uuid' => $this->server->uuid,
|
||||
'docker_registry_image_name' => 'nginx',
|
||||
'docker_registry_image_tag' => 'alpine',
|
||||
'ports_exposes' => '80',
|
||||
'use_build_secrets' => true,
|
||||
'autogenerate_domain' => false,
|
||||
])
|
||||
->assertCreated();
|
||||
|
||||
$application = Application::where('uuid', $response->json('uuid'))->firstOrFail();
|
||||
|
||||
expect($application->settings->use_build_secrets)->toBeTrue();
|
||||
});
|
||||
|
||||
test('creates a private deploy key application with build secrets enabled', function () {
|
||||
$privateKey = PrivateKey::factory()->create(['team_id' => $this->team->id]);
|
||||
|
||||
$response = $this->withHeaders(buildSecretsApiHeaders($this->bearerToken))
|
||||
->postJson('/api/v1/applications/private-deploy-key', [
|
||||
'project_uuid' => $this->project->uuid,
|
||||
'environment_uuid' => $this->environment->uuid,
|
||||
'server_uuid' => $this->server->uuid,
|
||||
'private_key_uuid' => $privateKey->uuid,
|
||||
'git_repository' => 'git@gitlab.com:coolify/build-secrets-test.git',
|
||||
'git_branch' => 'main',
|
||||
'build_pack' => 'nixpacks',
|
||||
'ports_exposes' => '3000',
|
||||
'use_build_secrets' => true,
|
||||
'autogenerate_domain' => false,
|
||||
])
|
||||
->assertCreated();
|
||||
|
||||
$application = Application::where('uuid', $response->json('uuid'))->firstOrFail();
|
||||
|
||||
expect($application->settings->use_build_secrets)->toBeTrue();
|
||||
});
|
||||
|
||||
test('creates a private GitHub App application with build secrets enabled', function () {
|
||||
$privateKey = PrivateKey::create([
|
||||
'name' => 'GitHub App Key',
|
||||
'private_key' => buildSecretsGithubPrivateKey(),
|
||||
'team_id' => $this->team->id,
|
||||
]);
|
||||
$githubApp = GithubApp::create([
|
||||
'name' => 'Build Secrets GitHub App',
|
||||
'api_url' => 'https://api.github.com',
|
||||
'html_url' => 'https://github.com',
|
||||
'app_id' => 12345,
|
||||
'installation_id' => 67890,
|
||||
'client_id' => 'build-secrets-client-id',
|
||||
'client_secret' => 'build-secrets-client-secret',
|
||||
'webhook_secret' => 'build-secrets-webhook-secret',
|
||||
'private_key_id' => $privateKey->id,
|
||||
'team_id' => $this->team->id,
|
||||
'is_system_wide' => false,
|
||||
'is_public' => false,
|
||||
]);
|
||||
|
||||
Http::fake([
|
||||
'https://api.github.com/zen' => Http::response('Keep it logically awesome.', 200, [
|
||||
'Date' => now()->toRfc7231String(),
|
||||
]),
|
||||
'https://api.github.com/app/installations/67890/access_tokens' => Http::response([
|
||||
'token' => 'github-installation-token',
|
||||
], 201),
|
||||
'https://api.github.com/repos/coolify/build-secrets-test' => Http::response([
|
||||
'id' => 123456,
|
||||
]),
|
||||
]);
|
||||
|
||||
$response = $this->withHeaders(buildSecretsApiHeaders($this->bearerToken))
|
||||
->postJson('/api/v1/applications/private-github-app', [
|
||||
'project_uuid' => $this->project->uuid,
|
||||
'environment_uuid' => $this->environment->uuid,
|
||||
'server_uuid' => $this->server->uuid,
|
||||
'github_app_uuid' => $githubApp->uuid,
|
||||
'git_repository' => 'coolify/build-secrets-test',
|
||||
'git_branch' => 'main',
|
||||
'build_pack' => 'nixpacks',
|
||||
'ports_exposes' => '3000',
|
||||
'use_build_secrets' => true,
|
||||
'autogenerate_domain' => false,
|
||||
])
|
||||
->assertCreated();
|
||||
|
||||
$application = Application::where('uuid', $response->json('uuid'))->firstOrFail();
|
||||
|
||||
expect($application->settings->use_build_secrets)->toBeTrue();
|
||||
});
|
||||
});
|
||||
183
tests/Feature/Api/ApplicationSettingsApiTest.php
Normal file
183
tests/Feature/Api/ApplicationSettingsApiTest.php
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\Environment;
|
||||
use App\Models\InstanceSettings;
|
||||
use App\Models\Project;
|
||||
use App\Models\Server;
|
||||
use App\Models\StandaloneDocker;
|
||||
use App\Models\Team;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Queue;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
beforeEach(function () {
|
||||
InstanceSettings::unguarded(fn () => InstanceSettings::firstOrCreate(['id' => 0]));
|
||||
|
||||
$this->team = Team::factory()->create();
|
||||
$this->user = User::factory()->create();
|
||||
$this->team->members()->attach($this->user->id, ['role' => 'owner']);
|
||||
session(['currentTeam' => $this->team]);
|
||||
|
||||
$this->bearerToken = $this->user->createToken('application-settings-api-test', ['*'])->plainTextToken;
|
||||
$this->server = Server::factory()->create(['team_id' => $this->team->id]);
|
||||
$this->destination = StandaloneDocker::where('server_id', $this->server->id)->first();
|
||||
$this->project = Project::factory()->create(['team_id' => $this->team->id]);
|
||||
$this->environment = Environment::factory()->create(['project_id' => $this->project->id]);
|
||||
$this->application = Application::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
]);
|
||||
});
|
||||
|
||||
function applicationSettingsApiHeaders(string $bearerToken): array
|
||||
{
|
||||
return [
|
||||
'Authorization' => 'Bearer '.$bearerToken,
|
||||
'Content-Type' => 'application/json',
|
||||
];
|
||||
}
|
||||
|
||||
function recommendedApplicationSettingsPayload(): array
|
||||
{
|
||||
return [
|
||||
'is_git_submodules_enabled' => false,
|
||||
'is_git_lfs_enabled' => false,
|
||||
'is_git_shallow_clone_enabled' => false,
|
||||
'disable_build_cache' => true,
|
||||
'inject_build_args_to_dockerfile' => false,
|
||||
'include_source_commit_in_build' => true,
|
||||
'is_env_sorting_enabled' => true,
|
||||
'is_pr_deployments_public_enabled' => true,
|
||||
'stop_grace_period' => 45,
|
||||
'docker_images_to_keep' => 7,
|
||||
'is_gzip_enabled' => false,
|
||||
'is_stripprefix_enabled' => false,
|
||||
'is_raw_compose_deployment_enabled' => true,
|
||||
];
|
||||
}
|
||||
|
||||
test('GET /api/v1/applications/{uuid} includes settings without internal metadata', function () {
|
||||
$this->application->settings->update(recommendedApplicationSettingsPayload());
|
||||
|
||||
$this->withHeaders(applicationSettingsApiHeaders($this->bearerToken))
|
||||
->getJson("/api/v1/applications/{$this->application->uuid}")
|
||||
->assertOk()
|
||||
->assertJsonPath('settings.disable_build_cache', true)
|
||||
->assertJsonPath('settings.stop_grace_period', 45)
|
||||
->assertJsonMissingPath('settings.id')
|
||||
->assertJsonMissingPath('settings.application_id')
|
||||
->assertJsonMissingPath('settings.created_at')
|
||||
->assertJsonMissingPath('settings.updated_at');
|
||||
});
|
||||
|
||||
test('PATCH /api/v1/applications/{uuid} updates application settings', function () {
|
||||
$this->application->update(['build_pack' => 'dockercompose']);
|
||||
|
||||
$this->withHeaders(applicationSettingsApiHeaders($this->bearerToken))
|
||||
->patchJson("/api/v1/applications/{$this->application->uuid}", recommendedApplicationSettingsPayload())
|
||||
->assertOk();
|
||||
|
||||
$settings = $this->application->fresh()->settings;
|
||||
|
||||
foreach (recommendedApplicationSettingsPayload() as $field => $value) {
|
||||
expect($settings->{$field})->toBe($value);
|
||||
}
|
||||
});
|
||||
|
||||
test('application creation accepts application settings', function () {
|
||||
Queue::fake();
|
||||
|
||||
$response = $this->withHeaders(applicationSettingsApiHeaders($this->bearerToken))
|
||||
->postJson('/api/v1/applications/public', array_merge([
|
||||
'project_uuid' => $this->project->uuid,
|
||||
'environment_uuid' => $this->environment->uuid,
|
||||
'server_uuid' => $this->server->uuid,
|
||||
'git_repository' => 'https://gitlab.com/coolify/application-settings-test',
|
||||
'git_branch' => 'main',
|
||||
'build_pack' => 'dockercompose',
|
||||
'autogenerate_domain' => false,
|
||||
], recommendedApplicationSettingsPayload()))
|
||||
->assertCreated();
|
||||
|
||||
$settings = Application::where('uuid', $response->json('uuid'))->firstOrFail()->settings;
|
||||
|
||||
foreach (recommendedApplicationSettingsPayload() as $field => $value) {
|
||||
expect($settings->{$field})->toBe($value);
|
||||
}
|
||||
});
|
||||
|
||||
test('proxy settings regenerate managed labels', function () {
|
||||
$this->application->settings->update([
|
||||
'is_container_label_readonly_enabled' => true,
|
||||
'is_gzip_enabled' => true,
|
||||
'is_stripprefix_enabled' => true,
|
||||
]);
|
||||
$this->application->update(['custom_labels' => base64_encode('sentinel-label=true')]);
|
||||
|
||||
$this->withHeaders(applicationSettingsApiHeaders($this->bearerToken))
|
||||
->patchJson("/api/v1/applications/{$this->application->uuid}", [
|
||||
'is_gzip_enabled' => false,
|
||||
'is_stripprefix_enabled' => false,
|
||||
])
|
||||
->assertOk();
|
||||
|
||||
expect(base64_decode($this->application->fresh()->custom_labels))->not->toContain('sentinel-label=true');
|
||||
});
|
||||
|
||||
test('rejects invalid boolean application settings', function () {
|
||||
$this->withHeaders(applicationSettingsApiHeaders($this->bearerToken))
|
||||
->patchJson("/api/v1/applications/{$this->application->uuid}", [
|
||||
'disable_build_cache' => 'not-a-boolean',
|
||||
])
|
||||
->assertUnprocessable()
|
||||
->assertJsonValidationErrors('disable_build_cache');
|
||||
});
|
||||
|
||||
test('validates stop grace period bounds', function (int $stopGracePeriod) {
|
||||
$this->withHeaders(applicationSettingsApiHeaders($this->bearerToken))
|
||||
->patchJson("/api/v1/applications/{$this->application->uuid}", [
|
||||
'stop_grace_period' => $stopGracePeriod,
|
||||
])
|
||||
->assertUnprocessable()
|
||||
->assertJsonValidationErrors('stop_grace_period');
|
||||
})->with([
|
||||
'below minimum' => 0,
|
||||
'above maximum' => 3601,
|
||||
]);
|
||||
|
||||
test('validates Docker image retention bounds', function (int $dockerImagesToKeep) {
|
||||
$this->withHeaders(applicationSettingsApiHeaders($this->bearerToken))
|
||||
->patchJson("/api/v1/applications/{$this->application->uuid}", [
|
||||
'docker_images_to_keep' => $dockerImagesToKeep,
|
||||
])
|
||||
->assertUnprocessable()
|
||||
->assertJsonValidationErrors('docker_images_to_keep');
|
||||
})->with([
|
||||
'below minimum' => -1,
|
||||
'above maximum' => 101,
|
||||
]);
|
||||
|
||||
test('stop grace period can be reset to null', function () {
|
||||
$this->application->settings->update(['stop_grace_period' => 45]);
|
||||
|
||||
$this->withHeaders(applicationSettingsApiHeaders($this->bearerToken))
|
||||
->patchJson("/api/v1/applications/{$this->application->uuid}", [
|
||||
'stop_grace_period' => null,
|
||||
])
|
||||
->assertOk();
|
||||
|
||||
expect($this->application->fresh()->settings->stop_grace_period)->toBeNull();
|
||||
});
|
||||
|
||||
test('raw compose deployment can only be enabled for Docker Compose applications', function () {
|
||||
$this->withHeaders(applicationSettingsApiHeaders($this->bearerToken))
|
||||
->patchJson("/api/v1/applications/{$this->application->uuid}", [
|
||||
'is_raw_compose_deployment_enabled' => true,
|
||||
])
|
||||
->assertUnprocessable()
|
||||
->assertJsonValidationErrors('is_raw_compose_deployment_enabled');
|
||||
});
|
||||
Loading…
Reference in a new issue