From 5ed59fcf1b819d944e340b5bd1d8976b73d1f251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Wed, 31 Dec 2025 15:11:42 +0100 Subject: [PATCH] Implement toggle for deployment screenshotting for sites --- app/config/collections/projects.php | 11 ++++ .../Modules/Functions/Workers/Builds.php | 2 +- .../Modules/Sites/Http/Sites/Create.php | 3 + .../Modules/Sites/Http/Sites/Update.php | 3 + src/Appwrite/Utopia/Response/Model/Site.php | 6 ++ .../Services/Sites/SitesConsoleClientTest.php | 58 +++++++++++++++++ .../Services/Sites/SitesCustomServerTest.php | 62 +++++++++++++++++++ 7 files changed, 144 insertions(+), 1 deletion(-) 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 { /**