mirror of
https://github.com/appwrite/appwrite
synced 2026-05-22 16:38:32 +00:00
Merge pull request #8877 from appwrite/feat-preview-deployments
Feat: Implement preview deployments
This commit is contained in:
commit
fd02ca00f0
8 changed files with 80 additions and 14 deletions
|
|
@ -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' => '',
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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([
|
||||
|
|
|
|||
|
|
@ -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', [
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
Loading…
Reference in a new issue