diff --git a/app/config/collections/projects.php b/app/config/collections/projects.php index dae0337dc9..3c6c7317be 100644 --- a/app/config/collections/projects.php +++ b/app/config/collections/projects.php @@ -1222,6 +1222,17 @@ return [ 'array' => false, 'filters' => [], ], + [ + '$id' => ID::custom('deploymentScreenshots'), + 'type' => Database::VAR_BOOLEAN, + 'signed' => true, + 'size' => 0, + 'format' => '', + 'filters' => [], + 'required' => false, + 'default' => true, + 'array' => false, + ], ], 'indexes' => [ [ diff --git a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php index 1d202b4948..959b6091e3 100644 --- a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php +++ b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php @@ -916,7 +916,7 @@ class Builds extends Action $logs = $deployment->getAttribute('buildLogs', ''); /** Screenshot site */ - if ($resource->getCollection() === 'sites') { + if ($resource->getCollection() === 'sites' && $resource->getAttribute('deploymentScreenshots', true)) { Console::log('Site screenshot started'); $date = \date('H:i:s'); diff --git a/src/Appwrite/Platform/Modules/Sites/Http/Sites/Create.php b/src/Appwrite/Platform/Modules/Sites/Http/Sites/Create.php index 76a11ff736..80e1fd87a8 100644 --- a/src/Appwrite/Platform/Modules/Sites/Http/Sites/Create.php +++ b/src/Appwrite/Platform/Modules/Sites/Http/Sites/Create.php @@ -78,6 +78,7 @@ class Create extends Base ->param('providerBranch', '', new Text(128, 0), 'Production branch for the repo linked to the site.', true) ->param('providerSilentMode', false, new Boolean(), 'Is the VCS (Version Control System) connection in silent mode for the repo linked to the site? In silent mode, comments will not be made on commits and pull requests.', true) ->param('providerRootDirectory', '', new Text(128, 0), 'Path to site code in the linked repo.', true) + ->param('deploymentScreenshots', true, new Boolean(), 'Whether to generate screenshots during deployment.', true) ->param('specification', fn (array $plan) => $this->getDefaultSpecification($plan), fn (array $plan) => new Specification( $plan, Config::getParam('specifications', []), @@ -110,6 +111,7 @@ class Create extends Base string $providerBranch, bool $providerSilentMode, string $providerRootDirectory, + bool $deploymentScreenshots, string $specification, Response $response, Database $dbForProject, @@ -164,6 +166,7 @@ class Create extends Base 'specification' => $specification, 'buildRuntime' => $buildRuntime, 'adapter' => $adapter, + 'deploymentScreenshots' => $deploymentScreenshots, ])); // Git connect logic diff --git a/src/Appwrite/Platform/Modules/Sites/Http/Sites/Update.php b/src/Appwrite/Platform/Modules/Sites/Http/Sites/Update.php index 8c48aff586..580e325ab0 100644 --- a/src/Appwrite/Platform/Modules/Sites/Http/Sites/Update.php +++ b/src/Appwrite/Platform/Modules/Sites/Http/Sites/Update.php @@ -82,6 +82,7 @@ class Update extends Base ->param('providerBranch', '', new Text(128, 0), 'Production branch for the repo linked to the site.', true) ->param('providerSilentMode', false, new Boolean(), 'Is the VCS (Version Control System) connection in silent mode for the repo linked to the site? In silent mode, comments will not be made on commits and pull requests.', true) ->param('providerRootDirectory', '', new Text(128, 0), 'Path to site code in the linked repo.', true) + ->param('deploymentScreenshots', true, new Boolean(), 'Whether to generate screenshots during deployment.', true) ->param('specification', fn (array $plan) => $this->getDefaultSpecification($plan), fn (array $plan) => new Specification( $plan, Config::getParam('specifications', []), @@ -118,6 +119,7 @@ class Update extends Base string $providerBranch, bool $providerSilentMode, string $providerRootDirectory, + bool $deploymentScreenshots, string $specification, Request $request, Response $response, @@ -268,6 +270,7 @@ class Update extends Base 'buildRuntime' => $buildRuntime, 'adapter' => $adapter, 'fallbackFile' => $fallbackFile, + 'deploymentScreenshots' => $deploymentScreenshots, ]))); // Redeploy logic diff --git a/src/Appwrite/Utopia/Response/Model/Site.php b/src/Appwrite/Utopia/Response/Model/Site.php index e6e205909b..bc1b9dfaf1 100644 --- a/src/Appwrite/Utopia/Response/Model/Site.php +++ b/src/Appwrite/Utopia/Response/Model/Site.php @@ -185,6 +185,12 @@ class Site extends Model 'default' => null, 'example' => 'index.html', ]) + ->addRule('deploymentScreenshots', [ + 'type' => self::TYPE_BOOLEAN, + 'description' => 'Whether to generate screenshots during deployment.', + 'default' => true, + 'example' => true, + ]) ; } diff --git a/tests/e2e/Services/Sites/SitesConsoleClientTest.php b/tests/e2e/Services/Sites/SitesConsoleClientTest.php index 2b75402b25..263926231a 100644 --- a/tests/e2e/Services/Sites/SitesConsoleClientTest.php +++ b/tests/e2e/Services/Sites/SitesConsoleClientTest.php @@ -141,4 +141,62 @@ class SitesConsoleClientTest extends Scope $this->cleanupSite($siteId); } + + /** + * @group screenshots + */ + public function testSiteScreenshotDisabled(): void + { + $siteId = $this->setupSite([ + 'siteId' => ID::unique(), + 'name' => 'Themed site', + 'framework' => 'other', + 'adapter' => 'static', + 'buildRuntime' => 'static-1', + 'outputDirectory' => './', + 'buildCommand' => '', + 'installCommand' => '', + 'fallbackFile' => '', + 'deploymentScreenshots' => false + ]); + + $this->assertNotEmpty($siteId); + + $site = $this->getSite($siteId); + $this->assertEquals(200, $site['headers']['status-code']); + $this->assertFalse($site['body']['deploymentScreenshots']); + + $domain = $this->setupSiteDomain($siteId); + + $deploymentId = $this->setupDeployment($siteId, [ + 'code' => $this->packageSite('static-themed'), + 'activate' => 'true' + ]); + + $this->assertNotEmpty($deploymentId); + + $domain = $this->getSiteDomain($siteId); + $this->assertNotEmpty($domain); + + $proxyClient = new Client(); + $proxyClient->setEndpoint('http://' . $domain); + + $response = $proxyClient->call(Client::METHOD_GET, '/'); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertStringContainsString("Themed website", $response['body']); + $this->assertStringContainsString("@media (prefers-color-scheme: dark)", $response['body']); + + $deployment = $this->getDeployment($siteId, $deploymentId); + $this->assertEquals(200, $deployment['headers']['status-code']); + $this->assertEmpty($deployment['body']['screenshotLight']); + $this->assertEmpty($deployment['body']['screenshotDark']); + + $site = $this->getSite($siteId); + $this->assertEquals(200, $site['headers']['status-code']); + $this->assertEmpty($site['body']['deploymentScreenshotLight']); + $this->assertEmpty($site['body']['deploymentScreenshotDark']); + + $this->cleanupSite($siteId); + } } diff --git a/tests/e2e/Services/Sites/SitesCustomServerTest.php b/tests/e2e/Services/Sites/SitesCustomServerTest.php index 22a33fbf4d..f6a91605d3 100644 --- a/tests/e2e/Services/Sites/SitesCustomServerTest.php +++ b/tests/e2e/Services/Sites/SitesCustomServerTest.php @@ -625,6 +625,68 @@ class SitesCustomServerTest extends Scope $this->cleanupSite($siteId); } + public function testSiteWithoutDeploymentScreenshot(): void + { + $site = $this->createSite([ + 'siteId' => ID::unique(), + 'name' => 'Static site', + 'framework' => 'astro', + 'buildRuntime' => 'node-22', + 'outputDirectory' => './dist', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'deploymentScreenshots' => true + ]); + $this->assertEquals(201, $site['headers']['status-code']); + $this->assertTrue($site['body']['deploymentScreenshots']); + + $siteId = $site['body']['$id']; + + $this->assertNotEmpty($siteId); + + $site = $this->getSite($siteId); + $this->assertEquals('200', $site['headers']['status-code']); + $this->assertTrue($site['body']['deploymentScreenshots']); + + $site = $this->updateSite([ + 'name' => 'Static site', + 'framework' => 'astro', + 'buildRuntime' => 'node-22', + 'outputDirectory' => './dist', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'deploymentScreenshots' => false, // Important change + '$id' => $siteId, + ]); + + $this->assertEquals('200', $site['headers']['status-code']); + $this->assertFalse($site['body']['deploymentScreenshots']); + + $site = $this->getSite($siteId); + $this->assertEquals('200', $site['headers']['status-code']); + $this->assertFalse($site['body']['deploymentScreenshots']); + + $site = $this->updateSite([ + 'name' => 'Static site', + 'framework' => 'astro', + 'buildRuntime' => 'node-22', + 'outputDirectory' => './dist', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'deploymentScreenshots' => true, // Important change + '$id' => $siteId, + ]); + + $this->assertEquals('200', $site['headers']['status-code']); + $this->assertTrue($site['body']['deploymentScreenshots']); + + $site = $this->getSite($siteId); + $this->assertEquals('200', $site['headers']['status-code']); + $this->assertTrue($site['body']['deploymentScreenshots']); + + $this->cleanupSite($siteId); + } + public function testListSites(): void { /**