diff --git a/.github/workflows/coolify-helper-next.yml b/.github/workflows/coolify-helper-next.yml index fec54d54a..2e50abbe7 100644 --- a/.github/workflows/coolify-helper-next.yml +++ b/.github/workflows/coolify-helper-next.yml @@ -44,8 +44,8 @@ jobs: uses: docker/login-action@v3 with: registry: ${{ env.DOCKER_REGISTRY }} - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Get Version id: version @@ -86,8 +86,8 @@ jobs: uses: docker/login-action@v3 with: registry: ${{ env.DOCKER_REGISTRY }} - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Get Version id: version diff --git a/.github/workflows/coolify-helper.yml b/.github/workflows/coolify-helper.yml index 0c9996ec8..ed6fc3bcb 100644 --- a/.github/workflows/coolify-helper.yml +++ b/.github/workflows/coolify-helper.yml @@ -44,8 +44,8 @@ jobs: uses: docker/login-action@v3 with: registry: ${{ env.DOCKER_REGISTRY }} - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Get Version id: version @@ -85,8 +85,8 @@ jobs: uses: docker/login-action@v3 with: registry: ${{ env.DOCKER_REGISTRY }} - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Get Version id: version diff --git a/.github/workflows/coolify-production-build.yml b/.github/workflows/coolify-production-build.yml index 21871b103..477274751 100644 --- a/.github/workflows/coolify-production-build.yml +++ b/.github/workflows/coolify-production-build.yml @@ -51,8 +51,8 @@ jobs: uses: docker/login-action@v3 with: registry: ${{ env.DOCKER_REGISTRY }} - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Get Version id: version @@ -91,8 +91,8 @@ jobs: uses: docker/login-action@v3 with: registry: ${{ env.DOCKER_REGISTRY }} - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Get Version id: version diff --git a/.github/workflows/coolify-realtime-next.yml b/.github/workflows/coolify-realtime-next.yml index 7ab4dcc42..8937ea27d 100644 --- a/.github/workflows/coolify-realtime-next.yml +++ b/.github/workflows/coolify-realtime-next.yml @@ -48,8 +48,8 @@ jobs: uses: docker/login-action@v3 with: registry: ${{ env.DOCKER_REGISTRY }} - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Get Version id: version @@ -90,8 +90,8 @@ jobs: uses: docker/login-action@v3 with: registry: ${{ env.DOCKER_REGISTRY }} - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Get Version id: version diff --git a/.github/workflows/coolify-realtime.yml b/.github/workflows/coolify-realtime.yml index 5efe445c5..d8784dd50 100644 --- a/.github/workflows/coolify-realtime.yml +++ b/.github/workflows/coolify-realtime.yml @@ -48,8 +48,8 @@ jobs: uses: docker/login-action@v3 with: registry: ${{ env.DOCKER_REGISTRY }} - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Get Version id: version @@ -90,8 +90,8 @@ jobs: uses: docker/login-action@v3 with: registry: ${{ env.DOCKER_REGISTRY }} - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Get Version id: version diff --git a/.github/workflows/coolify-staging-build.yml b/.github/workflows/coolify-staging-build.yml index 67b7b03e8..494ef6939 100644 --- a/.github/workflows/coolify-staging-build.yml +++ b/.github/workflows/coolify-staging-build.yml @@ -64,8 +64,8 @@ jobs: uses: docker/login-action@v3 with: registry: ${{ env.DOCKER_REGISTRY }} - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and Push Image (${{ matrix.arch }}) uses: docker/build-push-action@v6 @@ -110,8 +110,8 @@ jobs: uses: docker/login-action@v3 with: registry: ${{ env.DOCKER_REGISTRY }} - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }} run: | diff --git a/.github/workflows/coolify-testing-host.yml b/.github/workflows/coolify-testing-host.yml index 24133887a..0c1371573 100644 --- a/.github/workflows/coolify-testing-host.yml +++ b/.github/workflows/coolify-testing-host.yml @@ -44,8 +44,8 @@ jobs: uses: docker/login-action@v3 with: registry: ${{ env.DOCKER_REGISTRY }} - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and Push Image (${{ matrix.arch }}) uses: docker/build-push-action@v6 @@ -81,8 +81,8 @@ jobs: uses: docker/login-action@v3 with: registry: ${{ env.DOCKER_REGISTRY }} - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }} run: | diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 3c428cf5f..6df9a8623 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -670,13 +670,20 @@ private function deploy_docker_compose_buildpack() $build_command = "DOCKER_BUILDKIT=1 {$build_command}"; } - // Append build arguments if not using build secrets (matching default behavior) + // Inject build arguments after build subcommand if not using build secrets if (! $this->application->settings->use_build_secrets && $this->build_args instanceof \Illuminate\Support\Collection && $this->build_args->isNotEmpty()) { $build_args_string = $this->build_args->implode(' '); // Escape single quotes for bash -c context used by executeInDocker $build_args_string = str_replace("'", "'\\''", $build_args_string); - $build_command .= " {$build_args_string}"; - $this->application_deployment_queue->addLogEntry('Adding build arguments to custom Docker Compose build command.'); + + // Inject build args right after 'build' subcommand (not at the end) + $original_command = $build_command; + $build_command = injectDockerComposeBuildArgs($build_command, $build_args_string); + + // Only log if build args were actually injected (command was modified) + if ($build_command !== $original_command) { + $this->application_deployment_queue->addLogEntry('Adding build arguments to custom Docker Compose build command.'); + } } $this->execute_remote_command( diff --git a/app/Livewire/Project/Application/General.php b/app/Livewire/Project/Application/General.php index 71ca9720e..ef474fb02 100644 --- a/app/Livewire/Project/Application/General.php +++ b/app/Livewire/Project/Application/General.php @@ -1018,11 +1018,27 @@ public function getDockerComposeBuildCommandPreviewProperty(): string // Use relative path for clarity in preview (e.g., ./backend/docker-compose.yaml) // Actual deployment uses absolute path: /artifacts/{deployment_uuid}{base_directory}{docker_compose_location} // Build-time env path references ApplicationDeploymentJob::BUILD_TIME_ENV_PATH as source of truth - return injectDockerComposeFlags( + $command = injectDockerComposeFlags( $this->dockerComposeCustomBuildCommand, ".{$normalizedBase}{$this->dockerComposeLocation}", \App\Jobs\ApplicationDeploymentJob::BUILD_TIME_ENV_PATH ); + + // Inject build args if not using build secrets + if (! $this->application->settings->use_build_secrets) { + $buildTimeEnvs = $this->application->environment_variables() + ->where('is_buildtime', true) + ->get(); + + if ($buildTimeEnvs->isNotEmpty()) { + $buildArgs = generateDockerBuildArgs($buildTimeEnvs); + $buildArgsString = $buildArgs->implode(' '); + + $command = injectDockerComposeBuildArgs($command, $buildArgsString); + } + } + + return $command; } public function getDockerComposeStartCommandPreviewProperty(): string diff --git a/app/Livewire/Project/Service/ServiceApplicationView.php b/app/Livewire/Project/Service/ServiceApplicationView.php index 259b9dbec..68544f1ab 100644 --- a/app/Livewire/Project/Service/ServiceApplicationView.php +++ b/app/Livewire/Project/Service/ServiceApplicationView.php @@ -82,6 +82,21 @@ public function instantSave() } } + public function instantSaveSettings() + { + try { + $this->authorize('update', $this->application); + // Save checkbox states without port validation + $this->application->is_gzip_enabled = $this->isGzipEnabled; + $this->application->is_stripprefix_enabled = $this->isStripprefixEnabled; + $this->application->exclude_from_status = $this->excludeFromStatus; + $this->application->save(); + $this->dispatch('success', 'Settings saved.'); + } catch (\Throwable $e) { + return handleError($e, $this); + } + } + public function instantSaveAdvanced() { try { diff --git a/app/Notifications/Server/TraefikVersionOutdated.php b/app/Notifications/Server/TraefikVersionOutdated.php index 09ef4257d..c94cc1732 100644 --- a/app/Notifications/Server/TraefikVersionOutdated.php +++ b/app/Notifications/Server/TraefikVersionOutdated.php @@ -43,9 +43,19 @@ public function toMail($notifiable = null): MailMessage $mail = new MailMessage; $count = $this->servers->count(); + // Transform servers to include URLs + $serversWithUrls = $this->servers->map(function ($server) { + return [ + 'name' => $server->name, + 'uuid' => $server->uuid, + 'url' => base_url().'/server/'.$server->uuid.'/proxy', + 'outdatedInfo' => $server->outdatedInfo ?? [], + ]; + }); + $mail->subject("Coolify: Traefik proxy outdated on {$count} server(s)"); $mail->view('emails.traefik-version-outdated', [ - 'servers' => $this->servers, + 'servers' => $serversWithUrls, 'count' => $count, ]); diff --git a/bootstrap/helpers/docker.php b/bootstrap/helpers/docker.php index 4a0faaec1..f6d69ef60 100644 --- a/bootstrap/helpers/docker.php +++ b/bootstrap/helpers/docker.php @@ -1376,3 +1376,62 @@ function injectDockerComposeFlags(string $command, string $composeFilePath, stri // Replace only first occurrence to avoid modifying comments/strings/chained commands return preg_replace('/docker\s+compose/', $dockerComposeReplacement, $command, 1); } + +/** + * Inject build arguments right after build-related subcommands in docker/docker compose commands. + * This ensures build args are only applied to build operations, not to push, pull, up, etc. + * + * Supports: + * - docker compose build + * - docker buildx build + * - docker builder build + * - docker build (legacy) + * + * Examples: + * - Input: "docker compose -f file.yml build" + * Output: "docker compose -f file.yml build --build-arg X --build-arg Y" + * + * - Input: "docker buildx build --platform linux/amd64" + * Output: "docker buildx build --build-arg X --build-arg Y --platform linux/amd64" + * + * - Input: "docker builder build --tag myimage:latest" + * Output: "docker builder build --build-arg X --build-arg Y --tag myimage:latest" + * + * - Input: "docker compose build && docker compose push" + * Output: "docker compose build --build-arg X --build-arg Y && docker compose push" + * + * - Input: "docker compose push" + * Output: "docker compose push" (unchanged - no build command found) + * + * @param string $command The docker command + * @param string $buildArgsString The build arguments to inject (e.g., "--build-arg X --build-arg Y") + * @return string The modified command with build args injected after build subcommand + */ +function injectDockerComposeBuildArgs(string $command, string $buildArgsString): string +{ + // Early return if no build args to inject + if (empty(trim($buildArgsString))) { + return $command; + } + + // Match build-related commands: + // - ' builder build' (docker builder build) + // - ' buildx build' (docker buildx build) + // - ' build' (docker compose build, docker build) + // Followed by either: + // - whitespace (allowing service names, flags, or any valid arguments) + // - end of string ($) + // This regex ensures we match build subcommands, not "build" in other contexts + // IMPORTANT: Order matters - check longer patterns first (builder build, buildx build) before ' build' + $pattern = '/( builder build| buildx build| build)(?=\s|$)/'; + + // Replace the first occurrence of build command with build command + build-args + $modifiedCommand = preg_replace( + $pattern, + '$1 '.$buildArgsString, + $command, + 1 // Only replace first occurrence + ); + + return $modifiedCommand ?? $command; +} diff --git a/config/constants.php b/config/constants.php index 9b1dd5f68..c55bec981 100644 --- a/config/constants.php +++ b/config/constants.php @@ -2,7 +2,7 @@ return [ 'coolify' => [ - 'version' => '4.0.0-beta.452', + 'version' => '4.0.0-beta.453', 'helper_version' => '1.0.12', 'realtime_version' => '1.0.10', 'self_hosted' => env('SELF_HOSTED', true), diff --git a/other/nightly/versions.json b/other/nightly/versions.json index 577fdfe18..6d3f90371 100644 --- a/other/nightly/versions.json +++ b/other/nightly/versions.json @@ -1,10 +1,10 @@ { "coolify": { "v4": { - "version": "4.0.0-beta.452" + "version": "4.0.0-beta.453" }, "nightly": { - "version": "4.0.0-beta.453" + "version": "4.0.0-beta.454" }, "helper": { "version": "1.0.12" diff --git a/resources/views/emails/traefik-version-outdated.blade.php b/resources/views/emails/traefik-version-outdated.blade.php index 28effabf3..91c627a73 100644 --- a/resources/views/emails/traefik-version-outdated.blade.php +++ b/resources/views/emails/traefik-version-outdated.blade.php @@ -5,10 +5,12 @@ @foreach ($servers as $server) @php - $info = $server->outdatedInfo ?? []; - $current = $info['current'] ?? 'unknown'; - $latest = $info['latest'] ?? 'unknown'; - $isPatch = ($info['type'] ?? 'patch_update') === 'patch_update'; + $serverName = data_get($server, 'name', 'Unknown Server'); + $serverUrl = data_get($server, 'url', '#'); + $info = data_get($server, 'outdatedInfo', []); + $current = data_get($info, 'current', 'unknown'); + $latest = data_get($info, 'latest', 'unknown'); + $isPatch = (data_get($info, 'type', 'patch_update') === 'patch_update'); $hasNewerBranch = isset($info['newer_branch_target']); $hasUpgrades = $hasUpgrades ?? false; if (!$isPatch || $hasNewerBranch) { @@ -19,8 +21,9 @@ $latest = str_starts_with($latest, 'v') ? $latest : "v{$latest}"; // For minor upgrades, use the upgrade_target (e.g., "v3.6") - if (!$isPatch && isset($info['upgrade_target'])) { - $upgradeTarget = str_starts_with($info['upgrade_target'], 'v') ? $info['upgrade_target'] : "v{$info['upgrade_target']}"; + if (!$isPatch && data_get($info, 'upgrade_target')) { + $upgradeTarget = data_get($info, 'upgrade_target'); + $upgradeTarget = str_starts_with($upgradeTarget, 'v') ? $upgradeTarget : "v{$upgradeTarget}"; } else { // For patch updates, show the full version $upgradeTarget = $latest; @@ -28,22 +31,23 @@ // Get newer branch info if available if ($hasNewerBranch) { - $newerBranchTarget = $info['newer_branch_target']; - $newerBranchLatest = str_starts_with($info['newer_branch_latest'], 'v') ? $info['newer_branch_latest'] : "v{$info['newer_branch_latest']}"; + $newerBranchTarget = data_get($info, 'newer_branch_target', 'unknown'); + $newerBranchLatest = data_get($info, 'newer_branch_latest', 'unknown'); + $newerBranchLatest = str_starts_with($newerBranchLatest, 'v') ? $newerBranchLatest : "v{$newerBranchLatest}"; } @endphp @if ($isPatch && $hasNewerBranch) -- **{{ $server->name }}**: {{ $current }} → {{ $upgradeTarget }} (patch update available) | Also available: {{ $newerBranchTarget }} (latest patch: {{ $newerBranchLatest }}) - new minor version +- [**{{ $serverName }}**]({{ $serverUrl }}): {{ $current }} → {{ $upgradeTarget }} (patch update available) | Also available: {{ $newerBranchTarget }} (latest patch: {{ $newerBranchLatest }}) - new minor version @elseif ($isPatch) -- **{{ $server->name }}**: {{ $current }} → {{ $upgradeTarget }} (patch update available) +- [**{{ $serverName }}**]({{ $serverUrl }}): {{ $current }} → {{ $upgradeTarget }} (patch update available) @else -- **{{ $server->name }}**: {{ $current }} (latest patch: {{ $latest }}) → {{ $upgradeTarget }} (new minor version available) +- [**{{ $serverName }}**]({{ $serverUrl }}): {{ $current }} (latest patch: {{ $latest }}) → {{ $upgradeTarget }} (new minor version available) @endif @endforeach ## Recommendation -It is recommended to test the new Traefik version before switching it in production environments. You can update your proxy configuration through your [Coolify Dashboard]({{ config('app.url') }}). +It is recommended to test the new Traefik version before switching it in production environments. You can update your proxy configuration by clicking on any server name above. @if ($hasUpgrades ?? false) **Important for minor version upgrades:** Before upgrading to a new minor version, please read the [Traefik changelog](https://github.com/traefik/traefik/releases) to understand breaking changes and new features. @@ -58,5 +62,5 @@ --- -You can manage your server proxy settings in your Coolify Dashboard. +Click on any server name above to manage its proxy settings. diff --git a/resources/views/livewire/project/service/service-application-view.blade.php b/resources/views/livewire/project/service/service-application-view.blade.php index 5fb4a62d0..f04e33817 100644 --- a/resources/views/livewire/project/service/service-application-view.blade.php +++ b/resources/views/livewire/project/service/service-application-view.blade.php @@ -56,18 +56,18 @@

Advanced

@if (str($application->image)->contains('pocketbase')) - @else - @endif - -

DNS Settings

API Settings

+ helper="If enabled, authenticated requests to Coolify's REST API will be allowed. Configure API tokens in Security > API Tokens." />

Confirmation Settings

+ helper="Show monthly sponsorship reminders to support Coolify development. Disable to hide these messages permanently." />
diff --git a/tests/Feature/CheckTraefikVersionJobTest.php b/tests/Feature/CheckTraefikVersionJobTest.php index b7c5dd50d..cee156485 100644 --- a/tests/Feature/CheckTraefikVersionJobTest.php +++ b/tests/Feature/CheckTraefikVersionJobTest.php @@ -214,3 +214,90 @@ expect($notification->servers)->toHaveCount(1); expect($notification->servers->first()->outdatedInfo['type'])->toBe('patch_update'); }); + +it('notification generates correct server proxy URLs', function () { + $team = Team::factory()->create(); + $server = Server::factory()->create([ + 'name' => 'Test Server', + 'team_id' => $team->id, + 'uuid' => 'test-uuid-123', + ]); + + $server->outdatedInfo = [ + 'current' => '3.5.0', + 'latest' => '3.5.6', + 'type' => 'patch_update', + ]; + + $notification = new TraefikVersionOutdated(collect([$server])); + $mail = $notification->toMail($team); + + // Verify the mail has the transformed servers with URLs + expect($mail->viewData['servers'])->toHaveCount(1); + expect($mail->viewData['servers'][0]['name'])->toBe('Test Server'); + expect($mail->viewData['servers'][0]['uuid'])->toBe('test-uuid-123'); + expect($mail->viewData['servers'][0]['url'])->toBe(base_url().'/server/test-uuid-123/proxy'); + expect($mail->viewData['servers'][0]['outdatedInfo'])->toBeArray(); +}); + +it('notification transforms multiple servers with URLs correctly', function () { + $team = Team::factory()->create(); + $server1 = Server::factory()->create([ + 'name' => 'Server 1', + 'team_id' => $team->id, + 'uuid' => 'uuid-1', + ]); + $server1->outdatedInfo = [ + 'current' => '3.5.0', + 'latest' => '3.5.6', + 'type' => 'patch_update', + ]; + + $server2 = Server::factory()->create([ + 'name' => 'Server 2', + 'team_id' => $team->id, + 'uuid' => 'uuid-2', + ]); + $server2->outdatedInfo = [ + 'current' => '3.4.0', + 'latest' => '3.6.0', + 'type' => 'minor_upgrade', + 'upgrade_target' => 'v3.6', + ]; + + $servers = collect([$server1, $server2]); + $notification = new TraefikVersionOutdated($servers); + $mail = $notification->toMail($team); + + // Verify both servers have URLs + expect($mail->viewData['servers'])->toHaveCount(2); + + expect($mail->viewData['servers'][0]['name'])->toBe('Server 1'); + expect($mail->viewData['servers'][0]['url'])->toBe(base_url().'/server/uuid-1/proxy'); + + expect($mail->viewData['servers'][1]['name'])->toBe('Server 2'); + expect($mail->viewData['servers'][1]['url'])->toBe(base_url().'/server/uuid-2/proxy'); +}); + +it('notification uses base_url helper not config app.url', function () { + $team = Team::factory()->create(); + $server = Server::factory()->create([ + 'name' => 'Test Server', + 'team_id' => $team->id, + 'uuid' => 'test-uuid', + ]); + + $server->outdatedInfo = [ + 'current' => '3.5.0', + 'latest' => '3.5.6', + 'type' => 'patch_update', + ]; + + $notification = new TraefikVersionOutdated(collect([$server])); + $mail = $notification->toMail($team); + + // Verify URL starts with base_url() not config('app.url') + $generatedUrl = $mail->viewData['servers'][0]['url']; + expect($generatedUrl)->toStartWith(base_url()); + expect($generatedUrl)->not->toContain('localhost'); +}); diff --git a/tests/Unit/ApplicationDeploymentCustomBuildCommandTest.php b/tests/Unit/ApplicationDeploymentCustomBuildCommandTest.php index fc29f19c3..3dd18ee6c 100644 --- a/tests/Unit/ApplicationDeploymentCustomBuildCommandTest.php +++ b/tests/Unit/ApplicationDeploymentCustomBuildCommandTest.php @@ -615,3 +615,58 @@ expect($path)->not->toContain('//', "Double slash found for baseDir: {$case['baseDir']}"); } }); + +// Tests for injectDockerComposeBuildArgs() helper function +it('injects build args when building specific service', function () { + $command = 'docker compose build web'; + $buildArgs = '--build-arg ENV=prod'; + + $result = injectDockerComposeBuildArgs($command, $buildArgs); + + expect($result)->toBe('docker compose build --build-arg ENV=prod web'); +}); + +it('injects build args with service name containing hyphens', function () { + $command = 'docker compose build my-service-name'; + $buildArgs = '--build-arg TEST=value'; + + $result = injectDockerComposeBuildArgs($command, $buildArgs); + + expect($result)->toBe('docker compose build --build-arg TEST=value my-service-name'); +}); + +it('injects build args with service name containing underscores', function () { + $command = 'docker compose build my_service_name'; + $buildArgs = '--build-arg TEST=value'; + + $result = injectDockerComposeBuildArgs($command, $buildArgs); + + expect($result)->toBe('docker compose build --build-arg TEST=value my_service_name'); +}); + +it('injects build args before service name and existing flags', function () { + $command = 'docker compose build backend --no-cache'; + $buildArgs = '--build-arg FOO=bar'; + + $result = injectDockerComposeBuildArgs($command, $buildArgs); + + expect($result)->toBe('docker compose build --build-arg FOO=bar backend --no-cache'); +}); + +it('handles buildx with target and flags', function () { + $command = 'docker buildx build --platform linux/amd64 -t myimage:latest .'; + $buildArgs = '--build-arg VERSION=1.0'; + + $result = injectDockerComposeBuildArgs($command, $buildArgs); + + expect($result)->toBe('docker buildx build --build-arg VERSION=1.0 --platform linux/amd64 -t myimage:latest .'); +}); + +it('handles docker compose build with no arguments', function () { + $command = 'docker compose build'; + $buildArgs = '--build-arg FOO=bar'; + + $result = injectDockerComposeBuildArgs($command, $buildArgs); + + expect($result)->toBe('docker compose build --build-arg FOO=bar'); +}); diff --git a/versions.json b/versions.json index 577fdfe18..6d3f90371 100644 --- a/versions.json +++ b/versions.json @@ -1,10 +1,10 @@ { "coolify": { "v4": { - "version": "4.0.0-beta.452" + "version": "4.0.0-beta.453" }, "nightly": { - "version": "4.0.0-beta.453" + "version": "4.0.0-beta.454" }, "helper": { "version": "1.0.12"