Merge branch 'feat-sites' into chore-add-template-tests-to-sites

This commit is contained in:
Matej Bačo 2025-03-11 14:17:40 +01:00
commit ab7041d653
29 changed files with 165 additions and 61 deletions

View file

@ -1820,17 +1820,6 @@ return [
'array' => false,
'filters' => ['json'],
],
[
'$id' => ID::custom('search'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16384,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('scheduledAt'),
'type' => Database::VAR_DATETIME,
@ -1873,13 +1862,6 @@ return [
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_fulltext_search'),
'type' => Database::INDEX_FULLTEXT,
'attributes' => ['search'],
'lengths' => [],
'orders' => [],
],
[
'$id' => ID::custom('_key_trigger'),
'type' => Database::INDEX_KEY,

View file

@ -96,6 +96,16 @@ const TEMPLATE_FRAMEWORKS = [
'outputDirectory' => './dist',
'fallbackFile' => 'index.html',
],
'ANGULAR' => [
'key' => 'angular',
'name' => 'Angular',
'installCommand' => 'npm install',
'buildCommand' => 'npm run build',
'buildRuntime' => 'node-22',
'adapter' => 'static',
'outputDirectory' => './dist/angular/browser',
'fallbackFile' => 'index.html',
],
'VUE' => [
'key' => 'vue',
'name' => 'Vue.js',
@ -135,6 +145,95 @@ return [
'providerVersion' => '0.1.*',
'variables' => []
],
[
'key' => 'starter-for-js',
'name' => 'JavaScript starter',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/starter-for-js-dark.png',
'screenshotLight' => $url . '/images/sites/templates/starter-for-js-light.png',
'frameworks' => [
getFramework('OTHER', [
'installCommand' => 'npm install',
'buildCommand' => 'npm run build',
'providerRootDirectory' => './',
'outputDirectory' => './dist',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'starter-for-js',
'providerOwner' => 'appwrite',
'providerVersion' => '0.1.*',
'variables' => [
[
'name' => 'VITE_APPWRITE_ENDPOINT',
'description' => 'Endpoint of Appwrite server',
'value' => '{apiEndpoint}',
'placeholder' => '{apiEndpoint}',
'required' => true,
'type' => 'text'
],
[
'name' => 'VITE_APPWRITE_PROJECT_ID',
'description' => 'Your Appwrite project ID',
'value' => '{projectId}',
'placeholder' => '{projectId}',
'required' => true,
'type' => 'text'
],
[
'name' => 'VITE_APPWRITE_PROJECT_NAME',
'description' => 'Your Appwrite project name',
'value' => '{projectName}',
'placeholder' => '{projectName}',
'required' => true,
'type' => 'text'
],
]
],
[
'key' => 'starter-for-angular',
'name' => 'Angular starter',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/starter-for-angular-dark.png',
'screenshotLight' => $url . '/images/sites/templates/starter-for-angular-light.png',
'frameworks' => [
getFramework('ANGULAR', [
'providerRootDirectory' => './',
'outputDirectory' => './dist/angular-starter-kit-for-appwrite/browser',
'buildCommand' => 'sh prepare-env.sh && npm run build'
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'starter-for-angular',
'providerOwner' => 'appwrite',
'providerVersion' => '0.1.*',
'variables' => [
[
'name' => 'APPWRITE_ENDPOINT',
'description' => 'Endpoint of Appwrite server',
'value' => '{apiEndpoint}',
'placeholder' => '{apiEndpoint}',
'required' => true,
'type' => 'text'
],
[
'name' => 'APPWRITE_PROJECT_ID',
'description' => 'Your Appwrite project ID',
'value' => '{projectId}',
'placeholder' => '{projectId}',
'required' => true,
'type' => 'text'
],
[
'name' => 'APPWRITE_PROJECT_NAME',
'description' => 'Your Appwrite project name',
'value' => '{projectName}',
'placeholder' => '{projectName}',
'required' => true,
'type' => 'text'
],
]
],
[
'key' => 'starter-for-svelte',
'name' => 'Svelte starter',

View file

@ -245,7 +245,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
'providerCommitHash' => $providerCommitHash,
'providerCommitAuthorUrl' => $providerCommitAuthorUrl,
'providerCommitAuthor' => $providerCommitAuthor,
'providerCommitMessage' => $providerCommitMessage,
'providerCommitMessage' => mb_strimwidth($providerCommitMessage, 0, 255, '...'),
'providerCommitUrl' => $providerCommitUrl,
'providerCommentId' => \strval($latestCommentId),
'providerBranch' => $providerBranch,

View file

@ -330,7 +330,6 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
'errors' => '',
'logs' => '',
'duration' => 0.0,
'search' => implode(' ', [$resource->getId(), $executionId]),
]);
if ($type === 'function') {

View file

@ -390,8 +390,8 @@ Config::load('storage-mimes', __DIR__ . '/config/storage/mimes.php');
Config::load('storage-inputs', __DIR__ . '/config/storage/inputs.php');
Config::load('storage-outputs', __DIR__ . '/config/storage/outputs.php');
Config::load('specifications', __DIR__ . '/config/specifications.php');
Config::load('function-templates', __DIR__ . '/config/templates/function.php');
Config::load('site-templates', __DIR__ . '/config/templates/site.php');
Config::load('templates-function', __DIR__ . '/config/templates/function.php');
Config::load('templates-site', __DIR__ . '/config/templates/site.php');
/**
* New DB Filters

View file

@ -206,7 +206,7 @@ services:
appwrite-console:
<<: *x-logging
container_name: appwrite-console
image: appwrite/console:5.3.0-sites-rc.18
image: appwrite/console:5.3.0-sites-rc.20
restart: unless-stopped
networks:
- appwrite

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View file

@ -84,7 +84,7 @@ class Base extends Action
'providerCommitHash' => $commitDetails['commitHash'] ?? '',
'providerCommitAuthorUrl' => $authorUrl,
'providerCommitAuthor' => $commitDetails['commitAuthor'] ?? '',
'providerCommitMessage' => $commitDetails['commitMessage'] ?? '',
'providerCommitMessage' => mb_strimwidth($commitDetails['commitMessage'] ?? '', 0, 255, '...'),
'providerCommitUrl' => $commitDetails['commitUrl'] ?? '',
'providerBranch' => $providerBranch,
'providerRootDirectory' => $function->getAttribute('providerRootDirectory', ''),
@ -172,7 +172,7 @@ class Base extends Action
'providerCommitHash' => $commitDetails['commitHash'] ?? '',
'providerCommitAuthorUrl' => $authorUrl,
'providerCommitAuthor' => $commitDetails['commitAuthor'] ?? '',
'providerCommitMessage' => $commitDetails['commitMessage'] ?? '',
'providerCommitMessage' => mb_strimwidth($commitDetails['commitMessage'] ?? '', 0, 255, '...'),
'providerCommitUrl' => $commitDetails['commitUrl'] ?? '',
'providerBranch' => $providerBranch,
'providerRootDirectory' => $site->getAttribute('providerRootDirectory', ''),

View file

@ -49,7 +49,7 @@ class Get extends Action
],
contentType: ContentType::NONE,
))
->label('abuse-limit', 10)
->label('abuse-limit', 120)
->label('abuse-key', 'userId:{userId}, url:{url}')
->label('abuse-time', 60)
->param('value', '', new Text(256), 'Resource value.')

View file

@ -249,7 +249,6 @@ class Create extends Base
'errors' => '',
'logs' => '',
'duration' => 0.0,
'search' => implode(' ', [$functionId, $executionId]),
]);
$queueForEvents

View file

@ -19,7 +19,6 @@ use Utopia\Database\Validator\Query\Cursor;
use Utopia\Database\Validator\UID;
use Utopia\Platform\Action;
use Utopia\Platform\Scope\HTTP;
use Utopia\Validator\Text;
class XList extends Base
{
@ -55,13 +54,12 @@ class XList extends Base
))
->param('functionId', '', new UID(), 'Function ID.')
->param('queries', [], new Executions(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode(', ', Executions::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->inject('response')
->inject('dbForProject')
->callback([$this, 'action']);
}
public function action(string $functionId, array $queries, string $search, Response $response, Database $dbForProject)
public function action(string $functionId, array $queries, Response $response, Database $dbForProject)
{
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
@ -78,10 +76,6 @@ class XList extends Base
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
if (!empty($search)) {
$queries[] = Query::search('search', $search);
}
// Set internal queries
$queries[] = Query::equal('resourceInternalId', [$function->getInternalId()]);
$queries[] = Query::equal('resourceType', ['functions']);

View file

@ -97,6 +97,7 @@ class Update extends Base
Authorization::skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
$queries = [
Query::equal('trigger', 'manual'),
Query::equal("type", ["deployment"]),
Query::equal("deploymentResourceType", ["function"]),
Query::equal("deploymentResourceInternalId", [$function->getInternalId()]),

View file

@ -53,7 +53,7 @@ class Get extends Base
public function action(string $templateId, Response $response)
{
$templates = Config::getParam('function-templates', []);
$templates = Config::getParam('templates-function', []);
$filtered = \array_filter($templates, function ($template) use ($templateId) {
return $template['id'] === $templateId;

View file

@ -57,7 +57,7 @@ class XList extends Base
public function action(array $runtimes, array $usecases, int $limit, int $offset, Response $response)
{
$templates = Config::getParam('function-templates', []);
$templates = Config::getParam('templates-function', []);
if (!empty($runtimes)) {
$templates = \array_filter($templates, function ($template) use ($runtimes) {

View file

@ -493,8 +493,11 @@ class Builds extends Action
$vars[$var->getAttribute('key')] = $var->getAttribute('value', '');
}
// Some runtimes/frameworks can't compile with less memory than this
$minMemory = $resource->getCollection() === 'sites' ? 2048 : 1024;
$cpus = $spec['cpus'] ?? APP_COMPUTE_CPUS_DEFAULT;
$memory = max($spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT, 1024); // We have a minimum of 1024MB here because some runtimes can't compile with less memory than this.
$memory = max($spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT, $minMemory);
$timeout = (int) System::getEnv('_APP_COMPUTE_BUILD_TIMEOUT', 900);

View file

@ -18,7 +18,6 @@ use Utopia\Database\Validator\Query\Cursor;
use Utopia\Database\Validator\UID;
use Utopia\Platform\Action;
use Utopia\Platform\Scope\HTTP;
use Utopia\Validator\Text;
class XList extends Base
{
@ -54,13 +53,12 @@ class XList extends Base
))
->param('siteId', '', new UID(), 'Site ID.')
->param('queries', [], new Logs(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode(', ', Executions::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->inject('response')
->inject('dbForProject')
->callback([$this, 'action']);
}
public function action(string $siteId, array $queries, string $search, Response $response, Database $dbForProject)
public function action(string $siteId, array $queries, Response $response, Database $dbForProject)
{
$site = $dbForProject->getDocument('sites', $siteId);
@ -74,10 +72,6 @@ class XList extends Base
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
if (!empty($search)) {
$queries[] = Query::search('search', $search);
}
// Set internal queries
$queries[] = Query::equal('resourceInternalId', [$site->getInternalId()]);
$queries[] = Query::equal('resourceType', ['sites']);

View file

@ -86,6 +86,7 @@ class Update extends Base
])));
$queries = [
Query::equal('trigger', 'manual'),
Query::equal("type", ["deployment"]),
Query::equal("deploymentResourceType", ["site"]),
Query::equal("deploymentResourceInternalId", [$site->getInternalId()]),

View file

@ -98,8 +98,33 @@ class Update extends Base
->callback([$this, 'action']);
}
public function action(string $siteId, string $name, string $framework, bool $enabled, int $timeout, string $installCommand, string $buildCommand, string $outputDirectory, string $buildRuntime, string $adapter, string $fallbackFile, string $installationId, ?string $providerRepositoryId, string $providerBranch, bool $providerSilentMode, string $providerRootDirectory, string $specification, Request $request, Response $response, Database $dbForProject, Document $project, Event $queueForEvents, Build $queueForBuilds, Database $dbForPlatform, GitHub $github)
{
public function action(
string $siteId,
string $name,
string $framework,
bool $enabled,
int $timeout,
string $installCommand,
string $buildCommand,
string $outputDirectory,
string $buildRuntime,
string $adapter,
string $fallbackFile,
string $installationId,
?string $providerRepositoryId,
string $providerBranch,
bool $providerSilentMode,
string $providerRootDirectory,
string $specification,
Request $request,
Response $response,
Database $dbForProject,
Document $project,
Event $queueForEvents,
Build $queueForBuilds,
Database $dbForPlatform,
GitHub $github
) {
if (!empty($adapter)) {
$configFramework = Config::getParam('frameworks')[$framework] ?? [];
$adapters = \array_keys($configFramework['adapters'] ?? []);

View file

@ -53,7 +53,7 @@ class Get extends Base
public function action(string $templateId, Response $response)
{
$templates = Config::getParam('site-templates', []);
$templates = Config::getParam('templates-site', []);
$allowedTemplates = \array_filter($templates, function ($item) use ($templateId) {
return $item['key'] === $templateId;

View file

@ -57,7 +57,7 @@ class XList extends Base
public function action(array $frameworks, array $usecases, int $limit, int $offset, Response $response)
{
$templates = Config::getParam('site-templates', []);
$templates = Config::getParam('templates-site', []);
if (!empty($frameworks)) {
$templates = \array_filter($templates, function ($template) use ($frameworks) {

View file

@ -26,7 +26,7 @@ class Screenshot extends Action
public function action(string $templateId): void
{
$templates = Config::getParam('site-templates', []);
$templates = Config::getParam('templates-site', []);
$allowedTemplates = \array_filter($templates, function ($item) use ($templateId) {
return $item['key'] === $templateId;
@ -46,6 +46,10 @@ class Screenshot extends Action
// Register
$email = uniqid() . 'user@localhost.test';
$password = 'password';
Console::info("Email: {$email}");
Console::info("Pass: {$password}");
$user = $client->call(Client::METHOD_POST, '/account', [
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
@ -137,11 +141,11 @@ class Screenshot extends Action
'name' => $template["name"],
'framework' => $framework['key'],
'adapter' => $framework['adapter'],
'buildCommand' => $framework['buildCommand'],
'buildCommand' => $framework['buildCommand'] ?? '',
'buildRuntime' => $framework['buildRuntime'],
'fallbackFile' => $framework['fallbackFile'],
'installCommand' => $framework['installCommand'],
'outputDirectory' => $framework['outputDirectory'],
'fallbackFile' => $framework['fallbackFile'] ?? '',
'installCommand' => $framework['installCommand'] ?? '',
'outputDirectory' => $framework['outputDirectory'] ?? '',
'providerRootDirectory' => $framework['providerRootDirectory'],
'timeout' => 60
]);
@ -214,12 +218,17 @@ class Screenshot extends Action
$deploymentId = $deployment['body']['$id'];
// Await screenshot
$attempts = 50;
$attempts = 60; // 5 min
$sleep = 5;
$idLight = '';
$idDark = '';
if ($templateId === 'starter-for-react-native') {
Console::warning("React Native template takes long to build, increasing waiting time ...");
$attempts = 180; // 15 min
}
Console::log("Awaiting deployment (every $sleep seconds, $attempts attempts)");
for ($i = 0; $i < $attempts; $i++) {
@ -279,7 +288,6 @@ class Screenshot extends Action
foreach ($themes as $theme) {
$file = $client->call(Client::METHOD_GET, '/storage/buckets/screenshots/files/' . $theme['fileId'] . '/download', [
'x-appwrite-project' => 'console',
'x-appwrite-mode' => 'admin',
'cookie' => $cookieConsole
]);

View file

@ -271,7 +271,6 @@ class Functions extends Action
'errors' => $message,
'logs' => '',
'duration' => 0.0,
'search' => implode(' ', [$function->getId(), $executionId]),
]);
$execution = $dbForProject->createDocument('executions', $execution);
@ -407,7 +406,6 @@ class Functions extends Action
'errors' => '',
'logs' => '',
'duration' => 0.0,
'search' => implode(' ', [$functionId, $executionId]),
]);
$execution = $dbForProject->createDocument('executions', $execution);

View file

@ -5,6 +5,7 @@ namespace Appwrite\Utopia\Database\Validator\Queries;
class Logs extends Base
{
public const ALLOWED_ATTRIBUTES = [
'status',
'responseStatusCode',
'duration',
'requestMethod',

View file

@ -1802,7 +1802,7 @@ class SitesCustomServerTest extends Scope
$this->assertNotEmpty($deployment['body']['screenshotDark']);
$screenshotId = $deployment['body']['screenshotLight'];
$file = $this->client->call(Client::METHOD_GET, "/storage/buckets/screenshots/files/$screenshotId/view?project=console&mode=admin", array_merge([
$file = $this->client->call(Client::METHOD_GET, "/storage/buckets/screenshots/files/$screenshotId/view?project=console", array_merge([
], $this->getHeaders()));
$this->assertEquals(200, $file['headers']['status-code']);
@ -1814,7 +1814,7 @@ class SitesCustomServerTest extends Scope
$this->assertNotEmpty($screenshotHash);
$screenshotId = $deployment['body']['screenshotDark'];
$file = $this->client->call(Client::METHOD_GET, "/storage/buckets/screenshots/files/$screenshotId/view?project=console&mode=admin", array_merge([
$file = $this->client->call(Client::METHOD_GET, "/storage/buckets/screenshots/files/$screenshotId/view?project=console", array_merge([
], $this->getHeaders()));
$this->assertEquals(200, $file['headers']['status-code']);
@ -1827,10 +1827,10 @@ class SitesCustomServerTest extends Scope
$this->assertNotEquals($screenshotDarkHash, $screenshotHash);
$file = $this->client->call(Client::METHOD_GET, "/storage/buckets/screenshots/files/$screenshotId/view?project=console&mode=admin");
$file = $this->client->call(Client::METHOD_GET, "/storage/buckets/screenshots/files/$screenshotId/view?project=console");
$this->assertEquals(404, $file['headers']['status-code']);
$file = $this->client->call(Client::METHOD_GET, "/storage/buckets/screenshots/files/$screenshotId/view?project=console&mode=admin");
$file = $this->client->call(Client::METHOD_GET, "/storage/buckets/screenshots/files/$screenshotId/view?project=console");
$this->assertEquals(404, $file['headers']['status-code']);
$this->cleanupSite($siteId);