diff --git a/app/config/templates/site.php b/app/config/templates/site.php index d21a7bc34f..1130d55fcf 100644 --- a/app/config/templates/site.php +++ b/app/config/templates/site.php @@ -143,80 +143,80 @@ function getFramework(string $frameworkEnum, array $overrides) } return [ -[ - 'key' => 'nxt-lnk', - 'name' => 'Nxt Lnk', - 'useCases' => ['portfolio'], - 'screenshotDark' => $url . '/images/sites/templates/nxt-lnk-dark.png', - 'screenshotLight' => $url . '/images/sites/templates/nxt-lnk-light.png', - 'frameworks' => [ - getFramework('NEXTJS', [ - 'providerRootDirectory' => './nextjs/nxtlnk', - ]), + [ + 'key' => 'nxt-lnk', + 'name' => 'Nxt Lnk', + 'useCases' => ['portfolio'], + 'screenshotDark' => $url . '/images/sites/templates/nxt-lnk-dark.png', + 'screenshotLight' => $url . '/images/sites/templates/nxt-lnk-light.png', + 'frameworks' => [ + getFramework('NEXTJS', [ + 'providerRootDirectory' => './nextjs/nxtlnk', + ]), + ], + 'vcsProvider' => 'github', + 'providerRepositoryId' => 'templates-for-sites', + 'providerOwner' => 'appwrite', + 'providerVersion' => '0.3.*', + 'variables' => [] ], - 'vcsProvider' => 'github', - 'providerRepositoryId' => 'templates-for-sites', - 'providerOwner' => 'appwrite', - 'providerVersion' => '0.3.*', - 'variables' => [] -], -[ - 'key' => 'magic-portfolio', - 'name' => 'Magic Portfolio', - 'useCases' => ['portfolio'], - 'screenshotDark' => $url . '/images/sites/templates/magic-portfolio-dark.png', - 'screenshotLight' => $url . '/images/sites/templates/magic-portfolio-light.png', - 'frameworks' => [ - getFramework('NEXTJS', [ - 'providerRootDirectory' => './nextjs/magic-portfolio', - ]), + [ + 'key' => 'magic-portfolio', + 'name' => 'Magic Portfolio', + 'useCases' => ['portfolio'], + 'screenshotDark' => $url . '/images/sites/templates/magic-portfolio-dark.png', + 'screenshotLight' => $url . '/images/sites/templates/magic-portfolio-light.png', + 'frameworks' => [ + getFramework('NEXTJS', [ + 'providerRootDirectory' => './nextjs/magic-portfolio', + ]), + ], + 'vcsProvider' => 'github', + 'providerRepositoryId' => 'templates-for-sites', + 'providerOwner' => 'appwrite', + 'providerVersion' => '0.3.*', + 'variables' => [] ], - 'vcsProvider' => 'github', - 'providerRepositoryId' => 'templates-for-sites', - 'providerOwner' => 'appwrite', - 'providerVersion' => '0.3.*', - 'variables' => [] -], -[ - 'key' => 'littlelink', - 'name' => 'LittleLink', - 'useCases' => ['portfolio'], - 'screenshotDark' => $url . '/images/sites/templates/littlelink-dark.png', - 'screenshotLight' => $url . '/images/sites/templates/littlelink-light.png', - 'frameworks' => [ - getFramework('OTHER', [ - 'providerRootDirectory' => './other/littlelink', - ]), + [ + 'key' => 'littlelink', + 'name' => 'LittleLink', + 'useCases' => ['portfolio'], + 'screenshotDark' => $url . '/images/sites/templates/littlelink-dark.png', + 'screenshotLight' => $url . '/images/sites/templates/littlelink-light.png', + 'frameworks' => [ + getFramework('OTHER', [ + 'providerRootDirectory' => './other/littlelink', + ]), + ], + 'vcsProvider' => 'github', + 'providerRepositoryId' => 'templates-for-sites', + 'providerOwner' => 'appwrite', + 'providerVersion' => '0.3.*', + 'variables' => [] ], - 'vcsProvider' => 'github', - 'providerRepositoryId' => 'templates-for-sites', - 'providerOwner' => 'appwrite', - 'providerVersion' => '0.3.*', - 'variables' => [] -], -[ - 'key' => 'logspot', - 'name' => 'Logspot', - 'useCases' => ['blog'], - 'screenshotDark' => $url . '/images/sites/templates/logspot-dark.png', - 'screenshotLight' => $url . '/images/sites/templates/logspot-light.png', - 'frameworks' => [ - getFramework('NUXT', [ - 'providerRootDirectory' => './nuxt/logspot', - 'buildCommand' => 'npm run generate', - 'outputDirectory' => './dist', - 'adapter' => 'static', - ]), + [ + 'key' => 'logspot', + 'name' => 'Logspot', + 'useCases' => ['blog'], + 'screenshotDark' => $url . '/images/sites/templates/logspot-dark.png', + 'screenshotLight' => $url . '/images/sites/templates/logspot-light.png', + 'frameworks' => [ + getFramework('NUXT', [ + 'providerRootDirectory' => './nuxt/logspot', + 'buildCommand' => 'npm run generate', + 'outputDirectory' => './dist', + 'adapter' => 'static', + ]), + ], + 'vcsProvider' => 'github', + 'providerRepositoryId' => 'templates-for-sites', + 'providerOwner' => 'appwrite', + 'providerVersion' => '0.3.*', + 'variables' => [] ], - 'vcsProvider' => 'github', - 'providerRepositoryId' => 'templates-for-sites', - 'providerOwner' => 'appwrite', - 'providerVersion' => '0.3.*', - 'variables' => [] -], [ 'key' => 'astro-nano', 'name' => 'Astro Nano', diff --git a/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Template/Create.php b/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Template/Create.php index 98a975545d..398b22f50f 100644 --- a/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Template/Create.php +++ b/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Template/Create.php @@ -132,6 +132,11 @@ class Create extends Base return; } + $entrypoint = $function->getAttribute('entrypoint', ''); + if (empty($entrypoint)) { + throw new Exception(Exception::FUNCTION_ENTRYPOINT_MISSING); + } + $deploymentId = ID::unique(); $deployment = $dbForProject->createDocument('deployments', new Document([ '$id' => $deploymentId, @@ -143,10 +148,10 @@ class Create extends Base 'resourceId' => $function->getId(), 'resourceInternalId' => $function->getInternalId(), 'resourceType' => 'functions', - 'entrypoint' => $function->getAttribute('entrypoint', ''), + 'entrypoint' => $entrypoint, 'buildCommands' => $function->getAttribute('commands', ''), 'type' => 'manual', - 'search' => implode(' ', [$deploymentId, $function->getAttribute('entrypoint', '')]), + 'search' => implode(' ', [$deploymentId, $entrypoint]), 'activate' => $activate, ])); diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index 40d9ea5dba..e74a76bf22 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -2177,4 +2177,78 @@ class FunctionsCustomServerTest extends Scope $this->cleanupFunction($functionId); } + + public function testEmptyEntrypointInCreateDeployment() + { + $functionId = $this->setupFunction([ + 'functionId' => ID::unique(), + 'runtime' => 'php-8.0', + 'name' => 'Empty Entrypoint Test', + 'entrypoint' => '', + 'execute' => ['any'] + ]); + $this->assertNotEmpty($functionId); + + $deployment = $this->createDeployment($functionId, [ + 'code' => $this->packageFunction('php-cookie'), + 'activate' => true + ]); + $this->assertEquals(404, $deployment['headers']['status-code']); + $this->assertStringContainsString('Entrypoint for your Appwrite Function is missing.', $deployment['body']['message']); + + $this->cleanupFunction($functionId); + } + + public function testEmptyEntrypointInCreateTemplateDeployment() + { + $starterTemplate = $this->getTemplate('starter'); + $this->assertEquals(200, $starterTemplate['headers']['status-code']); + + $phpRuntime = array_values(array_filter($starterTemplate['body']['runtimes'], function ($runtime) { + return $runtime['name'] === 'php-8.0'; + }))[0]; + + $this->assertEmpty($starterTemplate['body']['variables']); + + $function = $this->createFunction( + [ + 'functionId' => ID::unique(), + 'name' => $starterTemplate['body']['name'], + 'runtime' => 'php-8.0', + 'execute' => $starterTemplate['body']['permissions'], + 'entrypoint' => '', + 'events' => $starterTemplate['body']['events'], + 'schedule' => $starterTemplate['body']['cron'], + 'timeout' => $starterTemplate['body']['timeout'], + 'commands' => $phpRuntime['commands'], + 'scopes' => $starterTemplate['body']['scopes'], + 'templateRepository' => $starterTemplate['body']['providerRepositoryId'], + 'templateOwner' => $starterTemplate['body']['providerOwner'], + 'templateRootDirectory' => $phpRuntime['providerRootDirectory'], + 'templateVersion' => $starterTemplate['body']['providerVersion'], + ] + ); + + $this->assertEquals(201, $function['headers']['status-code']); + $this->assertNotEmpty($function['body']['$id']); + + $functionId = $function['body']['$id'] ?? ''; + + $deployment = $this->createTemplateDeployment( + $functionId, + [ + 'functionId' => ID::unique(), + 'activate' => true, + 'repository' => $starterTemplate['body']['providerRepositoryId'], + 'owner' => $starterTemplate['body']['providerOwner'], + 'rootDirectory' => $phpRuntime['providerRootDirectory'], + 'version' => $starterTemplate['body']['providerVersion'], + ] + ); + + $this->assertEquals(404, $deployment['headers']['status-code']); + $this->assertStringContainsString('Entrypoint for your Appwrite Function is missing.', $deployment['body']['message']); + + $function = $this->cleanupFunction($functionId); + } }