From d9eb942e8cd39882ca991a55128d5df2cc32bc3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Tue, 4 Mar 2025 13:43:13 +0100 Subject: [PATCH 1/4] Merge deployment download endpoints --- .../Http/Deployments/Download/Get.php | 32 ++++- .../Modules/Functions/Services/Http.php | 2 - .../Http/Deployments/Builds/Download/Get.php | 133 ------------------ .../Sites/Http/Deployments/Download/Get.php | 36 +++-- .../Platform/Modules/Sites/Services/Http.php | 2 - src/Appwrite/Specification/Format.php | 16 +++ 6 files changed, 68 insertions(+), 153 deletions(-) delete mode 100644 src/Appwrite/Platform/Modules/Sites/Http/Deployments/Builds/Download/Get.php diff --git a/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Download/Get.php b/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Download/Get.php index 1a1ff9b938..c84d255f23 100644 --- a/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Download/Get.php +++ b/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Download/Get.php @@ -15,6 +15,7 @@ use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Storage\Device; use Utopia\Swoole\Request; +use Utopia\Validator\WhiteList; class Get extends Action { @@ -52,14 +53,16 @@ class Get extends Action )) ->param('functionId', '', new UID(), 'Function ID.') ->param('deploymentId', '', new UID(), 'Deployment ID.') + ->param('type', '', new WhiteList(['source', 'output']), 'Deployment file to download. Can be: "source", "output".') ->inject('response') ->inject('request') ->inject('dbForProject') ->inject('deviceForFunctions') + ->inject('deviceForBuilds') ->callback([$this, 'action']); } - public function action(string $functionId, string $deploymentId, Response $response, Request $request, Database $dbForProject, Device $deviceForFunctions) + public function action(string $functionId, string $deploymentId, string $type, Response $response, Request $request, Database $dbForProject, Device $deviceForFunctions, Device $deviceForBuilds) { $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { @@ -75,8 +78,23 @@ class Get extends Action throw new Exception(Exception::DEPLOYMENT_NOT_FOUND); } - $path = $deployment->getAttribute('path', ''); - if (!$deviceForFunctions->exists($path)) { + switch ($type) { + case 'output': + $build = $dbForProject->getDocument('builds', $deployment->getAttribute('buildId')); + if ($build->isEmpty()) { + throw new Exception(Exception::BUILD_NOT_FOUND); + } + + $path = $build->getAttribute('path', ''); + $device = $deviceForBuilds; + break; + case 'source': + $path = $deployment->getAttribute('path', ''); + $device = $deviceForFunctions; + break; + } + + if (!$device->exists($path)) { throw new Exception(Exception::DEPLOYMENT_NOT_FOUND); } @@ -86,7 +104,7 @@ class Get extends Action ->addHeader('X-Peak', \memory_get_peak_usage()) ->addHeader('Content-Disposition', 'attachment; filename="' . $deploymentId . '.tar.gz"'); - $size = $deviceForFunctions->getFileSize($path); + $size = $device->getFileSize($path); $rangeHeader = $request->getHeader('range'); if (!empty($rangeHeader)) { @@ -108,13 +126,13 @@ class Get extends Action ->addHeader('Content-Length', $end - $start + 1) ->setStatusCode(Response::STATUS_CODE_PARTIALCONTENT); - $response->send($deviceForFunctions->read($path, $start, ($end - $start + 1))); + $response->send($device->read($path, $start, ($end - $start + 1))); } if ($size > APP_STORAGE_READ_BUFFER) { for ($i = 0; $i < ceil($size / MAX_OUTPUT_CHUNK_SIZE); $i++) { $response->chunk( - $deviceForFunctions->read( + $device->read( $path, ($i * MAX_OUTPUT_CHUNK_SIZE), min(MAX_OUTPUT_CHUNK_SIZE, $size - ($i * MAX_OUTPUT_CHUNK_SIZE)) @@ -123,7 +141,7 @@ class Get extends Action ); } } else { - $response->send($deviceForFunctions->read($path)); + $response->send($device->read($path)); } } } diff --git a/src/Appwrite/Platform/Modules/Functions/Services/Http.php b/src/Appwrite/Platform/Modules/Functions/Services/Http.php index a17c80865e..5ae77c5d6b 100644 --- a/src/Appwrite/Platform/Modules/Functions/Services/Http.php +++ b/src/Appwrite/Platform/Modules/Functions/Services/Http.php @@ -3,7 +3,6 @@ namespace Appwrite\Platform\Modules\Functions\Services; use Appwrite\Platform\Modules\Functions\Http\Deployments\Builds\Create as CreateBuild; -use Appwrite\Platform\Modules\Functions\Http\Deployments\Builds\Download\Get as DownloadBuild; use Appwrite\Platform\Modules\Functions\Http\Deployments\Builds\Update as UpdateBuild; use Appwrite\Platform\Modules\Functions\Http\Deployments\Create as CreateDeployment; use Appwrite\Platform\Modules\Functions\Http\Deployments\Delete as DeleteDeployment; @@ -65,7 +64,6 @@ class Http extends Service $this->addAction(DownloadDeployment::getName(), new DownloadDeployment()); $this->addAction(CreateBuild::getName(), new CreateBuild()); $this->addAction(UpdateBuild::getName(), new UpdateBuild()); - $this->addAction(DownloadBuild::getName(), new DownloadBuild()); // Executions $this->addAction(CreateExecution::getName(), new CreateExecution()); diff --git a/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Builds/Download/Get.php b/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Builds/Download/Get.php deleted file mode 100644 index f86fa591c1..0000000000 --- a/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Builds/Download/Get.php +++ /dev/null @@ -1,133 +0,0 @@ -setHttpMethod(Action::HTTP_REQUEST_METHOD_GET) - ->setHttpPath('/v1/sites/:siteId/deployments/:deploymentId/build/download') - ->desc('Download build') - ->groups(['api', 'sites']) - ->label('scope', 'sites.read') - ->label('sdk', new Method( - namespace: 'sites', - name: 'getDeploymentBuildDownload', - description: <<param('siteId', '', new UID(), 'Site ID.') - ->param('deploymentId', '', new UID(), 'Deployment ID.') - ->inject('response') - ->inject('request') - ->inject('dbForProject') - ->inject('deviceForBuilds') - ->callback([$this, 'action']); - } - - public function action(string $siteId, string $deploymentId, Response $response, Request $request, Database $dbForProject, Device $deviceForBuilds) - { - $site = $dbForProject->getDocument('sites', $siteId); - if ($site->isEmpty()) { - throw new Exception(Exception::SITE_NOT_FOUND); - } - - $deployment = $dbForProject->getDocument('deployments', $deploymentId); - if ($deployment->isEmpty()) { - throw new Exception(Exception::DEPLOYMENT_NOT_FOUND); - } - - if ($deployment->getAttribute('resourceId') !== $site->getId()) { - throw new Exception(Exception::DEPLOYMENT_NOT_FOUND); - } - - $build = $dbForProject->getDocument('builds', $deployment->getAttribute('buildId')); - if ($build->isEmpty()) { - throw new Exception(Exception::BUILD_NOT_FOUND); - } - - $path = $build->getAttribute('path', ''); - if (!$deviceForBuilds->exists($path)) { - throw new Exception(Exception::BUILD_NOT_FOUND); - } - - $response - ->setContentType('application/gzip') - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache - ->addHeader('X-Peak', \memory_get_peak_usage()) - ->addHeader('Content-Disposition', 'attachment; filename="' . $deploymentId . '.tar.gz"'); - - $size = $deviceForBuilds->getFileSize($path); - $rangeHeader = $request->getHeader('range'); - - if (!empty($rangeHeader)) { - $start = $request->getRangeStart(); - $end = $request->getRangeEnd(); - $unit = $request->getRangeUnit(); - - if ($end === null) { - $end = min(($start + MAX_OUTPUT_CHUNK_SIZE - 1), ($size - 1)); - } - - if ($unit !== 'bytes' || $start >= $end || $end >= $size) { - throw new Exception(Exception::STORAGE_INVALID_RANGE); - } - - $response - ->addHeader('Accept-Ranges', 'bytes') - ->addHeader('Content-Range', 'bytes ' . $start . '-' . $end . '/' . $size) - ->addHeader('Content-Length', $end - $start + 1) - ->setStatusCode(Response::STATUS_CODE_PARTIALCONTENT); - - $response->send($deviceForBuilds->read($path, $start, ($end - $start + 1))); - } - - if ($size > APP_STORAGE_READ_BUFFER) { - for ($i = 0; $i < ceil($size / MAX_OUTPUT_CHUNK_SIZE); $i++) { - $response->chunk( - $deviceForBuilds->read( - $path, - ($i * MAX_OUTPUT_CHUNK_SIZE), - min(MAX_OUTPUT_CHUNK_SIZE, $size - ($i * MAX_OUTPUT_CHUNK_SIZE)) - ), - (($i + 1) * MAX_OUTPUT_CHUNK_SIZE) >= $size - ); - } - } else { - $response->send($deviceForBuilds->read($path)); - } - } -} diff --git a/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Download/Get.php b/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Download/Get.php index 2d38e619a6..2897c6914e 100644 --- a/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Download/Get.php +++ b/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Download/Get.php @@ -15,6 +15,7 @@ use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Storage\Device; use Utopia\Swoole\Request; +use Utopia\Validator\WhiteList; class Get extends Action { @@ -51,14 +52,16 @@ class Get extends Action )) ->param('siteId', '', new UID(), 'Site ID.') ->param('deploymentId', '', new UID(), 'Deployment ID.') + ->param('type', '', new WhiteList(['source', 'output']), 'Deployment file to download. Can be: "source", "output".') ->inject('response') ->inject('request') ->inject('dbForProject') ->inject('deviceForSites') + ->inject('deviceForBuilds') ->callback([$this, 'action']); } - public function action(string $siteId, string $deploymentId, Response $response, Request $request, Database $dbForProject, Device $deviceForSites) + public function action(string $siteId, string $deploymentId, string $type, Response $response, Request $request, Database $dbForProject, Device $deviceForSites, Device $deviceForBuilds) { $site = $dbForProject->getDocument('sites', $siteId); if ($site->isEmpty()) { @@ -74,18 +77,33 @@ class Get extends Action throw new Exception(Exception::DEPLOYMENT_NOT_FOUND); } - $path = $deployment->getAttribute('path', ''); - if (!$deviceForSites->exists($path)) { - throw new Exception(Exception::DEPLOYMENT_NOT_FOUND); + switch ($type) { + case 'output': + $build = $dbForProject->getDocument('builds', $deployment->getAttribute('buildId')); + if ($build->isEmpty()) { + throw new Exception(Exception::BUILD_NOT_FOUND); + } + + $path = $build->getAttribute('path', ''); + $device = $deviceForBuilds; + break; + case 'source': + $path = $deployment->getAttribute('path', ''); + $device = $deviceForSites; + break; + } + + if (!$device->exists($path)) { + throw new Exception(Exception::BUILD_NOT_FOUND); } $response ->setContentType('application/gzip') ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache ->addHeader('X-Peak', \memory_get_peak_usage()) - ->addHeader('Content-Disposition', 'attachment; filename="' . $deploymentId . '.tar.gz"'); + ->addHeader('Content-Disposition', 'attachment; filename="' . $deploymentId . '-' . $type . '.tar.gz"'); - $size = $deviceForSites->getFileSize($path); + $size = $device->getFileSize($path); $rangeHeader = $request->getHeader('range'); if (!empty($rangeHeader)) { @@ -107,13 +125,13 @@ class Get extends Action ->addHeader('Content-Length', $end - $start + 1) ->setStatusCode(Response::STATUS_CODE_PARTIALCONTENT); - $response->send($deviceForSites->read($path, $start, ($end - $start + 1))); + $response->send($device->read($path, $start, ($end - $start + 1))); } if ($size > APP_STORAGE_READ_BUFFER) { for ($i = 0; $i < ceil($size / MAX_OUTPUT_CHUNK_SIZE); $i++) { $response->chunk( - $deviceForSites->read( + $device->read( $path, ($i * MAX_OUTPUT_CHUNK_SIZE), min(MAX_OUTPUT_CHUNK_SIZE, $size - ($i * MAX_OUTPUT_CHUNK_SIZE)) @@ -122,7 +140,7 @@ class Get extends Action ); } } else { - $response->send($deviceForSites->read($path)); + $response->send($device->read($path)); } } } diff --git a/src/Appwrite/Platform/Modules/Sites/Services/Http.php b/src/Appwrite/Platform/Modules/Sites/Services/Http.php index 9df4329b01..7b322900d1 100644 --- a/src/Appwrite/Platform/Modules/Sites/Services/Http.php +++ b/src/Appwrite/Platform/Modules/Sites/Services/Http.php @@ -3,7 +3,6 @@ namespace Appwrite\Platform\Modules\Sites\Services; use Appwrite\Platform\Modules\Sites\Http\Deployments\Builds\Create as CreateBuild; -use Appwrite\Platform\Modules\Sites\Http\Deployments\Builds\Download\Get as DownloadBuild; use Appwrite\Platform\Modules\Sites\Http\Deployments\Builds\Update as UpdateBuild; use Appwrite\Platform\Modules\Sites\Http\Deployments\Create as CreateDeployment; use Appwrite\Platform\Modules\Sites\Http\Deployments\Delete as DeleteDeployment; @@ -58,7 +57,6 @@ class Http extends Service $this->addAction(UpdateDeployment::getName(), new UpdateDeployment()); $this->addAction(DeleteDeployment::getName(), new DeleteDeployment()); $this->addAction(DownloadDeployment::getName(), new DownloadDeployment()); - $this->addAction(DownloadBuild::getName(), new DownloadBuild()); $this->addAction(CreateBuild::getName(), new CreateBuild()); $this->addAction(UpdateBuild::getName(), new UpdateBuild()); diff --git a/src/Appwrite/Specification/Format.php b/src/Appwrite/Specification/Format.php index f4bec326e7..7e7dd988df 100644 --- a/src/Appwrite/Specification/Format.php +++ b/src/Appwrite/Specification/Format.php @@ -210,8 +210,24 @@ abstract class Format break; } break; + case 'functions': + switch ($method) { + case 'getDeploymentDownload': + switch ($param) { + case 'type': + return 'DeploymentDownloadType'; + } + break; + } + break; case 'sites': switch ($method) { + case 'getDeploymentDownload': + switch ($param) { + case 'type': + return 'Deployment'; + } + break; case 'getUsage': case 'listUsage': switch ($param) { From 64183f2946e3138952ee63be209b6131d9868ba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Tue, 4 Mar 2025 13:45:44 +0100 Subject: [PATCH 2/4] Fix tests, remove leftovers --- .../Http/Deployments/Builds/Download/Get.php | 133 ------------------ .../e2e/Services/Functions/FunctionsBase.php | 16 +-- .../Functions/FunctionsConsoleClientTest.php | 4 +- tests/e2e/Services/Sites/SitesBase.php | 16 +-- .../Services/Sites/SitesCustomServerTest.php | 4 +- 5 files changed, 12 insertions(+), 161 deletions(-) delete mode 100644 src/Appwrite/Platform/Modules/Functions/Http/Deployments/Builds/Download/Get.php diff --git a/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Builds/Download/Get.php b/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Builds/Download/Get.php deleted file mode 100644 index b6f40acb2a..0000000000 --- a/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Builds/Download/Get.php +++ /dev/null @@ -1,133 +0,0 @@ -setHttpMethod(Action::HTTP_REQUEST_METHOD_GET) - ->setHttpPath('/v1/functions/:functionId/deployments/:deploymentId/build/download') - ->desc('Download build') - ->groups(['api', 'functions']) - ->label('scope', 'functions.read') - ->label('sdk', new Method( - namespace: 'functions', - name: 'getDeploymentBuildDownload', - description: <<param('functionId', '', new UID(), 'Function ID.') - ->param('deploymentId', '', new UID(), 'Deployment ID.') - ->inject('response') - ->inject('request') - ->inject('dbForProject') - ->inject('deviceForBuilds') - ->callback([$this, 'action']); - } - - public function action(string $functionId, string $deploymentId, Response $response, Request $request, Database $dbForProject, Device $deviceForBuilds) - { - $function = $dbForProject->getDocument('functions', $functionId); - if ($function->isEmpty()) { - throw new Exception(Exception::FUNCTION_NOT_FOUND); - } - - $deployment = $dbForProject->getDocument('deployments', $deploymentId); - if ($deployment->isEmpty()) { - throw new Exception(Exception::DEPLOYMENT_NOT_FOUND); - } - - if ($deployment->getAttribute('resourceId') !== $function->getId()) { - throw new Exception(Exception::DEPLOYMENT_NOT_FOUND); - } - - $build = $dbForProject->getDocument('builds', $deployment->getAttribute('buildId')); - if ($build->isEmpty()) { - throw new Exception(Exception::BUILD_NOT_FOUND); - } - - $path = $build->getAttribute('path', ''); - if (!$deviceForBuilds->exists($path)) { - throw new Exception(Exception::BUILD_NOT_FOUND); - } - - $response - ->setContentType('application/gzip') - ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache - ->addHeader('X-Peak', \memory_get_peak_usage()) - ->addHeader('Content-Disposition', 'attachment; filename="' . $deploymentId . '.tar.gz"'); - - $size = $deviceForBuilds->getFileSize($path); - $rangeHeader = $request->getHeader('range'); - - if (!empty($rangeHeader)) { - $start = $request->getRangeStart(); - $end = $request->getRangeEnd(); - $unit = $request->getRangeUnit(); - - if ($end === null) { - $end = min(($start + MAX_OUTPUT_CHUNK_SIZE - 1), ($size - 1)); - } - - if ($unit !== 'bytes' || $start >= $end || $end >= $size) { - throw new Exception(Exception::STORAGE_INVALID_RANGE); - } - - $response - ->addHeader('Accept-Ranges', 'bytes') - ->addHeader('Content-Range', 'bytes ' . $start . '-' . $end . '/' . $size) - ->addHeader('Content-Length', $end - $start + 1) - ->setStatusCode(Response::STATUS_CODE_PARTIALCONTENT); - - $response->send($deviceForBuilds->read($path, $start, ($end - $start + 1))); - } - - if ($size > APP_STORAGE_READ_BUFFER) { - for ($i = 0; $i < ceil($size / MAX_OUTPUT_CHUNK_SIZE); $i++) { - $response->chunk( - $deviceForBuilds->read( - $path, - ($i * MAX_OUTPUT_CHUNK_SIZE), - min(MAX_OUTPUT_CHUNK_SIZE, $size - ($i * MAX_OUTPUT_CHUNK_SIZE)) - ), - (($i + 1) * MAX_OUTPUT_CHUNK_SIZE) >= $size - ); - } - } else { - $response->send($deviceForBuilds->read($path)); - } - } -} diff --git a/tests/e2e/Services/Functions/FunctionsBase.php b/tests/e2e/Services/Functions/FunctionsBase.php index c340032e5b..f97245b0af 100644 --- a/tests/e2e/Services/Functions/FunctionsBase.php +++ b/tests/e2e/Services/Functions/FunctionsBase.php @@ -313,22 +313,14 @@ trait FunctionsBase return $domain; } - protected function getDeploymentDownload(string $functionId, string $deploymentId): mixed + protected function getDeploymentDownload(string $functionId, string $deploymentId, string $type): mixed { $response = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments/' . $deploymentId . '/download', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), []); - - return $response; - } - - protected function getBuildDownload(string $functionId, string $deploymentId): mixed - { - $response = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments/' . $deploymentId . '/build/download', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), []); + ], $this->getHeaders()), [ + 'type' => $type + ]); return $response; } diff --git a/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php b/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php index 5778e9f20a..300090b156 100644 --- a/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php +++ b/tests/e2e/Services/Functions/FunctionsConsoleClientTest.php @@ -517,7 +517,7 @@ class FunctionsConsoleClientTest extends Scope $this->assertNotEmpty($deploymentId); - $response = $this->getDeploymentDownload($functionId, $deploymentId); + $response = $this->getDeploymentDownload($functionId, $deploymentId, 'source'); $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals('application/gzip', $response['headers']['content-type']); $this->assertGreaterThan(0, $response['headers']['content-length']); @@ -525,7 +525,7 @@ class FunctionsConsoleClientTest extends Scope $deploymentMd5 = \md5($response['body']); - $response = $this->getBuildDownload($functionId, $deploymentId); + $response = $this->getDeploymentDownload($functionId, $deploymentId, 'output'); $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals('application/gzip', $response['headers']['content-type']); $this->assertGreaterThan(0, $response['headers']['content-length']); diff --git a/tests/e2e/Services/Sites/SitesBase.php b/tests/e2e/Services/Sites/SitesBase.php index cdb7b3e2ad..6e597b31ec 100644 --- a/tests/e2e/Services/Sites/SitesBase.php +++ b/tests/e2e/Services/Sites/SitesBase.php @@ -348,22 +348,14 @@ trait SitesBase return $domain; } - protected function getDeploymentDownload(string $siteId, string $deploymentId): mixed + protected function getDeploymentDownload(string $siteId, string $deploymentId, string $type): mixed { $response = $this->client->call(Client::METHOD_GET, '/sites/' . $siteId . '/deployments/' . $deploymentId . '/download', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), []); - - return $response; - } - - protected function getBuildDownload(string $siteId, string $deploymentId): mixed - { - $response = $this->client->call(Client::METHOD_GET, '/sites/' . $siteId . '/deployments/' . $deploymentId . '/build/download', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), []); + ], $this->getHeaders()), [ + 'type' => $type, + ]); return $response; } diff --git a/tests/e2e/Services/Sites/SitesCustomServerTest.php b/tests/e2e/Services/Sites/SitesCustomServerTest.php index c6eb50fdee..3e6132c845 100644 --- a/tests/e2e/Services/Sites/SitesCustomServerTest.php +++ b/tests/e2e/Services/Sites/SitesCustomServerTest.php @@ -1657,7 +1657,7 @@ class SitesCustomServerTest extends Scope $this->assertNotEmpty($deploymentId); - $response = $this->getDeploymentDownload($siteId, $deploymentId); + $response = $this->getDeploymentDownload($siteId, $deploymentId, 'source'); $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals('application/gzip', $response['headers']['content-type']); $this->assertGreaterThan(0, $response['headers']['content-length']); @@ -1665,7 +1665,7 @@ class SitesCustomServerTest extends Scope $deploymentMd5 = \md5($response['body']); - $response = $this->getBuildDownload($siteId, $deploymentId); + $response = $this->getDeploymentDownload($siteId, $deploymentId, 'output'); $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals('application/gzip', $response['headers']['content-type']); $this->assertGreaterThan(0, $response['headers']['content-length']); From a2abd982cfc0bd631f2b890412287678924d5f48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Tue, 4 Mar 2025 14:13:47 +0100 Subject: [PATCH 3/4] Backwards compatibility --- .../Modules/Functions/Http/Deployments/Download/Get.php | 3 ++- .../Platform/Modules/Sites/Http/Deployments/Download/Get.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Download/Get.php b/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Download/Get.php index c84d255f23..a63ac18354 100644 --- a/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Download/Get.php +++ b/src/Appwrite/Platform/Modules/Functions/Http/Deployments/Download/Get.php @@ -31,6 +31,7 @@ class Get extends Action $this ->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET) ->setHttpPath('/v1/functions/:functionId/deployments/:deploymentId/download') + ->httpAlias('/v1/functions/:functionId/deployments/:deploymentId/build/download', [ 'type' => 'output' ]) ->groups(['api', 'functions']) ->desc('Download deployment') ->label('scope', 'functions.read') @@ -53,7 +54,7 @@ class Get extends Action )) ->param('functionId', '', new UID(), 'Function ID.') ->param('deploymentId', '', new UID(), 'Deployment ID.') - ->param('type', '', new WhiteList(['source', 'output']), 'Deployment file to download. Can be: "source", "output".') + ->param('type', 'source', new WhiteList(['source', 'output']), 'Deployment file to download. Can be: "source", "output".', true) ->inject('response') ->inject('request') ->inject('dbForProject') diff --git a/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Download/Get.php b/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Download/Get.php index 2897c6914e..10cebc94a1 100644 --- a/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Download/Get.php +++ b/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Download/Get.php @@ -31,6 +31,7 @@ class Get extends Action $this ->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET) ->setHttpPath('/v1/sites/:siteId/deployments/:deploymentId/download') + ->httpAlias('/v1/sites/:functionId/deployments/:deploymentId/build/download', [ 'type' => 'output' ]) ->desc('Download deployment') ->groups(['api', 'sites']) ->label('scope', 'sites.read') @@ -52,7 +53,7 @@ class Get extends Action )) ->param('siteId', '', new UID(), 'Site ID.') ->param('deploymentId', '', new UID(), 'Deployment ID.') - ->param('type', '', new WhiteList(['source', 'output']), 'Deployment file to download. Can be: "source", "output".') + ->param('type', 'source', new WhiteList(['source', 'output']), 'Deployment file to download. Can be: "source", "output".', true) ->inject('response') ->inject('request') ->inject('dbForProject') From 54413f4c5e32ad8467305d0348d1f161348f8fb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Tue, 4 Mar 2025 14:31:00 +0100 Subject: [PATCH 4/4] Fix bug --- src/Appwrite/Specification/Format.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Specification/Format.php b/src/Appwrite/Specification/Format.php index 7e7dd988df..b4d2270eef 100644 --- a/src/Appwrite/Specification/Format.php +++ b/src/Appwrite/Specification/Format.php @@ -225,7 +225,7 @@ abstract class Format case 'getDeploymentDownload': switch ($param) { case 'type': - return 'Deployment'; + return 'DeploymentDownloadType'; } break; case 'getUsage':