From 081cf5c6aa07f2ef24ba2c6fd2cc0d590a5ac2d1 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Wed, 6 Nov 2024 23:35:30 +0530 Subject: [PATCH 01/10] Delete rules when site or deployment is deleted --- app/init.php | 1 + src/Appwrite/Platform/Workers/Deletes.php | 115 +++++++++++++++++++++- 2 files changed, 113 insertions(+), 3 deletions(-) diff --git a/app/init.php b/app/init.php index 882d96f57e..055f68d10d 100644 --- a/app/init.php +++ b/app/init.php @@ -179,6 +179,7 @@ const DELETE_TYPE_DATABASES = 'databases'; const DELETE_TYPE_DOCUMENT = 'document'; const DELETE_TYPE_COLLECTIONS = 'collections'; const DELETE_TYPE_PROJECTS = 'projects'; +const DELETE_TYPE_SITES = 'sites'; const DELETE_TYPE_FUNCTIONS = 'functions'; const DELETE_TYPE_DEPLOYMENTS = 'deployments'; const DELETE_TYPE_USERS = 'users'; diff --git a/src/Appwrite/Platform/Workers/Deletes.php b/src/Appwrite/Platform/Workers/Deletes.php index 676120b741..fcb8ef5e12 100644 --- a/src/Appwrite/Platform/Workers/Deletes.php +++ b/src/Appwrite/Platform/Workers/Deletes.php @@ -87,11 +87,14 @@ class Deletes extends Action case DELETE_TYPE_PROJECTS: $this->deleteProject($dbForConsole, $getProjectDB, $deviceForFiles, $deviceForSites, $deviceForFunctions, $deviceForBuilds, $deviceForCache, $document); break; + case DELETE_TYPE_SITES: + $this->deleteSite($dbForConsole, $getProjectDB, $deviceForSites, $deviceForFunctions, $deviceForBuilds, $document, $project); + break; case DELETE_TYPE_FUNCTIONS: $this->deleteFunction($dbForConsole, $getProjectDB, $deviceForFunctions, $deviceForBuilds, $document, $project); break; case DELETE_TYPE_DEPLOYMENTS: - $this->deleteDeployment($getProjectDB, $deviceForFunctions, $deviceForBuilds, $document, $project); + $this->deleteDeployment($dbForConsole, $getProjectDB, $deviceForFunctions, $deviceForBuilds, $document, $project); break; case DELETE_TYPE_USERS: $this->deleteUser($getProjectDB, $document, $project); @@ -732,6 +735,100 @@ class Deletes extends Action } } + /** + * @param callable $getProjectDB + * @param Device $deviceForSites + * @param Device $deviceForFunctions + * @param Device $deviceForBuilds + * @param Document $document function document + * @param Document $project + * @return void + * @throws Exception + */ + private function deleteSite(Database $dbForConsole, callable $getProjectDB, Device $deviceForSites, Device $deviceForFunctions, Device $deviceForBuilds, Document $document, Document $project): void + { + $dbForProject = $getProjectDB($project); + $siteId = $document->getId(); + $siteInternalId = $document->getInternalId(); + + /** + * Delete rules for site + */ + Console::info("Deleting rules for site " . $siteId); + $this->deleteByGroup('rules', [ + Query::equal('resourceType', ['site']), + Query::equal('resourceInternalId', [$siteInternalId]), + Query::equal('projectInternalId', [$project->getInternalId()]) + ], $dbForConsole, function (Document $document) use ($dbForConsole) { + $this->deleteRule($dbForConsole, $document); + }); + + /** + * Delete Variables + */ + Console::info("Deleting variables for site " . $siteId); + $this->deleteByGroup('variables', [ + Query::equal('resourceType', ['site']), + Query::equal('resourceInternalId', [$siteInternalId]) + ], $dbForProject); + + /** + * Delete Deployments + */ + Console::info("Deleting deployments for site " . $siteId); + $deploymentInternalIds = []; + $this->deleteByGroup('deployments', [ + Query::equal('resourceInternalId', [$siteInternalId]) + ], $dbForProject, function (Document $document) use ($deviceForFunctions, &$deploymentInternalIds) { + $deploymentInternalIds[] = $document->getInternalId(); + $this->deleteDeploymentFiles($deviceForFunctions, $document); + }); + + /** + * Delete rules for all deployments of the site + */ + //TODO: If functions also have previews in the future, change the logic here to use unique identifier for sites and functions + foreach ($deploymentInternalIds as $deploymentInternalId) { + Console::info("Deleting rules for site " . $siteId . "'s deployment " . $deploymentInternalId); + $this->deleteByGroup('rules', [ + Query::equal('resourceType', ['deployment']), + Query::equal('resourceInternalId', [$deploymentInternalId]), + Query::equal('projectInternalId', [$project->getInternalId()]) + ], $dbForConsole, function (Document $document) use ($dbForConsole) { + $this->deleteRule($dbForConsole, $document); + }); + } + + /** + * Delete builds + */ + Console::info("Deleting builds for site " . $siteId); + foreach ($deploymentInternalIds as $deploymentInternalId) { + $this->deleteByGroup('builds', [ + Query::equal('deploymentInternalId', [$deploymentInternalId]) + ], $dbForProject, function (Document $document) use ($deviceForBuilds) { + $this->deleteBuildFiles($deviceForBuilds, $document); + }); + } + + /** + * Delete VCS Repositories and VCS Comments + */ + Console::info("Deleting VCS repositories and comments linked to site " . $siteId); + $this->deleteByGroup('repositories', [ + Query::equal('projectInternalId', [$project->getInternalId()]), + Query::equal('resourceInternalId', [$siteInternalId]), + Query::equal('resourceType', ['site']), + ], $dbForConsole, function (Document $document) use ($dbForConsole) { + $providerRepositoryId = $document->getAttribute('providerRepositoryId', ''); + $projectInternalId = $document->getAttribute('projectInternalId', ''); + $this->deleteByGroup('vcsComments', [ + Query::equal('providerRepositoryId', [$providerRepositoryId]), + Query::equal('projectInternalId', [$projectInternalId]), + ], $dbForConsole); + }); + } + /** * @param callable $getProjectDB * @param Device $deviceForFunctions @@ -898,7 +995,7 @@ class Deletes extends Action * @return void * @throws Exception */ - private function deleteDeployment(callable $getProjectDB, Device $deviceForFunctions, Device $deviceForBuilds, Document $document, Document $project): void + private function deleteDeployment(Database $dbForConsole, callable $getProjectDB, Device $deviceForFunctions, Device $deviceForBuilds, Document $document, Document $project): void { $projectId = $project->getId(); $dbForProject = $getProjectDB($project); @@ -908,7 +1005,7 @@ class Deletes extends Action /** * Delete deployment files */ - $this->deleteDeploymentFiles($deviceForFunctions, $document); + $this->deleteDeploymentFiles($deviceForFunctions, $document); //TODO: For sites, this should be deviceForSites /** * Delete builds @@ -921,6 +1018,18 @@ class Deletes extends Action $this->deleteBuildFiles($deviceForBuilds, $document); }); + /** + * Delete rules associated with the deployment + */ + Console::info("Deleting rules for deployment " . $deploymentId); + $this->deleteByGroup('rules', [ + Query::equal('resourceType', ['deployment']), + Query::equal('resourceInternalId', [$deploymentInternalId]), + Query::equal('projectInternalId', [$project->getInternalId()]) + ], $dbForConsole, function (Document $document) use ($dbForConsole) { + $this->deleteRule($dbForConsole, $document); + }); + /** * Request executor to delete all deployment containers */ From a031b54feb2e179a9e783acf7bfb55987d8e4324 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Thu, 7 Nov 2024 00:04:26 +0530 Subject: [PATCH 02/10] Add sitesBase test file --- tests/e2e/Services/Sites/SitesBase.php | 178 +++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 tests/e2e/Services/Sites/SitesBase.php diff --git a/tests/e2e/Services/Sites/SitesBase.php b/tests/e2e/Services/Sites/SitesBase.php new file mode 100644 index 0000000000..8b1444ea1a --- /dev/null +++ b/tests/e2e/Services/Sites/SitesBase.php @@ -0,0 +1,178 @@ +client->call(Client::METHOD_POST, '/sites', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]), $params); + + $this->assertEquals($site['headers']['status-code'], 201, 'Setup site failed with status code: ' . $site['headers']['status-code'] . ' and response: ' . json_encode($site['body'], JSON_PRETTY_PRINT)); + + $siteId = $site['body']['$id']; + + return $siteId; + } + + protected function setupDeployment(string $siteId, mixed $params): string + { + $deployment = $this->client->call(Client::METHOD_POST, '/sites/' . $siteId . '/deployments', array_merge([ + 'content-type' => 'multipart/form-data', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ]), $params); + $this->assertEquals($deployment['headers']['status-code'], 202, 'Setup deployment failed with status code: ' . $deployment['headers']['status-code'] . ' and response: ' . json_encode($deployment['body'], JSON_PRETTY_PRINT)); + $deploymentId = $deployment['body']['$id'] ?? ''; + + $this->assertEventually(function () use ($siteId, $deploymentId) { + $deployment = $this->client->call(Client::METHOD_GET, '/sites/' . $siteId . '/deployments/' . $deploymentId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ])); + $this->assertEquals('ready', $deployment['body']['status'], 'Deployment status is not ready, deployment: ' . json_encode($deployment['body'], JSON_PRETTY_PRINT)); + }, 50000, 500); + + return $deploymentId; + } + + protected function cleanupSite(string $siteId): void + { + $site = $this->client->call(Client::METHOD_DELETE, '/sites/' . $siteId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ])); + + $this->assertEquals($site['headers']['status-code'], 204); + } + + protected function createSite(mixed $params): mixed + { + $site = $this->client->call(Client::METHOD_POST, '/sites', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), $params); + + return $site; + } + + protected function createVariable(string $siteId, mixed $params): mixed + { + $variable = $this->client->call(Client::METHOD_POST, '/sites/' . $siteId . '/variables', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), $params); + + return $variable; + } + + protected function getSite(string $siteId): mixed + { + $site = $this->client->call(Client::METHOD_GET, '/sites/' . $siteId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + return $site; + } + + protected function getDeployment(string $siteId, string $deploymentId): mixed + { + $deployment = $this->client->call(Client::METHOD_GET, '/sites/' . $siteId . '/deployments/' . $deploymentId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + return $deployment; + } + + protected function listSites(mixed $params = []): mixed + { + $sites = $this->client->call(Client::METHOD_GET, '/sites', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), $params); + + return $sites; + } + + protected function listDeployments(string $siteId, $params = []): mixed + { + $deployments = $this->client->call(Client::METHOD_GET, '/sites/' . $siteId . '/deployments', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), $params); + + return $deployments; + } + + protected function packageSite(string $site): CURLFile + { + $folderPath = realpath(__DIR__ . '/../../../resources/sites') . "/$site"; + $tarPath = "$folderPath/code.tar.gz"; + + Console::execute("cd $folderPath && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr); + + if (filesize($tarPath) > 1024 * 1024 * 5) { + throw new \Exception('Code package is too large. Use the chunked upload method instead.'); + } + + return new CURLFile($tarPath, 'application/x-gzip', \basename($tarPath)); + } + + protected function createDeployment(string $siteId, mixed $params = []): mixed + { + $deployment = $this->client->call(Client::METHOD_POST, '/sites/' . $siteId . '/deployments', array_merge([ + 'content-type' => 'multipart/form-data', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), $params); + + return $deployment; + } + + protected function getSiteUsage(string $siteId, mixed $params): mixed + { + $usage = $this->client->call(Client::METHOD_GET, '/sites/' . $siteId . '/usage', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), $params); + + return $usage; + } + + protected function getTemplate(string $templateId) + { + $template = $this->client->call(Client::METHOD_GET, '/sites/templates/' . $templateId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + return $template; + } + + protected function deleteSite(string $siteId): mixed + { + $site = $this->client->call(Client::METHOD_DELETE, '/sites/' . $siteId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + return $site; + } +} From b88cd8e5444a4f29c791e069d5ba767ea03e0556 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Thu, 7 Nov 2024 21:55:41 +0530 Subject: [PATCH 03/10] Add subdomain param in functions and tests --- app/config/services.php | 13 ++ .../Http/Functions/CreateFunction.php | 28 +++- tests/e2e/Scopes/ProjectCustom.php | 2 + .../Functions/FunctionsCustomServerTest.php | 22 +++ .../Services/Sites/SitesCustomServerTest.php | 155 ++++++++++++++++++ 5 files changed, 214 insertions(+), 6 deletions(-) create mode 100644 tests/e2e/Services/Sites/SitesCustomServerTest.php diff --git a/app/config/services.php b/app/config/services.php index c4fb98c59a..e8789fcbec 100644 --- a/app/config/services.php +++ b/app/config/services.php @@ -173,6 +173,19 @@ return [ 'optional' => false, 'icon' => '', ], + 'sites' => [ + 'key' => 'sites', + 'name' => 'Sites', + 'subtitle' => 'The Sites Service allows you view, create and manage your Cloud Sites.', + 'description' => '/docs/services/sites.md', + 'controller' => 'api/sites.php', + 'sdk' => true, + 'docs' => true, + 'docsUrl' => 'https://appwrite.io/docs/sites', + 'tests' => false, + 'optional' => true, + 'icon' => '', // TODO: Update icon later + ], 'functions' => [ 'key' => 'functions', 'name' => 'Functions', diff --git a/src/Appwrite/Platform/Modules/Functions/Http/Functions/CreateFunction.php b/src/Appwrite/Platform/Modules/Functions/Http/Functions/CreateFunction.php index 4074eca1c0..14da817a3f 100644 --- a/src/Appwrite/Platform/Modules/Functions/Http/Functions/CreateFunction.php +++ b/src/Appwrite/Platform/Modules/Functions/Http/Functions/CreateFunction.php @@ -21,6 +21,7 @@ use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; +use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Roles; use Utopia\Platform\Action; @@ -88,6 +89,7 @@ class CreateFunction extends Base App::getEnv('_APP_COMPUTE_CPUS', APP_COMPUTE_CPUS_DEFAULT), App::getEnv('_APP_COMPUTE_MEMORY', APP_COMPUTE_MEMORY_DEFAULT) ), 'Runtime specification for the function and builds.', true, ['plan']) + ->param('subdomain', '', new CustomId(), 'Unique custom sub-domain. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.', true) ->inject('request') ->inject('response') ->inject('dbForProject') @@ -100,8 +102,27 @@ class CreateFunction extends Base ->callback([$this, 'action']); } - public function action(string $functionId, string $name, string $runtime, array $execute, array $events, string $schedule, int $timeout, bool $enabled, bool $logging, string $entrypoint, string $commands, array $scopes, string $installationId, string $providerRepositoryId, string $providerBranch, bool $providerSilentMode, string $providerRootDirectory, string $templateRepository, string $templateOwner, string $templateRootDirectory, string $templateVersion, string $specification, Request $request, Response $response, Database $dbForProject, Document $project, Document $user, Event $queueForEvents, Build $queueForBuilds, Database $dbForConsole, GitHub $github) + public function action(string $functionId, string $name, string $runtime, array $execute, array $events, string $schedule, int $timeout, bool $enabled, bool $logging, string $entrypoint, string $commands, array $scopes, string $installationId, string $providerRepositoryId, string $providerBranch, bool $providerSilentMode, string $providerRootDirectory, string $templateRepository, string $templateOwner, string $templateRootDirectory, string $templateVersion, string $specification, string $subdomain, Request $request, Response $response, Database $dbForProject, Document $project, Document $user, Event $queueForEvents, Build $queueForBuilds, Database $dbForConsole, GitHub $github) { + $functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', ''); + $ruleId = ''; + $routeSubdomain = ''; + $domain = ''; + + if (!empty($functionsDomain)) { + $ruleId = ID::unique(); + $routeSubdomain = $subdomain ?: ID::unique(); + $domain = "{$routeSubdomain}.{$functionsDomain}"; + + $subdomain = Authorization::skip(fn () => $dbForConsole->findOne('rules', [ + Query::equal('domain', [$domain]) + ])); + + if (!empty($subdomain)) { + throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Subdomain already exists. Please choose a different subdomain.'); + } + } + $functionId = ($functionId == 'unique()') ? ID::unique() : $functionId; $allowList = \array_filter(\explode(',', System::getEnv('_APP_FUNCTIONS_RUNTIMES', ''))); @@ -241,12 +262,7 @@ class CreateFunction extends Base ->setTemplate($template); } - $functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', ''); if (!empty($functionsDomain)) { - $ruleId = ID::unique(); - $routeSubdomain = ID::unique(); - $domain = "{$routeSubdomain}.{$functionsDomain}"; - $rule = Authorization::skip( fn () => $dbForConsole->createDocument('rules', new Document([ '$id' => $ruleId, diff --git a/tests/e2e/Scopes/ProjectCustom.php b/tests/e2e/Scopes/ProjectCustom.php index ad2c93790c..69bf680f5e 100644 --- a/tests/e2e/Scopes/ProjectCustom.php +++ b/tests/e2e/Scopes/ProjectCustom.php @@ -74,6 +74,8 @@ trait ProjectCustom 'files.write', 'buckets.read', 'buckets.write', + 'sites.read', + 'sites.write', 'functions.read', 'functions.write', 'execution.read', diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 41b890caf6..f7a856a76f 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -36,6 +36,7 @@ class FunctionsCustomServerTest extends Scope 'buckets.*.delete', ], 'timeout' => 10, + 'subdomain' => 'test' ]); $functionId = $functionId = $function['body']['$id'] ?? ''; @@ -1984,4 +1985,25 @@ class FunctionsCustomServerTest extends Scope $this->cleanupFunction($functionId); } + + /** + * @depends testCreateFunction + */ + public function testUniqueSubdomain(array $data): void + { + $function = $this->createFunction([ + 'functionId' => ID::unique(), + 'name' => 'Test', + 'runtime' => 'php-8.0', + 'entrypoint' => 'index.php', + 'events' => [ + 'buckets.*.create', + 'buckets.*.delete', + ], + 'timeout' => 10, + 'subdomain' => 'test' + ]); + + $this->assertEquals(400, $function['headers']['status-code']); + } } diff --git a/tests/e2e/Services/Sites/SitesCustomServerTest.php b/tests/e2e/Services/Sites/SitesCustomServerTest.php new file mode 100644 index 0000000000..25ebfc9283 --- /dev/null +++ b/tests/e2e/Services/Sites/SitesCustomServerTest.php @@ -0,0 +1,155 @@ +createSite([ + 'siteId' => ID::unique(), + 'name' => 'Test', + 'framework' => 'sveltekit', + 'installCommand' => 'npm install --force', + 'buildCommand' => 'npm run build', + 'outputDirectory' => './build', + 'buildRuntime' => 'node-22', + 'serveRuntime' => 'static-1', + 'subdomain' => 'test' + ]); + + $siteId = $site['body']['$id'] ?? ''; + + $dateValidator = new DatetimeValidator(); + $this->assertEquals(201, $site['headers']['status-code']); + $this->assertNotEmpty($site['body']['$id']); + $this->assertEquals('Test', $site['body']['name']); + $this->assertEquals('sveltekit', $site['body']['framework']); + $this->assertEquals(true, $dateValidator->isValid($site['body']['$createdAt'])); + $this->assertEquals(true, $dateValidator->isValid($site['body']['$updatedAt'])); + $this->assertEquals('npm install --force', $site['body']['installCommand']); + $this->assertEquals('npm run build', $site['body']['buildCommand']); + $this->assertEquals('./build', $site['body']['outputDirectory']); + $this->assertEquals('node-22', $site['body']['buildRuntime']); + $this->assertEquals('static-1', $site['body']['serveRuntime']); + + $variable = $this->createVariable($siteId, [ + 'key' => 'siteKey1', + 'value' => 'siteValue1', + ]); + $variable2 = $this->createVariable($siteId, [ + 'key' => 'siteKey2', + 'value' => 'siteValue2', + ]); + $variable3 = $this->createVariable($siteId, [ + 'key' => 'siteKey3', + 'value' => 'siteValue3', + ]); + + $this->assertEquals(201, $variable['headers']['status-code']); + $this->assertEquals(201, $variable2['headers']['status-code']); + $this->assertEquals(201, $variable3['headers']['status-code']); + + return [ + 'siteId' => $siteId, + ]; + } + + /** + * @depends testCreateSite + */ + public function testGetSite(array $data): array + { + /** + * Test for SUCCESS + */ + $site = $this->getSite($data['siteId']); + + $this->assertEquals($site['headers']['status-code'], 200); + $this->assertEquals($site['body']['name'], 'Test'); + + /** + * Test for FAILURE + */ + $site = $this->getSite('x'); + + $this->assertEquals($site['headers']['status-code'], 404); + + return $data; + } + + /** + * @depends testGetSite + */ + public function testDeleteSite(array $data): array + { + /** + * Test for SUCCESS + */ + $site = $this->deleteSite($data['siteId']); + + $this->assertEquals(204, $site['headers']['status-code']); + $this->assertEmpty($site['body']); + + $site = $this->getSite($data['siteId']); + + $this->assertEquals(404, $site['headers']['status-code']); + + return $data; + } + + /** + * @depends testGetSite + */ + public function testUniqueSubdomain(array $data): void + { + /** + * Test for SUCCESS + */ + $site = $this->createSite([ + 'siteId' => ID::unique(), + 'name' => 'Test', + 'framework' => 'sveltekit', + 'installCommand' => 'npm install --force', + 'buildCommand' => 'npm run build', + 'outputDirectory' => './build', + 'buildRuntime' => 'node-22', + 'serveRuntime' => 'static-1', + 'subdomain' => 'test' + ]); + + $this->assertEquals(201, $site['headers']['status-code']); + + /** + * Test for FAILURE + */ + $site = $this->createSite([ + 'siteId' => ID::unique(), + 'name' => 'Test2', + 'framework' => 'sveltekit', + 'installCommand' => 'npm install --force', + 'buildCommand' => 'npm run build', + 'outputDirectory' => './build', + 'buildRuntime' => 'node-22', + 'serveRuntime' => 'static-1', + 'subdomain' => 'test' + ]); + + $this->assertEquals(400, $site['headers']['status-code']); + + return; + } +} From ba74ffd4bf95d348f12f105f69f4bbdc5f4b700f Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Mon, 11 Nov 2024 11:48:26 +0530 Subject: [PATCH 04/10] Address PR comments --- app/config/services.php | 2 +- .../Functions/FunctionsCustomServerTest.php | 39 +++++++++---------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/app/config/services.php b/app/config/services.php index e8789fcbec..d3e221e2fa 100644 --- a/app/config/services.php +++ b/app/config/services.php @@ -176,7 +176,7 @@ return [ 'sites' => [ 'key' => 'sites', 'name' => 'Sites', - 'subtitle' => 'The Sites Service allows you view, create and manage your Cloud Sites.', + 'subtitle' => 'The Sites Service allows you view, create and manage your web applications.', 'description' => '/docs/services/sites.md', 'controller' => 'api/sites.php', 'sdk' => true, diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index f7a856a76f..67f2f17c86 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -73,6 +73,24 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(201, $variable2['headers']['status-code']); $this->assertEquals(201, $variable3['headers']['status-code']); + /** + * Test for FAILURE + */ + $function2 = $this->createFunction([ + 'functionId' => ID::unique(), + 'name' => 'Test', + 'runtime' => 'php-8.0', + 'entrypoint' => 'index.php', + 'events' => [ + 'buckets.*.create', + 'buckets.*.delete', + ], + 'timeout' => 10, + 'subdomain' => 'test' + ]); + + $this->assertEquals(400, $function2['headers']['status-code']); + return [ 'functionId' => $functionId, ]; @@ -1985,25 +2003,4 @@ class FunctionsCustomServerTest extends Scope $this->cleanupFunction($functionId); } - - /** - * @depends testCreateFunction - */ - public function testUniqueSubdomain(array $data): void - { - $function = $this->createFunction([ - 'functionId' => ID::unique(), - 'name' => 'Test', - 'runtime' => 'php-8.0', - 'entrypoint' => 'index.php', - 'events' => [ - 'buckets.*.create', - 'buckets.*.delete', - ], - 'timeout' => 10, - 'subdomain' => 'test' - ]); - - $this->assertEquals(400, $function['headers']['status-code']); - } } From 9c37c3a740146791637e65f88b5cf887bd3cbfd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Wed, 8 Jan 2025 16:14:33 +0000 Subject: [PATCH 05/10] Fix basic configs --- .env | 4 +- app/cli.php | 2 +- app/config/frameworks.php | 12 +- app/config/runtimes.php | 2 +- app/config/site-templates.php | 10 +- composer.json | 2 +- composer.lock | 273 +++++++++++++++++----------------- docker-compose.yml | 4 +- 8 files changed, 157 insertions(+), 152 deletions(-) diff --git a/.env b/.env index 2d2e335186..fc64dc88a6 100644 --- a/.env +++ b/.env @@ -79,8 +79,8 @@ _APP_COMPUTE_RUNTIMES_NETWORK=runtimes _APP_EXECUTOR_SECRET=your-secret-key _APP_EXECUTOR_HOST=http://exc1/v1 _APP_FUNCTIONS_RUNTIMES=php-8.0,node-18.0,python-3.9,ruby-3.1 -_APP_SITES_RUNTIMES=static-1,node-22,flutter-3.24 -_APP_SITES_FRAMEWORKS=sveltekit,nextjs,nuxt,astro,remix,static,flutter # TODO: Angular +_APP_SITES_RUNTIMES=static-1,ssr-22,flutter-3.24 +_APP_SITES_FRAMEWORKS=sveltekit,nextjs,nuxt,astro,remix,static,flutter,other # TODO: Angular _APP_MAINTENANCE_INTERVAL=86400 _APP_MAINTENANCE_DELAY= _APP_MAINTENANCE_RETENTION_CACHE=2592000 diff --git a/app/cli.php b/app/cli.php index 23502ec402..4aad804f77 100644 --- a/app/cli.php +++ b/app/cli.php @@ -24,7 +24,7 @@ use Utopia\Registry\Registry; use Utopia\System\System; // overwriting runtimes to be architectur agnostic for CLI -Config::setParam('runtimes', (new Runtimes('v4'))->getAll(supported: false)); +Config::setParam('runtimes', (new Runtimes('v4rc'))->getAll(supported: false)); // require controllers after overwriting runtimes require_once __DIR__ . '/controllers/general.php'; diff --git a/app/config/frameworks.php b/app/config/frameworks.php index 35c9c9909c..ff54c0aacb 100644 --- a/app/config/frameworks.php +++ b/app/config/frameworks.php @@ -21,7 +21,7 @@ return [ 'nextjs' => [ 'key' => 'nextjs', 'name' => 'Next.js', - 'buildRuntime' => 'node-22', + 'buildRuntime' => 'ssr-22', 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), 'adapters' => [ 'ssr' => [ @@ -45,7 +45,7 @@ return [ 'nuxt' => [ 'key' => 'nuxt', 'name' => 'Nuxt', - 'buildRuntime' => 'node-22', + 'buildRuntime' => 'ssr-22', 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), 'adapters' => [ 'ssr' => [ @@ -69,7 +69,7 @@ return [ 'sveltekit' => [ 'key' => 'sveltekit', 'name' => 'SvelteKit', - 'buildRuntime' => 'node-22', + 'buildRuntime' => 'ssr-22', 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), 'adapters' => [ 'ssr' => [ @@ -93,7 +93,7 @@ return [ 'astro' => [ 'key' => 'astro', 'name' => 'Astro', - 'buildRuntime' => 'node-22', + 'buildRuntime' => 'ssr-22', 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), 'adapters' => [ 'ssr' => [ @@ -117,7 +117,7 @@ return [ 'remix' => [ 'key' => 'remix', 'name' => 'Remix', - 'buildRuntime' => 'node-22', + 'buildRuntime' => 'ssr-22', 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), 'adapters' => [ 'ssr' => [ @@ -157,7 +157,7 @@ return [ 'other' => [ 'key' => 'other', 'name' => 'Other', - 'buildRuntime' => 'node-22', + 'buildRuntime' => 'ssr-22', 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), 'adapters' => [ 'static' => [ diff --git a/app/config/runtimes.php b/app/config/runtimes.php index 980613ebec..4260655342 100644 --- a/app/config/runtimes.php +++ b/app/config/runtimes.php @@ -6,4 +6,4 @@ use Appwrite\Runtimes\Runtimes; -return (new Runtimes('v4'))->getAll(); +return (new Runtimes('v4rc'))->getAll(); diff --git a/app/config/site-templates.php b/app/config/site-templates.php index 79bccc0e2c..c65ca8f577 100644 --- a/app/config/site-templates.php +++ b/app/config/site-templates.php @@ -13,7 +13,7 @@ const TEMPLATE_FRAMEWORKS = [ 'installCommand' => 'npm install', 'buildCommand' => 'npm run build', 'outputDirectory' => './build', - 'buildRuntime' => 'node-22', + 'buildRuntime' => 'ssr-22', 'adapter' => 'ssr', 'fallbackFile' => null, ], @@ -23,7 +23,7 @@ const TEMPLATE_FRAMEWORKS = [ 'installCommand' => 'npm install', 'buildCommand' => 'npm run build', 'outputDirectory' => './.next', - 'buildRuntime' => 'node-22', + 'buildRuntime' => 'ssr-22', 'adapter' => 'ssr', 'fallbackFile' => null, ], @@ -33,7 +33,7 @@ const TEMPLATE_FRAMEWORKS = [ 'installCommand' => 'npm install', 'buildCommand' => 'npm run build', 'outputDirectory' => './.output', - 'buildRuntime' => 'node-22', + 'buildRuntime' => 'ssr-22', 'adapter' => 'ssr', 'fallbackFile' => null, ], @@ -43,7 +43,7 @@ const TEMPLATE_FRAMEWORKS = [ 'installCommand' => 'npm install', 'buildCommand' => 'npm run build', 'outputDirectory' => './build', - 'buildRuntime' => 'node-22', + 'buildRuntime' => 'ssr-22', 'adapter' => 'ssr', 'fallbackFile' => null, ], @@ -53,7 +53,7 @@ const TEMPLATE_FRAMEWORKS = [ 'installCommand' => 'npm install', 'buildCommand' => 'npm run build', 'outputDirectory' => './dist', - 'buildRuntime' => 'node-22', + 'buildRuntime' => 'ssr-22', 'adapter' => 'ssr', 'fallbackFile' => null, ], diff --git a/composer.json b/composer.json index f04239dc1c..54440debe5 100644 --- a/composer.json +++ b/composer.json @@ -43,7 +43,7 @@ "ext-openssl": "*", "ext-zlib": "*", "ext-sockets": "*", - "appwrite/php-runtimes": "0.16.*", + "appwrite/php-runtimes": "dev-feat-add-ssr-runtime as 0.16.99", "appwrite/php-clamav": "2.0.*", "utopia-php/abuse": "0.43.0", "utopia-php/analytics": "0.10.*", diff --git a/composer.lock b/composer.lock index 123f6bfbe3..0cf7746c41 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "026d47ead39933ab29b2ea7046bfec4f", + "content-hash": "2a57d56106703cb729370214435feb98", "packages": [ { "name": "adhocore/jwt", @@ -157,16 +157,16 @@ }, { "name": "appwrite/php-runtimes", - "version": "0.16.5", + "version": "dev-feat-add-ssr-runtime", "source": { "type": "git", "url": "https://github.com/appwrite/runtimes.git", - "reference": "1e430646fdf847a7caf3c611dcf3d6d5a28c3fd9" + "reference": "a021a2b09b045375979f8e7bc2e7aa520fc94847" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/runtimes/zipball/1e430646fdf847a7caf3c611dcf3d6d5a28c3fd9", - "reference": "1e430646fdf847a7caf3c611dcf3d6d5a28c3fd9", + "url": "https://api.github.com/repos/appwrite/runtimes/zipball/a021a2b09b045375979f8e7bc2e7aa520fc94847", + "reference": "a021a2b09b045375979f8e7bc2e7aa520fc94847", "shasum": "" }, "require": { @@ -206,9 +206,9 @@ ], "support": { "issues": "https://github.com/appwrite/runtimes/issues", - "source": "https://github.com/appwrite/runtimes/tree/0.16.5" + "source": "https://github.com/appwrite/runtimes/tree/feat-add-ssr-runtime" }, - "time": "2024-11-25T15:17:06+00:00" + "time": "2025-01-07T12:14:14+00:00" }, { "name": "beberlei/assert", @@ -709,16 +709,16 @@ }, { "name": "google/protobuf", - "version": "v4.29.0", + "version": "v4.29.2", "source": { "type": "git", "url": "https://github.com/protocolbuffers/protobuf-php.git", - "reference": "0ef6b2eb74b782f3f9023276c324d22e440f7587" + "reference": "79aa5014efeeec3d137df5cdb0ae2fc163953945" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/0ef6b2eb74b782f3f9023276c324d22e440f7587", - "reference": "0ef6b2eb74b782f3f9023276c324d22e440f7587", + "url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/79aa5014efeeec3d137df5cdb0ae2fc163953945", + "reference": "79aa5014efeeec3d137df5cdb0ae2fc163953945", "shasum": "" }, "require": { @@ -747,9 +747,9 @@ "proto" ], "support": { - "source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.29.0" + "source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.29.2" }, - "time": "2024-11-27T18:37:40+00:00" + "time": "2024-12-18T14:11:12+00:00" }, { "name": "jean85/pretty-package-versions", @@ -1237,16 +1237,16 @@ }, { "name": "open-telemetry/api", - "version": "1.1.1", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/opentelemetry-php/api.git", - "reference": "542064815d38a6df55af7957cd6f1d7d967c99c6" + "reference": "04c85a1e41a3d59fa9bdc801a5de1df6624b95ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opentelemetry-php/api/zipball/542064815d38a6df55af7957cd6f1d7d967c99c6", - "reference": "542064815d38a6df55af7957cd6f1d7d967c99c6", + "url": "https://api.github.com/repos/opentelemetry-php/api/zipball/04c85a1e41a3d59fa9bdc801a5de1df6624b95ed", + "reference": "04c85a1e41a3d59fa9bdc801a5de1df6624b95ed", "shasum": "" }, "require": { @@ -1260,13 +1260,13 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.1.x-dev" - }, "spi": { "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\HookManagerInterface": [ "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\ExtensionHookManager" ] + }, + "branch-alias": { + "dev-main": "1.1.x-dev" } }, "autoload": { @@ -1303,7 +1303,7 @@ "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", "source": "https://github.com/open-telemetry/opentelemetry-php" }, - "time": "2024-10-15T22:42:37+00:00" + "time": "2024-11-16T04:32:30+00:00" }, { "name": "open-telemetry/context", @@ -1530,13 +1530,13 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.0.x-dev" - }, "spi": { "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\HookManagerInterface": [ "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\ExtensionHookManager" ] + }, + "branch-alias": { + "dev-main": "1.0.x-dev" } }, "autoload": { @@ -2403,12 +2403,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -2453,23 +2453,23 @@ }, { "name": "symfony/http-client", - "version": "v7.2.0", + "version": "v7.2.2", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "955e43336aff03df1e8a8e17daefabb0127a313b" + "reference": "339ba21476eb184290361542f732ad12c97591ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/955e43336aff03df1e8a8e17daefabb0127a313b", - "reference": "955e43336aff03df1e8a8e17daefabb0127a313b", + "url": "https://api.github.com/repos/symfony/http-client/zipball/339ba21476eb184290361542f732ad12c97591ec", + "reference": "339ba21476eb184290361542f732ad12c97591ec", "shasum": "" }, "require": { "php": ">=8.2", "psr/log": "^1|^2|^3", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-client-contracts": "~3.4.3|^3.5.1", + "symfony/http-client-contracts": "~3.4.4|^3.5.2", "symfony/service-contracts": "^2.5|^3" }, "conflict": { @@ -2528,7 +2528,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.2.0" + "source": "https://github.com/symfony/http-client/tree/v7.2.2" }, "funding": [ { @@ -2544,20 +2544,20 @@ "type": "tidelift" } ], - "time": "2024-11-29T08:22:02+00:00" + "time": "2024-12-30T18:35:15+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v3.5.1", + "version": "v3.5.2", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "c2f3ad828596624ca39ea40f83617ef51ca8bbf9" + "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/c2f3ad828596624ca39ea40f83617ef51ca8bbf9", - "reference": "c2f3ad828596624ca39ea40f83617ef51ca8bbf9", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ee8d807ab20fcb51267fdace50fbe3494c31e645", + "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645", "shasum": "" }, "require": { @@ -2565,12 +2565,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -2606,7 +2606,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.1" + "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.2" }, "funding": [ { @@ -2622,7 +2622,7 @@ "type": "tidelift" } ], - "time": "2024-11-25T12:02:18+00:00" + "time": "2024-12-07T08:49:48+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -2650,8 +2650,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -2724,8 +2724,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -2804,8 +2804,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -2884,12 +2884,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -2970,10 +2970,10 @@ }, "type": "composer-plugin", "extra": { + "class": "Nevay\\SPI\\Composer\\Plugin", "branch-alias": { "dev-main": "0.2.x-dev" }, - "class": "Nevay\\SPI\\Composer\\Plugin", "plugin-optional": true }, "autoload": { @@ -3929,16 +3929,16 @@ }, { "name": "utopia-php/migration", - "version": "0.6.13", + "version": "0.6.14", "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "68d9b0a9477755afcda607e7e8109785cae17a13" + "reference": "59a19f09ded0ccab4c8cca35b1242c01e2b9cfd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/68d9b0a9477755afcda607e7e8109785cae17a13", - "reference": "68d9b0a9477755afcda607e7e8109785cae17a13", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/59a19f09ded0ccab4c8cca35b1242c01e2b9cfd2", + "reference": "59a19f09ded0ccab4c8cca35b1242c01e2b9cfd2", "shasum": "" }, "require": { @@ -3979,9 +3979,9 @@ ], "support": { "issues": "https://github.com/utopia-php/migration/issues", - "source": "https://github.com/utopia-php/migration/tree/0.6.13" + "source": "https://github.com/utopia-php/migration/tree/0.6.14" }, - "time": "2024-11-26T13:57:53+00:00" + "time": "2025-01-08T01:07:25+00:00" }, { "name": "utopia-php/mongo", @@ -4363,16 +4363,16 @@ }, { "name": "utopia-php/storage", - "version": "0.18.7", + "version": "0.18.8", "source": { "type": "git", "url": "https://github.com/utopia-php/storage.git", - "reference": "0d9228faa1c202f9e01483e45a8950485f01a288" + "reference": "84737afa634e6a833fc4f8b0c967553234d3f215" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/0d9228faa1c202f9e01483e45a8950485f01a288", - "reference": "0d9228faa1c202f9e01483e45a8950485f01a288", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/84737afa634e6a833fc4f8b0c967553234d3f215", + "reference": "84737afa634e6a833fc4f8b0c967553234d3f215", "shasum": "" }, "require": { @@ -4412,9 +4412,9 @@ ], "support": { "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.18.7" + "source": "https://github.com/utopia-php/storage/tree/0.18.8" }, - "time": "2024-11-28T11:10:53+00:00" + "time": "2024-12-04T08:30:35+00:00" }, { "name": "utopia-php/swoole", @@ -4575,16 +4575,16 @@ }, { "name": "utopia-php/vcs", - "version": "0.8.5", + "version": "0.8.6", "source": { "type": "git", "url": "https://github.com/utopia-php/vcs.git", - "reference": "7622330628d53844a3873ca873338150756bab82" + "reference": "b10225f54d5670f09f83e82e09de9d820ada6931" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/vcs/zipball/7622330628d53844a3873ca873338150756bab82", - "reference": "7622330628d53844a3873ca873338150756bab82", + "url": "https://api.github.com/repos/utopia-php/vcs/zipball/b10225f54d5670f09f83e82e09de9d820ada6931", + "reference": "b10225f54d5670f09f83e82e09de9d820ada6931", "shasum": "" }, "require": { @@ -4618,9 +4618,9 @@ ], "support": { "issues": "https://github.com/utopia-php/vcs/issues", - "source": "https://github.com/utopia-php/vcs/tree/0.8.5" + "source": "https://github.com/utopia-php/vcs/tree/0.8.6" }, - "time": "2024-11-11T18:33:10+00:00" + "time": "2024-12-10T13:13:23+00:00" }, { "name": "utopia-php/websocket", @@ -4807,16 +4807,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "0.39.25", + "version": "0.39.29", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "5b5323636a8d75a1c4faaae9728098dd6a6a47d1" + "reference": "a9c3f6076ec162588dac7b0a741bc1a2c3d1a2b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/5b5323636a8d75a1c4faaae9728098dd6a6a47d1", - "reference": "5b5323636a8d75a1c4faaae9728098dd6a6a47d1", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/a9c3f6076ec162588dac7b0a741bc1a2c3d1a2b7", + "reference": "a9c3f6076ec162588dac7b0a741bc1a2c3d1a2b7", "shasum": "" }, "require": { @@ -4852,9 +4852,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/0.39.25" + "source": "https://github.com/appwrite/sdk-generator/tree/0.39.29" }, - "time": "2024-11-08T10:16:34+00:00" + "time": "2025-01-07T05:28:35+00:00" }, { "name": "doctrine/annotations", @@ -4934,29 +4934,27 @@ }, { "name": "doctrine/deprecations", - "version": "1.1.3", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" + "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", - "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/31610dbb31faa98e6b5447b62340826f54fbc4e9", + "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9", - "phpstan/phpstan": "1.4.10 || 1.10.15", - "phpstan/phpstan-phpunit": "^1.0", + "doctrine/coding-standard": "^9 || ^12", + "phpstan/phpstan": "1.4.10 || 2.0.3", + "phpstan/phpstan-phpunit": "^1.0 || ^2", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psalm/plugin-phpunit": "0.18.4", - "psr/log": "^1 || ^2 || ^3", - "vimeo/psalm": "4.30.0 || 5.12.0" + "psr/log": "^1 || ^2 || ^3" }, "suggest": { "psr/log": "Allows logging deprecations via PSR-3 logger implementation" @@ -4964,7 +4962,7 @@ "type": "library", "autoload": { "psr-4": { - "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + "Doctrine\\Deprecations\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -4975,9 +4973,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.3" + "source": "https://github.com/doctrine/deprecations/tree/1.1.4" }, - "time": "2024-01-30T19:34:25+00:00" + "time": "2024-12-07T21:18:45+00:00" }, { "name": "doctrine/instantiator", @@ -5128,16 +5126,16 @@ }, { "name": "laravel/pint", - "version": "v1.18.3", + "version": "v1.19.0", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "cef51821608239040ab841ad6e1c6ae502ae3026" + "reference": "8169513746e1bac70c85d6ea1524d9225d4886f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/cef51821608239040ab841ad6e1c6ae502ae3026", - "reference": "cef51821608239040ab841ad6e1c6ae502ae3026", + "url": "https://api.github.com/repos/laravel/pint/zipball/8169513746e1bac70c85d6ea1524d9225d4886f0", + "reference": "8169513746e1bac70c85d6ea1524d9225d4886f0", "shasum": "" }, "require": { @@ -5148,10 +5146,10 @@ "php": "^8.1.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.65.0", - "illuminate/view": "^10.48.24", - "larastan/larastan": "^2.9.11", - "laravel-zero/framework": "^10.4.0", + "friendsofphp/php-cs-fixer": "^3.66.0", + "illuminate/view": "^10.48.25", + "larastan/larastan": "^2.9.12", + "laravel-zero/framework": "^10.48.25", "mockery/mockery": "^1.6.12", "nunomaduro/termwind": "^1.17.0", "pestphp/pest": "^2.36.0" @@ -5190,7 +5188,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-11-26T15:34:00+00:00" + "time": "2024-12-30T16:20:10+00:00" }, { "name": "matthiasmullie/minify", @@ -5378,16 +5376,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.3.1", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" + "reference": "447a020a1f875a434d62f2a401f53b82a396e494" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", - "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", + "reference": "447a020a1f875a434d62f2a401f53b82a396e494", "shasum": "" }, "require": { @@ -5430,9 +5428,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" }, - "time": "2024-10-08T18:51:32+00:00" + "time": "2024-12-30T11:07:19+00:00" }, { "name": "phar-io/manifest", @@ -5809,16 +5807,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.6.0", + "version": "5.6.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "f3558a4c23426d12bffeaab463f8a8d8b681193c" + "reference": "e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/f3558a4c23426d12bffeaab463f8a8d8b681193c", - "reference": "f3558a4c23426d12bffeaab463f8a8d8b681193c", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8", + "reference": "e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8", "shasum": "" }, "require": { @@ -5867,9 +5865,9 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.0" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.1" }, - "time": "2024-11-12T11:25:25+00:00" + "time": "2024-12-07T09:39:29+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -7578,16 +7576,16 @@ }, { "name": "symfony/console", - "version": "v7.2.0", + "version": "v7.2.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "23c8aae6d764e2bae02d2a99f7532a7f6ed619cf" + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/23c8aae6d764e2bae02d2a99f7532a7f6ed619cf", - "reference": "23c8aae6d764e2bae02d2a99f7532a7f6ed619cf", + "url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3", + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3", "shasum": "" }, "require": { @@ -7651,7 +7649,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.2.0" + "source": "https://github.com/symfony/console/tree/v7.2.1" }, "funding": [ { @@ -7667,7 +7665,7 @@ "type": "tidelift" } ], - "time": "2024-11-06T14:24:19+00:00" + "time": "2024-12-11T03:49:26+00:00" }, { "name": "symfony/filesystem", @@ -7737,16 +7735,16 @@ }, { "name": "symfony/finder", - "version": "v7.2.0", + "version": "v7.2.2", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49" + "reference": "87a71856f2f56e4100373e92529eed3171695cfb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/6de263e5868b9a137602dd1e33e4d48bfae99c49", - "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49", + "url": "https://api.github.com/repos/symfony/finder/zipball/87a71856f2f56e4100373e92529eed3171695cfb", + "reference": "87a71856f2f56e4100373e92529eed3171695cfb", "shasum": "" }, "require": { @@ -7781,7 +7779,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.2.0" + "source": "https://github.com/symfony/finder/tree/v7.2.2" }, "funding": [ { @@ -7797,7 +7795,7 @@ "type": "tidelift" } ], - "time": "2024-10-23T06:56:12+00:00" + "time": "2024-12-30T19:00:17+00:00" }, { "name": "symfony/options-resolver", @@ -7892,8 +7890,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -7968,8 +7966,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -8046,8 +8044,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -8124,8 +8122,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -8557,6 +8555,12 @@ } ], "aliases": [ + { + "package": "appwrite/php-runtimes", + "version": "dev-feat-add-ssr-runtime", + "alias": "0.16.99", + "alias_normalized": "0.16.99.0" + }, { "package": "utopia-php/framework", "version": "dev-fix-prevent-duplicate-compression", @@ -8566,6 +8570,7 @@ ], "minimum-stability": "stable", "stability-flags": { + "appwrite/php-runtimes": 20, "utopia-php/framework": 20 }, "prefer-stable": false, diff --git a/docker-compose.yml b/docker-compose.yml index bb7af40946..826b0e0f12 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -893,7 +893,7 @@ services: # It's not possible to share mount file between 2 containers without host mount (copying is too slow) - /tmp:/tmp:rw environment: - - OPR_EXECUTOR_IMAGE_PULL=disabled + - OPR_EXECUTOR_IMAGE_PULL=enabled - OPR_EXECUTOR_INACTIVE_TRESHOLD=$_APP_COMPUTE_INACTIVE_THRESHOLD - OPR_EXECUTOR_MAINTENANCE_INTERVAL=$_APP_COMPUTE_MAINTENANCE_INTERVAL - OPR_EXECUTOR_NETWORK=$_APP_COMPUTE_RUNTIMES_NETWORK @@ -902,7 +902,7 @@ services: - OPR_EXECUTOR_ENV=$_APP_ENV - OPR_EXECUTOR_RUNTIMES=$_APP_FUNCTIONS_RUNTIMES,$_APP_SITES_RUNTIMES - OPR_EXECUTOR_SECRET=$_APP_EXECUTOR_SECRET - - OPR_EXECUTOR_RUNTIME_VERSIONS=v2,v4 + - OPR_EXECUTOR_RUNTIME_VERSIONS=v2,v4,v4rc - OPR_EXECUTOR_LOGGING_CONFIG=$_APP_LOGGING_CONFIG - OPR_EXECUTOR_STORAGE_DEVICE=$_APP_STORAGE_DEVICE - OPR_EXECUTOR_STORAGE_S3_ACCESS_KEY=$_APP_STORAGE_S3_ACCESS_KEY From 8a260ceece3c4f63a09c0c7c91019e8a1194dc41 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Thu, 9 Jan 2025 17:41:45 +0530 Subject: [PATCH 06/10] Remove unrelated changes to site deletion --- .../Http/Functions/CreateFunction.php | 24 +-- .../Functions/FunctionsCustomServerTest.php | 19 -- tests/e2e/Services/Sites/SitesBase.php | 178 ------------------ .../Services/Sites/SitesCustomServerTest.php | 155 --------------- 4 files changed, 2 insertions(+), 374 deletions(-) delete mode 100644 tests/e2e/Services/Sites/SitesBase.php delete mode 100644 tests/e2e/Services/Sites/SitesCustomServerTest.php diff --git a/src/Appwrite/Platform/Modules/Functions/Http/Functions/CreateFunction.php b/src/Appwrite/Platform/Modules/Functions/Http/Functions/CreateFunction.php index b44b615d48..16df486c8c 100644 --- a/src/Appwrite/Platform/Modules/Functions/Http/Functions/CreateFunction.php +++ b/src/Appwrite/Platform/Modules/Functions/Http/Functions/CreateFunction.php @@ -21,7 +21,6 @@ use Utopia\Database\Document; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; -use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Roles; use Utopia\Platform\Action; @@ -90,7 +89,6 @@ class CreateFunction extends Base App::getEnv('_APP_COMPUTE_CPUS', APP_COMPUTE_CPUS_DEFAULT), App::getEnv('_APP_COMPUTE_MEMORY', APP_COMPUTE_MEMORY_DEFAULT) ), 'Runtime specification for the function and builds.', true, ['plan']) - ->param('subdomain', '', new CustomId(), 'Unique custom sub-domain. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.', true) ->inject('request') ->inject('response') ->inject('dbForProject') @@ -103,27 +101,8 @@ class CreateFunction extends Base ->callback([$this, 'action']); } - public function action(string $functionId, string $name, string $runtime, array $execute, array $events, string $schedule, int $timeout, bool $enabled, bool $logging, string $entrypoint, string $commands, array $scopes, string $installationId, string $providerRepositoryId, string $providerBranch, bool $providerSilentMode, string $providerRootDirectory, string $templateRepository, string $templateOwner, string $templateRootDirectory, string $templateVersion, string $specification, string $subdomain, Request $request, Response $response, Database $dbForProject, Document $project, Document $user, Event $queueForEvents, Build $queueForBuilds, Database $dbForConsole, GitHub $github) + public function action(string $functionId, string $name, string $runtime, array $execute, array $events, string $schedule, int $timeout, bool $enabled, bool $logging, string $entrypoint, string $commands, array $scopes, string $installationId, string $providerRepositoryId, string $providerBranch, bool $providerSilentMode, string $providerRootDirectory, string $templateRepository, string $templateOwner, string $templateRootDirectory, string $templateVersion, string $specification, Request $request, Response $response, Database $dbForProject, Document $project, Document $user, Event $queueForEvents, Build $queueForBuilds, Database $dbForConsole, GitHub $github) { - $functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', ''); - $ruleId = ''; - $routeSubdomain = ''; - $domain = ''; - - if (!empty($functionsDomain)) { - $ruleId = ID::unique(); - $routeSubdomain = $subdomain ?: ID::unique(); - $domain = "{$routeSubdomain}.{$functionsDomain}"; - - $subdomain = Authorization::skip(fn () => $dbForConsole->findOne('rules', [ - Query::equal('domain', [$domain]) - ])); - - if (!empty($subdomain)) { - throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Subdomain already exists. Please choose a different subdomain.'); - } - } - $functionId = ($functionId == 'unique()') ? ID::unique() : $functionId; $allowList = \array_filter(\explode(',', System::getEnv('_APP_FUNCTIONS_RUNTIMES', ''))); @@ -263,6 +242,7 @@ class CreateFunction extends Base ->setTemplate($template); } + $functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', ''); if (!empty($functionsDomain)) { $routeSubdomain = ID::unique(); $domain = "{$routeSubdomain}.{$functionsDomain}"; diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 67f2f17c86..41b890caf6 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -36,7 +36,6 @@ class FunctionsCustomServerTest extends Scope 'buckets.*.delete', ], 'timeout' => 10, - 'subdomain' => 'test' ]); $functionId = $functionId = $function['body']['$id'] ?? ''; @@ -73,24 +72,6 @@ class FunctionsCustomServerTest extends Scope $this->assertEquals(201, $variable2['headers']['status-code']); $this->assertEquals(201, $variable3['headers']['status-code']); - /** - * Test for FAILURE - */ - $function2 = $this->createFunction([ - 'functionId' => ID::unique(), - 'name' => 'Test', - 'runtime' => 'php-8.0', - 'entrypoint' => 'index.php', - 'events' => [ - 'buckets.*.create', - 'buckets.*.delete', - ], - 'timeout' => 10, - 'subdomain' => 'test' - ]); - - $this->assertEquals(400, $function2['headers']['status-code']); - return [ 'functionId' => $functionId, ]; diff --git a/tests/e2e/Services/Sites/SitesBase.php b/tests/e2e/Services/Sites/SitesBase.php deleted file mode 100644 index 8b1444ea1a..0000000000 --- a/tests/e2e/Services/Sites/SitesBase.php +++ /dev/null @@ -1,178 +0,0 @@ -client->call(Client::METHOD_POST, '/sites', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]), $params); - - $this->assertEquals($site['headers']['status-code'], 201, 'Setup site failed with status code: ' . $site['headers']['status-code'] . ' and response: ' . json_encode($site['body'], JSON_PRETTY_PRINT)); - - $siteId = $site['body']['$id']; - - return $siteId; - } - - protected function setupDeployment(string $siteId, mixed $params): string - { - $deployment = $this->client->call(Client::METHOD_POST, '/sites/' . $siteId . '/deployments', array_merge([ - 'content-type' => 'multipart/form-data', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ]), $params); - $this->assertEquals($deployment['headers']['status-code'], 202, 'Setup deployment failed with status code: ' . $deployment['headers']['status-code'] . ' and response: ' . json_encode($deployment['body'], JSON_PRETTY_PRINT)); - $deploymentId = $deployment['body']['$id'] ?? ''; - - $this->assertEventually(function () use ($siteId, $deploymentId) { - $deployment = $this->client->call(Client::METHOD_GET, '/sites/' . $siteId . '/deployments/' . $deploymentId, array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ])); - $this->assertEquals('ready', $deployment['body']['status'], 'Deployment status is not ready, deployment: ' . json_encode($deployment['body'], JSON_PRETTY_PRINT)); - }, 50000, 500); - - return $deploymentId; - } - - protected function cleanupSite(string $siteId): void - { - $site = $this->client->call(Client::METHOD_DELETE, '/sites/' . $siteId, array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ])); - - $this->assertEquals($site['headers']['status-code'], 204); - } - - protected function createSite(mixed $params): mixed - { - $site = $this->client->call(Client::METHOD_POST, '/sites', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), $params); - - return $site; - } - - protected function createVariable(string $siteId, mixed $params): mixed - { - $variable = $this->client->call(Client::METHOD_POST, '/sites/' . $siteId . '/variables', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), $params); - - return $variable; - } - - protected function getSite(string $siteId): mixed - { - $site = $this->client->call(Client::METHOD_GET, '/sites/' . $siteId, array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); - - return $site; - } - - protected function getDeployment(string $siteId, string $deploymentId): mixed - { - $deployment = $this->client->call(Client::METHOD_GET, '/sites/' . $siteId . '/deployments/' . $deploymentId, array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); - - return $deployment; - } - - protected function listSites(mixed $params = []): mixed - { - $sites = $this->client->call(Client::METHOD_GET, '/sites', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), $params); - - return $sites; - } - - protected function listDeployments(string $siteId, $params = []): mixed - { - $deployments = $this->client->call(Client::METHOD_GET, '/sites/' . $siteId . '/deployments', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), $params); - - return $deployments; - } - - protected function packageSite(string $site): CURLFile - { - $folderPath = realpath(__DIR__ . '/../../../resources/sites') . "/$site"; - $tarPath = "$folderPath/code.tar.gz"; - - Console::execute("cd $folderPath && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr); - - if (filesize($tarPath) > 1024 * 1024 * 5) { - throw new \Exception('Code package is too large. Use the chunked upload method instead.'); - } - - return new CURLFile($tarPath, 'application/x-gzip', \basename($tarPath)); - } - - protected function createDeployment(string $siteId, mixed $params = []): mixed - { - $deployment = $this->client->call(Client::METHOD_POST, '/sites/' . $siteId . '/deployments', array_merge([ - 'content-type' => 'multipart/form-data', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), $params); - - return $deployment; - } - - protected function getSiteUsage(string $siteId, mixed $params): mixed - { - $usage = $this->client->call(Client::METHOD_GET, '/sites/' . $siteId . '/usage', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), $params); - - return $usage; - } - - protected function getTemplate(string $templateId) - { - $template = $this->client->call(Client::METHOD_GET, '/sites/templates/' . $templateId, array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); - - return $template; - } - - protected function deleteSite(string $siteId): mixed - { - $site = $this->client->call(Client::METHOD_DELETE, '/sites/' . $siteId, array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders())); - - return $site; - } -} diff --git a/tests/e2e/Services/Sites/SitesCustomServerTest.php b/tests/e2e/Services/Sites/SitesCustomServerTest.php deleted file mode 100644 index 25ebfc9283..0000000000 --- a/tests/e2e/Services/Sites/SitesCustomServerTest.php +++ /dev/null @@ -1,155 +0,0 @@ -createSite([ - 'siteId' => ID::unique(), - 'name' => 'Test', - 'framework' => 'sveltekit', - 'installCommand' => 'npm install --force', - 'buildCommand' => 'npm run build', - 'outputDirectory' => './build', - 'buildRuntime' => 'node-22', - 'serveRuntime' => 'static-1', - 'subdomain' => 'test' - ]); - - $siteId = $site['body']['$id'] ?? ''; - - $dateValidator = new DatetimeValidator(); - $this->assertEquals(201, $site['headers']['status-code']); - $this->assertNotEmpty($site['body']['$id']); - $this->assertEquals('Test', $site['body']['name']); - $this->assertEquals('sveltekit', $site['body']['framework']); - $this->assertEquals(true, $dateValidator->isValid($site['body']['$createdAt'])); - $this->assertEquals(true, $dateValidator->isValid($site['body']['$updatedAt'])); - $this->assertEquals('npm install --force', $site['body']['installCommand']); - $this->assertEquals('npm run build', $site['body']['buildCommand']); - $this->assertEquals('./build', $site['body']['outputDirectory']); - $this->assertEquals('node-22', $site['body']['buildRuntime']); - $this->assertEquals('static-1', $site['body']['serveRuntime']); - - $variable = $this->createVariable($siteId, [ - 'key' => 'siteKey1', - 'value' => 'siteValue1', - ]); - $variable2 = $this->createVariable($siteId, [ - 'key' => 'siteKey2', - 'value' => 'siteValue2', - ]); - $variable3 = $this->createVariable($siteId, [ - 'key' => 'siteKey3', - 'value' => 'siteValue3', - ]); - - $this->assertEquals(201, $variable['headers']['status-code']); - $this->assertEquals(201, $variable2['headers']['status-code']); - $this->assertEquals(201, $variable3['headers']['status-code']); - - return [ - 'siteId' => $siteId, - ]; - } - - /** - * @depends testCreateSite - */ - public function testGetSite(array $data): array - { - /** - * Test for SUCCESS - */ - $site = $this->getSite($data['siteId']); - - $this->assertEquals($site['headers']['status-code'], 200); - $this->assertEquals($site['body']['name'], 'Test'); - - /** - * Test for FAILURE - */ - $site = $this->getSite('x'); - - $this->assertEquals($site['headers']['status-code'], 404); - - return $data; - } - - /** - * @depends testGetSite - */ - public function testDeleteSite(array $data): array - { - /** - * Test for SUCCESS - */ - $site = $this->deleteSite($data['siteId']); - - $this->assertEquals(204, $site['headers']['status-code']); - $this->assertEmpty($site['body']); - - $site = $this->getSite($data['siteId']); - - $this->assertEquals(404, $site['headers']['status-code']); - - return $data; - } - - /** - * @depends testGetSite - */ - public function testUniqueSubdomain(array $data): void - { - /** - * Test for SUCCESS - */ - $site = $this->createSite([ - 'siteId' => ID::unique(), - 'name' => 'Test', - 'framework' => 'sveltekit', - 'installCommand' => 'npm install --force', - 'buildCommand' => 'npm run build', - 'outputDirectory' => './build', - 'buildRuntime' => 'node-22', - 'serveRuntime' => 'static-1', - 'subdomain' => 'test' - ]); - - $this->assertEquals(201, $site['headers']['status-code']); - - /** - * Test for FAILURE - */ - $site = $this->createSite([ - 'siteId' => ID::unique(), - 'name' => 'Test2', - 'framework' => 'sveltekit', - 'installCommand' => 'npm install --force', - 'buildCommand' => 'npm run build', - 'outputDirectory' => './build', - 'buildRuntime' => 'node-22', - 'serveRuntime' => 'static-1', - 'subdomain' => 'test' - ]); - - $this->assertEquals(400, $site['headers']['status-code']); - - return; - } -} From 9089eb42280bf0f3f5ffab9767583e660a0e2329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Thu, 9 Jan 2025 15:44:13 +0000 Subject: [PATCH 07/10] New specs --- app/config/specs/open-api3-latest-console.json | 12 ++++++++---- app/config/specs/open-api3-latest-server.json | 12 ++++++++---- app/config/specs/swagger2-latest-console.json | 12 ++++++++---- app/config/specs/swagger2-latest-server.json | 12 ++++++++---- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/app/config/specs/open-api3-latest-console.json b/app/config/specs/open-api3-latest-console.json index 15e86fb6ce..c0636f5b20 100644 --- a/app/config/specs/open-api3-latest-console.json +++ b/app/config/specs/open-api3-latest-console.json @@ -9489,7 +9489,8 @@ "bun-1.1", "go-1.23", "static-1", - "flutter-3.24" + "flutter-3.24", + "ssr-22" ], "x-enum-name": null, "x-enum-keys": [] @@ -10147,7 +10148,8 @@ "bun-1.1", "go-1.23", "static-1", - "flutter-3.24" + "flutter-3.24", + "ssr-22" ], "x-enum-name": null, "x-enum-keys": [] @@ -25417,7 +25419,8 @@ "bun-1.1", "go-1.23", "static-1", - "flutter-3.24" + "flutter-3.24", + "ssr-22" ], "x-enum-name": null, "x-enum-keys": [] @@ -26021,7 +26024,8 @@ "bun-1.1", "go-1.23", "static-1", - "flutter-3.24" + "flutter-3.24", + "ssr-22" ], "x-enum-name": null, "x-enum-keys": [] diff --git a/app/config/specs/open-api3-latest-server.json b/app/config/specs/open-api3-latest-server.json index bd1b36a7dc..94b5075ade 100644 --- a/app/config/specs/open-api3-latest-server.json +++ b/app/config/specs/open-api3-latest-server.json @@ -8597,7 +8597,8 @@ "bun-1.1", "go-1.23", "static-1", - "flutter-3.24" + "flutter-3.24", + "ssr-22" ], "x-enum-name": null, "x-enum-keys": [] @@ -9021,7 +9022,8 @@ "bun-1.1", "go-1.23", "static-1", - "flutter-3.24" + "flutter-3.24", + "ssr-22" ], "x-enum-name": null, "x-enum-keys": [] @@ -17233,7 +17235,8 @@ "bun-1.1", "go-1.23", "static-1", - "flutter-3.24" + "flutter-3.24", + "ssr-22" ], "x-enum-name": null, "x-enum-keys": [] @@ -17602,7 +17605,8 @@ "bun-1.1", "go-1.23", "static-1", - "flutter-3.24" + "flutter-3.24", + "ssr-22" ], "x-enum-name": null, "x-enum-keys": [] diff --git a/app/config/specs/swagger2-latest-console.json b/app/config/specs/swagger2-latest-console.json index 2681bf0772..0365ec616a 100644 --- a/app/config/specs/swagger2-latest-console.json +++ b/app/config/specs/swagger2-latest-console.json @@ -9611,7 +9611,8 @@ "bun-1.1", "go-1.23", "static-1", - "flutter-3.24" + "flutter-3.24", + "ssr-22" ], "x-enum-name": null, "x-enum-keys": [] @@ -10288,7 +10289,8 @@ "bun-1.1", "go-1.23", "static-1", - "flutter-3.24" + "flutter-3.24", + "ssr-22" ], "x-enum-name": null, "x-enum-keys": [] @@ -25901,7 +25903,8 @@ "bun-1.1", "go-1.23", "static-1", - "flutter-3.24" + "flutter-3.24", + "ssr-22" ], "x-enum-name": null, "x-enum-keys": [] @@ -26521,7 +26524,8 @@ "bun-1.1", "go-1.23", "static-1", - "flutter-3.24" + "flutter-3.24", + "ssr-22" ], "x-enum-name": null, "x-enum-keys": [] diff --git a/app/config/specs/swagger2-latest-server.json b/app/config/specs/swagger2-latest-server.json index 199b94b202..f64f379d2d 100644 --- a/app/config/specs/swagger2-latest-server.json +++ b/app/config/specs/swagger2-latest-server.json @@ -8721,7 +8721,8 @@ "bun-1.1", "go-1.23", "static-1", - "flutter-3.24" + "flutter-3.24", + "ssr-22" ], "x-enum-name": null, "x-enum-keys": [] @@ -9168,7 +9169,8 @@ "bun-1.1", "go-1.23", "static-1", - "flutter-3.24" + "flutter-3.24", + "ssr-22" ], "x-enum-name": null, "x-enum-keys": [] @@ -17685,7 +17687,8 @@ "bun-1.1", "go-1.23", "static-1", - "flutter-3.24" + "flutter-3.24", + "ssr-22" ], "x-enum-name": null, "x-enum-keys": [] @@ -18074,7 +18077,8 @@ "bun-1.1", "go-1.23", "static-1", - "flutter-3.24" + "flutter-3.24", + "ssr-22" ], "x-enum-name": null, "x-enum-keys": [] From 0f8ce0e93e992e25c377cf44f5fc8435a2aca52e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Thu, 9 Jan 2025 16:59:40 +0000 Subject: [PATCH 08/10] Fix Sites --- app/config/site-templates.php | 6 +++--- docker-compose.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/config/site-templates.php b/app/config/site-templates.php index c65ca8f577..64696cedfa 100644 --- a/app/config/site-templates.php +++ b/app/config/site-templates.php @@ -135,12 +135,12 @@ return [ 'demoImage' => 'https://qa17.appwrite.org/console/images/sites/templates/astro-starter.png', 'frameworks' => [ getFramework('ASTRO', [ - 'providerRootDirectory' => './', + 'providerRootDirectory' => './astro/starter', ]), ], 'vcsProvider' => 'github', - 'providerRepositoryId' => 'astro-ssr-test-template', - 'providerOwner' => 'Meldiron', + 'providerRepositoryId' => 'templates-for-sites', + 'providerOwner' => 'appwrite', 'providerVersion' => '0.2.*', 'variables' => [], ], diff --git a/docker-compose.yml b/docker-compose.yml index 826b0e0f12..148ffe51f5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -201,7 +201,7 @@ services: appwrite-console: <<: *x-logging container_name: appwrite-console - image: appwrite/console:5.0.12 + image: appwrite/console:5.3.0-sites-rc.2 restart: unless-stopped networks: - appwrite From efe24db5a1dfb96fd42ba4ce70ecec7bc51e8751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Fri, 10 Jan 2025 15:28:09 +0100 Subject: [PATCH 09/10] Fix site starting crashes --- app/config/frameworks.php | 12 ++++++++++ composer.json | 2 +- composer.lock | 23 +++++++------------ docker-compose.yml | 2 +- .../Modules/Functions/Workers/Builds.php | 3 +++ 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/app/config/frameworks.php b/app/config/frameworks.php index ff54c0aacb..d19262ff57 100644 --- a/app/config/frameworks.php +++ b/app/config/frameworks.php @@ -31,6 +31,7 @@ return [ 'outputDirectory' => './.next', 'startCommand' => 'sh helpers/next-js/server.sh', 'bundleCommand' => 'sh /usr/local/server/helpers/next-js/bundle.sh', + 'envCommand' => 'source /usr/local/server/helpers/next-js/env.sh', ], 'static' => [ 'key' => 'static', @@ -39,6 +40,7 @@ return [ 'outputDirectory' => './out', 'startCommand' => 'sh helpers/server.sh', 'bundleCommand' => '', + 'envCommand' => '', ] ] ], @@ -55,6 +57,7 @@ return [ 'outputDirectory' => './.output', 'startCommand' => 'sh helpers/nuxt/server.sh', 'bundleCommand' => 'sh /usr/local/server/helpers/nuxt/bundle.sh', + 'envCommand' => 'source /usr/local/server/helpers/nuxt/env.sh', ], 'static' => [ 'key' => 'static', @@ -63,6 +66,7 @@ return [ 'outputDirectory' => './dist', 'startCommand' => 'sh helpers/server.sh', 'bundleCommand' => '', + 'envCommand' => '', ] ] ], @@ -79,6 +83,7 @@ return [ 'outputDirectory' => './build', 'startCommand' => 'sh helpers/sveltekit/server.sh', 'bundleCommand' => 'sh /usr/local/server/helpers/sveltekit/bundle.sh', + 'envCommand' => 'source /usr/local/server/helpers/sveltekit/env.sh', ], 'static' => [ 'key' => 'static', @@ -87,6 +92,7 @@ return [ 'outputDirectory' => './build', 'startCommand' => 'sh helpers/server.sh', 'bundleCommand' => '', + 'envCommand' => '', ] ] ], @@ -103,6 +109,7 @@ return [ 'outputDirectory' => './dist', 'startCommand' => 'sh helpers/astro/server.sh', 'bundleCommand' => 'sh /usr/local/server/helpers/astro/bundle.sh', + 'envCommand' => 'source /usr/local/server/helpers/astro/env.sh', ], 'static' => [ 'key' => 'static', @@ -111,6 +118,7 @@ return [ 'outputDirectory' => './dist', 'startCommand' => 'sh helpers/server.sh', 'bundleCommand' => '', + 'envCommand' => '', ] ] ], @@ -127,6 +135,7 @@ return [ 'outputDirectory' => './build', 'startCommand' => 'sh helpers/remix/server.sh', 'bundleCommand' => 'sh /usr/local/server/helpers/remix/bundle.sh', + 'envCommand' => 'source /usr/local/server/helpers/remix/env.sh', ], 'static' => [ 'key' => 'static', @@ -135,6 +144,7 @@ return [ 'outputDirectory' => './build/client', 'startCommand' => 'sh helpers/server.sh', 'bundleCommand' => '', + 'envCommand' => '', ] ] ], @@ -151,6 +161,7 @@ return [ 'outputDirectory' => './build/web', 'startCommand' => 'sh helpers/server.sh', 'bundleCommand' => '', + 'envCommand' => '', ], ], ], @@ -167,6 +178,7 @@ return [ 'outputDirectory' => './', 'startCommand' => 'sh helpers/server.sh', 'bundleCommand' => '', + 'envCommand' => '', ], ] ], diff --git a/composer.json b/composer.json index 54440debe5..4569c84354 100644 --- a/composer.json +++ b/composer.json @@ -43,7 +43,7 @@ "ext-openssl": "*", "ext-zlib": "*", "ext-sockets": "*", - "appwrite/php-runtimes": "dev-feat-add-ssr-runtime as 0.16.99", + "appwrite/php-runtimes": "0.17.*", "appwrite/php-clamav": "2.0.*", "utopia-php/abuse": "0.43.0", "utopia-php/analytics": "0.10.*", diff --git a/composer.lock b/composer.lock index 0cf7746c41..2098b9db8c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2a57d56106703cb729370214435feb98", + "content-hash": "20874601c6797a65c01000471bd74645", "packages": [ { "name": "adhocore/jwt", @@ -157,16 +157,16 @@ }, { "name": "appwrite/php-runtimes", - "version": "dev-feat-add-ssr-runtime", + "version": "0.17.0", "source": { "type": "git", "url": "https://github.com/appwrite/runtimes.git", - "reference": "a021a2b09b045375979f8e7bc2e7aa520fc94847" + "reference": "9a9e20d1f5c28caf539ad4cb52164dc283f99797" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/runtimes/zipball/a021a2b09b045375979f8e7bc2e7aa520fc94847", - "reference": "a021a2b09b045375979f8e7bc2e7aa520fc94847", + "url": "https://api.github.com/repos/appwrite/runtimes/zipball/9a9e20d1f5c28caf539ad4cb52164dc283f99797", + "reference": "9a9e20d1f5c28caf539ad4cb52164dc283f99797", "shasum": "" }, "require": { @@ -206,9 +206,9 @@ ], "support": { "issues": "https://github.com/appwrite/runtimes/issues", - "source": "https://github.com/appwrite/runtimes/tree/feat-add-ssr-runtime" + "source": "https://github.com/appwrite/runtimes/tree/0.17.0" }, - "time": "2025-01-07T12:14:14+00:00" + "time": "2025-01-10T13:36:30+00:00" }, { "name": "beberlei/assert", @@ -8555,12 +8555,6 @@ } ], "aliases": [ - { - "package": "appwrite/php-runtimes", - "version": "dev-feat-add-ssr-runtime", - "alias": "0.16.99", - "alias_normalized": "0.16.99.0" - }, { "package": "utopia-php/framework", "version": "dev-fix-prevent-duplicate-compression", @@ -8570,7 +8564,6 @@ ], "minimum-stability": "stable", "stability-flags": { - "appwrite/php-runtimes": 20, "utopia-php/framework": 20 }, "prefer-stable": false, @@ -8596,5 +8589,5 @@ "platform-overrides": { "php": "8.3" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.3.0" } diff --git a/docker-compose.yml b/docker-compose.yml index 148ffe51f5..35bdf30256 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -880,7 +880,7 @@ services: hostname: exc1 <<: *x-logging stop_signal: SIGINT - image: openruntimes/executor:0.7.2 + image: openruntimes/executor:0.7.3 restart: unless-stopped networks: - appwrite diff --git a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php index 047038e99b..d4e1820f0f 100644 --- a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php +++ b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php @@ -881,6 +881,9 @@ class Builds extends Action if (!is_null($adapter) && isset($adapter['bundleCommand'])) { $commands[] = $adapter['bundleCommand']; } + if (!is_null($adapter) && isset($adapter['envCommand'])) { + $commands[] = $adapter['envCommand']; + } } $commands = array_filter($commands, fn ($command) => !empty($command)); From d652a17fd7d6a9b3a70d7a6016561d687eb2db8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Tue, 21 Jan 2025 09:13:20 +0100 Subject: [PATCH 10/10] Remove unneeded runtime --- .env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env b/.env index fc64dc88a6..a17d5ba06c 100644 --- a/.env +++ b/.env @@ -80,7 +80,7 @@ _APP_EXECUTOR_SECRET=your-secret-key _APP_EXECUTOR_HOST=http://exc1/v1 _APP_FUNCTIONS_RUNTIMES=php-8.0,node-18.0,python-3.9,ruby-3.1 _APP_SITES_RUNTIMES=static-1,ssr-22,flutter-3.24 -_APP_SITES_FRAMEWORKS=sveltekit,nextjs,nuxt,astro,remix,static,flutter,other # TODO: Angular +_APP_SITES_FRAMEWORKS=sveltekit,nextjs,nuxt,astro,remix,flutter,other # TODO: Angular _APP_MAINTENANCE_INTERVAL=86400 _APP_MAINTENANCE_DELAY= _APP_MAINTENANCE_RETENTION_CACHE=2592000