From 03f01e322e9239134d188c7f946f74a52e7dcf22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Sun, 18 May 2025 10:30:27 +0200 Subject: [PATCH] SSR detection without createCommand and remove=false --- .../Modules/Functions/Workers/Builds.php | 82 ++++++++++--------- 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php index c7fc833316..1b3e1a8af9 100644 --- a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php +++ b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php @@ -659,6 +659,11 @@ class Builds extends Action if ($version === 'v2') { $command = 'tar -zxf /tmp/code.tar.gz -C /usr/code && cd /usr/local/src/ && ./build.sh'; } else { + if ($resource->getCollection() === 'sites') { + $listFilesCommand = 'echo "{APPWRITE_DETECTION_SEPARATOR}" && cd /usr/local/build && cd $OPEN_RUNTIMES_OUTPUT_DIRECTORY && find . -name \'node_modules\' -prune -o -type f -print'; + $command .= '&& ' . $listFilesCommand; + } + $command = 'tar -zxf /tmp/code.tar.gz -C /mnt/code && helpers/build.sh ' . \trim(\escapeshellarg($command)); } @@ -706,6 +711,12 @@ class Builds extends Action // Get only valid UTF8 part - removes leftover half-multibytes causing SQL errors $logs = \mb_substr($logs, 0, null, 'UTF-8'); + // Do not stream logs added for SSR detection + $separator = \strpos($logs, '{APPWRITE_DETECTION_SEPARATOR}'); + if ($separator !== false) { + $logs = substr($logs, 0, $separator); + } + $currentLogs = $deployment->getAttribute('buildLogs', ''); $streamLogs = \str_replace("\\n", "{APPWRITE_LINEBREAK_PLACEHOLDER}", $logs); @@ -755,44 +766,6 @@ class Builds extends Action throw new \Exception('Build size should be less than ' . number_format($buildSizeLimit / 1048576, 2) . ' MBs.'); } - if ($resource->getCollection() === 'sites') { - // TODO: Refactor with structured command in future, using utopia library (CLI) - $listFilesCommand = "cd /usr/local/build && cd " . \escapeshellarg($resource->getAttribute('outputDirectory', './')) . " && find . -name 'node_modules' -prune -o -type f -print"; - $command = $executor->createCommand( - deploymentId: $deployment->getId(), - projectId: $project->getId(), - command: $listFilesCommand, - timeout: 15 - ); - - $files = \explode("\n", $command['output']); // Parse output - $files = \array_filter($files); // Remove empty - $files = \array_map(fn ($file) => \trim($file), $files); // Remove whitepsaces - $files = \array_map(fn ($file) => \str_starts_with($file, './') ? \substr($file, 2) : $file, $files); // Remove beginning ./ - - $detector = new Rendering($files, $resource->getAttribute('framework', '')); - $detector - ->addOption(new SSR()) - ->addOption(new XStatic()); - $detection = $detector->detect(); - - $adapter = $resource->getAttribute('adapter', ''); - - if (empty($adapter)) { - $resource->setAttribute('adapter', $detection->getName()); - $resource->setAttribute('fallbackFile', $detection->getFallbackFile() ?? ''); - $resource = $dbForProject->updateDocument('sites', $resource->getId(), $resource); - - $deployment->setAttribute('adapter', $detection->getName()); - $deployment->setAttribute('fallbackFile', $detection->getFallbackFile() ?? ''); - $deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment); - } elseif ($adapter === 'ssr' && $detection->getName() === 'static') { - throw new \Exception('Adapter mismatch. Detected: ' . $detection->getName() . ' does not match with the set adapter: ' . $adapter); - } - } - - $executor->deleteRuntime($project->getId(), $deployment->getId(), '-build'); - /** Update the build document */ $deployment->setAttribute('buildStartedAt', DateTime::format((new \DateTime())->setTimestamp(floor($response['startTime'])))); $deployment->setAttribute('buildEndedAt', $endTime); @@ -806,6 +779,14 @@ class Builds extends Action $logs .= $log['content']; } + // Separate logs for SSR detection + $detectionLogs = ''; + $separator = \strpos($logs, '{APPWRITE_DETECTION_SEPARATOR}'); + if ($separator !== false) { + $detectionLogs = \substr($logs, $separator + strlen('{APPWRITE_DETECTION_SEPARATOR}')); + $logs = \substr($logs, 0, $separator); + } + if ($resource->getCollection() === 'sites') { $date = \date('H:i:s'); $logs .= "[$date] [appwrite] Screenshot capturing started. \n"; @@ -813,6 +794,31 @@ class Builds extends Action $deployment->setAttribute('buildLogs', $logs); + if ($resource->getCollection() === 'sites' && !empty($detectionLogs)) { + $files = \explode("\n", $detectionLogs); // Parse output + $files = \array_filter($files); // Remove empty + $files = \array_map(fn ($file) => \trim($file), $files); // Remove whitepsaces + $files = \array_map(fn ($file) => \str_starts_with($file, './') ? \substr($file, 2) : $file, $files); // Remove beginning ./ + + $detector = new Rendering($files, $resource->getAttribute('framework', '')); + $detector + ->addOption(new SSR()) + ->addOption(new XStatic()); + $detection = $detector->detect(); + + $adapter = $resource->getAttribute('adapter', ''); + if (empty($adapter)) { + $resource->setAttribute('adapter', $detection->getName()); + $resource->setAttribute('fallbackFile', $detection->getFallbackFile() ?? ''); + $resource = $dbForProject->updateDocument('sites', $resource->getId(), $resource); + + $deployment->setAttribute('adapter', $detection->getName()); + $deployment->setAttribute('fallbackFile', $detection->getFallbackFile() ?? ''); + } elseif ($adapter === 'ssr' && $detection->getName() === 'static') { + throw new \Exception('Adapter mismatch. Detected: ' . $detection->getName() . ' does not match with the set adapter: ' . $adapter); + } + } + $deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment); $queueForRealtime