diff --git a/app/controllers/general.php b/app/controllers/general.php index 5fc86479a1..9803233a86 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -99,10 +99,11 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo $type = $rule->getAttribute('resourceType'); - if ($type === 'function' || $type === 'site') { + if ($type === 'function' || $type === 'site' || $type === 'deployment') { $resourceCollection = match($type) { 'function' => 'functions', - 'site' => 'sites' + 'site' => 'sites', + 'deployment' => 'deployments', }; $utopia->getRoute()?->label('sdk.namespace', 'functions'); @@ -136,7 +137,12 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo /** @var Database $dbForProject */ $dbForProject = $getProjectDB($project); - $resource = Authorization::skip(fn () => $dbForProject->getDocument($resourceCollection, $resourceId)); + if ($resourceCollection === 'deployments') { + $subResource = Authorization::skip(fn () => $dbForProject->getDocument($resourceCollection, $resourceId)); + $resource = Authorization::skip(fn () => $dbForProject->getDocument($subResource->getAttribute('resourceType'), $subResource->getAttribute('resourceId'))); + } else { + $resource = Authorization::skip(fn () => $dbForProject->getDocument($resourceCollection, $resourceId)); + } if ($resource->isEmpty() || !$resource->getAttribute('enabled')) { throw new AppwriteException(AppwriteException::FUNCTION_NOT_FOUND); @@ -144,7 +150,8 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo $version = match($type) { 'function' => $resource->getAttribute('version', 'v2'), - 'site' => 'v4' + 'site' => 'v4', + 'deployment' => 'v4' }; $runtimes = Config::getParam($version === 'v2' ? 'runtimes-v2' : 'runtimes', []); @@ -153,6 +160,7 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo $runtime = match($type) { 'function' => $runtimes[$resource->getAttribute('runtime')] ?? null, 'site' => $runtimes[$resource->getAttribute('serveRuntime')] ?? null, + 'deployment' => $runtimes[$resource->getAttribute('serveRuntime')] ?? null, default => null }; @@ -162,7 +170,8 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo $deploymentId = match($type) { 'function' => $resource->getAttribute('deployment', ''), - 'site' => $resource->getAttribute('deploymentId', '') + 'site' => $resource->getAttribute('deploymentId', ''), + 'deployment' => $subResource->getId() }; $deployment = Authorization::skip(fn () => $dbForProject->getDocument('deployments', $deploymentId)); @@ -321,11 +330,13 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo try { $version = match($type) { 'function' => $resource->getAttribute('version', 'v2'), - 'site' => 'v4' + 'site' => 'v4', + 'deployment' => 'v4' }; $entrypoint = match($type) { 'function' => $deployment->getAttribute('entrypoint', ''), - 'site' => '' + 'site' => '', + 'deployment' => '' }; $runtimeEntrypoint = match ($version) { 'v2' => '', diff --git a/app/views/install/compose.phtml b/app/views/install/compose.phtml index 15a68fac46..94ad4caec6 100644 --- a/app/views/install/compose.phtml +++ b/app/views/install/compose.phtml @@ -797,7 +797,7 @@ $image = $this->getParam('image', ''); <<: *x-logging restart: unless-stopped stop_signal: SIGINT - image: openruntimes/executor:0.6.25 + image: openruntimes/executor:0.6.26 networks: - appwrite - runtimes diff --git a/docker-compose.yml b/docker-compose.yml index e324f93870..bac0488ba7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -481,6 +481,7 @@ services: - _APP_STORAGE_WASABI_REGION - _APP_STORAGE_WASABI_BUCKET - _APP_DATABASE_SHARED_TABLES + - _APP_DOMAIN_SITES appwrite-worker-certificates: entrypoint: worker-certificates @@ -878,7 +879,7 @@ services: hostname: exc1 <<: *x-logging stop_signal: SIGINT - image: openruntimes/executor:0.6.25 + image: openruntimes/executor:0.6.26 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 97e5170d66..403941c893 100644 --- a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php +++ b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php @@ -692,6 +692,31 @@ class Builds extends Action } } + // Preview deployments for sites + if ($resource->getCollection() === 'sites') { + $ruleId = ID::unique(); + + $deploymentId = $deployment->getId(); + $projectId = $project->getId(); + + $sitesDomain = System::getEnv('_APP_DOMAIN_SITES', ''); + $domain = "{$deploymentId}-{$projectId}.{$sitesDomain}"; + + $rule = Authorization::skip( + fn () => $dbForConsole->createDocument('rules', new Document([ + '$id' => $ruleId, + 'projectId' => $project->getId(), + 'projectInternalId' => $project->getInternalId(), + 'domain' => $domain, + 'resourceType' => 'deployment', + 'resourceId' => $deployment->getId(), + 'resourceInternalId' => $deployment->getInternalId(), + 'status' => 'verified', + 'certificateId' => '', + ])) + ); + } + if ($dbForProject->getDocument('builds', $buildId)->getAttribute('status') === 'canceled') { Console::info('Build has been canceled'); return; diff --git a/src/Appwrite/Platform/Modules/Sites/Http/Deployments/GetDeployment.php b/src/Appwrite/Platform/Modules/Sites/Http/Deployments/GetDeployment.php index cbe4b21569..b70bddb842 100644 --- a/src/Appwrite/Platform/Modules/Sites/Http/Deployments/GetDeployment.php +++ b/src/Appwrite/Platform/Modules/Sites/Http/Deployments/GetDeployment.php @@ -3,8 +3,10 @@ namespace Appwrite\Platform\Modules\Sites\Http\Deployments; use Appwrite\Extend\Exception; +use Appwrite\Query; use Appwrite\Utopia\Response; use Utopia\Database\Database; +use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\UID; use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; @@ -37,10 +39,11 @@ class GetDeployment extends Action ->param('deploymentId', '', new UID(), 'Deployment ID.') ->inject('response') ->inject('dbForProject') + ->inject('dbForConsole') ->callback([$this, 'action']); } - public function action(string $siteId, string $deploymentId, Response $response, Database $dbForProject) + public function action(string $siteId, string $deploymentId, Response $response, Database $dbForProject, Database $dbForConsole) { $site = $dbForProject->getDocument('sites', $siteId); @@ -65,6 +68,15 @@ class GetDeployment extends Action $deployment->setAttribute('buildSize', $build->getAttribute('size', 0)); $deployment->setAttribute('size', $deployment->getAttribute('size', 0)); + $rule = Authorization::skip(fn () => $dbForConsole->findOne('rules', [ + Query::equal("resourceType", ["deployment"]), + Query::equal("resourceId", [$deployment->getId()]) + ])); + + if (!empty($rule)) { + $deployment->setAttribute('domain', $rule->getAttribute('domain', '')); + } + $response->dynamic($deployment, Response::MODEL_DEPLOYMENT); } } diff --git a/src/Appwrite/Platform/Modules/Sites/Http/Deployments/ListDeployments.php b/src/Appwrite/Platform/Modules/Sites/Http/Deployments/ListDeployments.php index c800f7245b..b1642852dc 100644 --- a/src/Appwrite/Platform/Modules/Sites/Http/Deployments/ListDeployments.php +++ b/src/Appwrite/Platform/Modules/Sites/Http/Deployments/ListDeployments.php @@ -9,6 +9,7 @@ use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Exception\Query as QueryException; use Utopia\Database\Query; +use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\Query\Cursor; use Utopia\Database\Validator\UID; use Utopia\Platform\Action; @@ -44,10 +45,11 @@ class ListDeployments extends Action ->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true) ->inject('response') ->inject('dbForProject') + ->inject('dbForConsole') ->callback([$this, 'action']); } - public function action(string $siteId, array $queries, string $search, Response $response, Database $dbForProject) + public function action(string $siteId, array $queries, string $search, Response $response, Database $dbForProject, Database $dbForConsole) { $site = $dbForProject->getDocument('sites', $siteId); @@ -106,6 +108,15 @@ class ListDeployments extends Action $result->setAttribute('buildTime', $build->getAttribute('duration', 0)); $result->setAttribute('buildSize', $build->getAttribute('size', 0)); $result->setAttribute('size', $result->getAttribute('size', 0)); + + $rule = Authorization::skip(fn () => $dbForConsole->findOne('rules', [ + Query::equal("resourceType", ["deployment"]), + Query::equal("resourceId", [$result->getId()]) + ])); + + if (!empty($rule)) { + $result->setAttribute('domain', $rule->getAttribute('domain', '')); + } } $response->dynamic(new Document([ diff --git a/src/Appwrite/Platform/Modules/Sites/Http/Sites/CreateSite.php b/src/Appwrite/Platform/Modules/Sites/Http/Sites/CreateSite.php index f6983e8f48..b98dc1bb07 100644 --- a/src/Appwrite/Platform/Modules/Sites/Http/Sites/CreateSite.php +++ b/src/Appwrite/Platform/Modules/Sites/Http/Sites/CreateSite.php @@ -66,8 +66,8 @@ class CreateSite extends Base ->param('buildCommand', '', new Text(8192, 0), 'Build Command.', true) ->param('outputDirectory', '', new Text(8192, 0), 'Output Directory for site.', true) ->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) - ->param('buildRuntime', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Runtime to use during build step.', true) - ->param('serveRuntime', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Runtime to use when serving site.', true) + ->param('buildRuntime', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Runtime to use during build step.') + ->param('serveRuntime', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Runtime to use when serving site.') ->param('installationId', '', new Text(128, 0), 'Appwrite Installation ID for VCS (Version Control System) deployment.', true) ->param('providerRepositoryId', '', new Text(128, 0), 'Repository ID of the repo linked to the site.', true) ->param('providerBranch', '', new Text(128, 0), 'Production branch for the repo linked to the site.', true) @@ -104,7 +104,7 @@ class CreateSite extends Base if (!empty($sitesDomain)) { $ruleId = ID::unique(); - $routeSubdomain = $subdomain ?? ID::unique(); + $routeSubdomain = $subdomain ?: ID::unique(); $domain = "{$routeSubdomain}.{$sitesDomain}"; $subdomain = Authorization::skip(fn () => $dbForConsole->findOne('rules', [ diff --git a/src/Appwrite/Utopia/Response/Model/Deployment.php b/src/Appwrite/Utopia/Response/Model/Deployment.php index 91a9f40956..0e49c82f82 100644 --- a/src/Appwrite/Utopia/Response/Model/Deployment.php +++ b/src/Appwrite/Utopia/Response/Model/Deployment.php @@ -94,6 +94,12 @@ class Deployment extends Model 'default' => 0, 'example' => 128, ]) + ->addRule('domain', [ + 'type' => self::TYPE_STRING, + 'description' => 'Preview domain.', + 'default' => '', + 'example' => 'deploy1-project1.appwrite.site', + ]) ->addRule('providerRepositoryName', [ 'type' => self::TYPE_STRING, 'description' => 'The name of the vcs provider repository',