mirror of
https://github.com/appwrite/appwrite
synced 2026-05-23 08:58:35 +00:00
Merge pull request #9804 from appwrite/fix-function-create-compatibility
Fix: backwards compatibility for function creation
This commit is contained in:
commit
908d80e8d9
6 changed files with 211 additions and 20 deletions
|
|
@ -67,7 +67,7 @@
|
|||
"utopia-php/platform": "0.7.*",
|
||||
"utopia-php/pools": "0.8.*",
|
||||
"utopia-php/preloader": "0.2.*",
|
||||
"utopia-php/queue": "0.9.*",
|
||||
"utopia-php/queue": "0.10.*",
|
||||
"utopia-php/registry": "0.5.*",
|
||||
"utopia-php/storage": "0.18.*",
|
||||
"utopia-php/swoole": "0.8.*",
|
||||
|
|
|
|||
37
composer.lock
generated
37
composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "735023e2b70ce47fe65985f195b257bd",
|
||||
"content-hash": "b6f5295db11727cb4e88e702dc97809d",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
|
|
@ -4104,16 +4104,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/platform",
|
||||
"version": "0.7.4",
|
||||
"version": "0.7.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/platform.git",
|
||||
"reference": "a5b93d8177702ec458c3af9137663133c012b71b"
|
||||
"reference": "6bc7fbb43ec2b7f9ee5bdef5d4b5e4a81860950b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/platform/zipball/a5b93d8177702ec458c3af9137663133c012b71b",
|
||||
"reference": "a5b93d8177702ec458c3af9137663133c012b71b",
|
||||
"url": "https://api.github.com/repos/utopia-php/platform/zipball/6bc7fbb43ec2b7f9ee5bdef5d4b5e4a81860950b",
|
||||
"reference": "6bc7fbb43ec2b7f9ee5bdef5d4b5e4a81860950b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -4122,11 +4122,11 @@
|
|||
"php": ">=8.0",
|
||||
"utopia-php/cli": "0.15.*",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/queue": "0.9.*"
|
||||
"utopia-php/queue": "0.10.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.2.*",
|
||||
"phpunit/phpunit": "^9.3"
|
||||
"laravel/pint": "1.*",
|
||||
"phpunit/phpunit": "9.*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
|
|
@ -4148,9 +4148,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/platform/issues",
|
||||
"source": "https://github.com/utopia-php/platform/tree/0.7.4"
|
||||
"source": "https://github.com/utopia-php/platform/tree/0.7.6"
|
||||
},
|
||||
"time": "2025-03-13T13:00:12+00:00"
|
||||
"time": "2025-05-18T20:31:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/pools",
|
||||
|
|
@ -4259,16 +4259,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/queue",
|
||||
"version": "0.9.1",
|
||||
"version": "0.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/queue.git",
|
||||
"reference": "32b6f84c55aae761db5a5ae76cc91ca8dbc8bc32"
|
||||
"reference": "0eccc559168ea72241c39a4c482d868314666be1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/queue/zipball/32b6f84c55aae761db5a5ae76cc91ca8dbc8bc32",
|
||||
"reference": "32b6f84c55aae761db5a5ae76cc91ca8dbc8bc32",
|
||||
"url": "https://api.github.com/repos/utopia-php/queue/zipball/0eccc559168ea72241c39a4c482d868314666be1",
|
||||
"reference": "0eccc559168ea72241c39a4c482d868314666be1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -4277,6 +4277,7 @@
|
|||
"utopia-php/cli": "0.15.*",
|
||||
"utopia-php/fetch": "0.4.*",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/pools": "0.8.*",
|
||||
"utopia-php/telemetry": "0.1.*"
|
||||
},
|
||||
"require-dev": {
|
||||
|
|
@ -4318,9 +4319,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/queue/issues",
|
||||
"source": "https://github.com/utopia-php/queue/tree/0.9.1"
|
||||
"source": "https://github.com/utopia-php/queue/tree/0.10.0"
|
||||
},
|
||||
"time": "2025-03-28T19:49:36+00:00"
|
||||
"time": "2025-04-17T12:15:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/registry",
|
||||
|
|
@ -8240,7 +8241,7 @@
|
|||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {},
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
|
|
@ -8264,5 +8265,5 @@
|
|||
"platform-overrides": {
|
||||
"php": "8.3"
|
||||
},
|
||||
"plugin-api-version": "2.6.0"
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,12 @@
|
|||
|
||||
namespace Appwrite\Platform\Modules\Functions\Http\Functions;
|
||||
|
||||
use Appwrite\Event\Build;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Func;
|
||||
use Appwrite\Event\Realtime;
|
||||
use Appwrite\Event\Validator\FunctionEvent;
|
||||
use Appwrite\Event\Webhook;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Platform\Modules\Compute\Base;
|
||||
use Appwrite\Platform\Modules\Compute\Validator\Specification;
|
||||
|
|
@ -13,6 +17,7 @@ use Appwrite\SDK\Response as SDKResponse;
|
|||
use Appwrite\Task\Validator\Cron;
|
||||
use Appwrite\Utopia\Database\Validator\CustomId;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Utopia\Response\Model\Rule;
|
||||
use Utopia\Abuse\Abuse;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
|
|
@ -25,12 +30,14 @@ use Utopia\Database\Validator\Authorization;
|
|||
use Utopia\Database\Validator\Roles;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\Request;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\WhiteList;
|
||||
use Utopia\VCS\Adapter\Git\GitHub;
|
||||
|
||||
class Create extends Base
|
||||
{
|
||||
|
|
@ -91,12 +98,22 @@ class Create extends Base
|
|||
System::getEnv('_APP_COMPUTE_CPUS', 0),
|
||||
System::getEnv('_APP_COMPUTE_MEMORY', 0)
|
||||
), 'Runtime specification for the function and builds.', true, ['plan'])
|
||||
->param('templateRepository', '', new Text(128, 0), 'Repository name of the template.', true, deprecated: true)
|
||||
->param('templateOwner', '', new Text(128, 0), 'The name of the owner of the template.', true, deprecated: true)
|
||||
->param('templateRootDirectory', '', new Text(128, 0), 'Path to function code in the template repo.', true, deprecated: true)
|
||||
->param('templateVersion', '', new Text(128, 0), 'Version (tag) for the repo linked to the function template.', true, deprecated: true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('timelimit')
|
||||
->inject('project')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForBuilds')
|
||||
->inject('queueForRealtime')
|
||||
->inject('queueForWebhooks')
|
||||
->inject('queueForFunctions')
|
||||
->inject('dbForPlatform')
|
||||
->inject('request')
|
||||
->inject('gitHub')
|
||||
->callback([$this, 'action']);
|
||||
}
|
||||
|
||||
|
|
@ -119,12 +136,22 @@ class Create extends Base
|
|||
bool $providerSilentMode,
|
||||
string $providerRootDirectory,
|
||||
string $specification,
|
||||
string $templateRepository,
|
||||
string $templateOwner,
|
||||
string $templateRootDirectory,
|
||||
string $templateVersion,
|
||||
Response $response,
|
||||
Database $dbForProject,
|
||||
callable $timelimit,
|
||||
Document $project,
|
||||
Event $queueForEvents,
|
||||
Database $dbForPlatform
|
||||
Build $queueForBuilds,
|
||||
Realtime $queueForRealtime,
|
||||
Webhook $queueForWebhooks,
|
||||
Func $queueForFunctions,
|
||||
Database $dbForPlatform,
|
||||
Request $request,
|
||||
GitHub $github
|
||||
) {
|
||||
|
||||
// Temporary abuse check
|
||||
|
|
@ -251,6 +278,136 @@ class Create extends Base
|
|||
|
||||
$function = $dbForProject->updateDocument('functions', $function->getId(), $function);
|
||||
|
||||
// Backwards compatibility with 1.6 behaviour
|
||||
$requestFormat = $request->getHeader('x-appwrite-response-format', System::getEnv('_APP_SYSTEM_RESPONSE_FORMAT', ''));
|
||||
if ($requestFormat && version_compare($requestFormat, '1.7.0', '<')) {
|
||||
// build from template
|
||||
$template = new Document([]);
|
||||
if (
|
||||
!empty($templateRepository)
|
||||
&& !empty($templateOwner)
|
||||
&& !empty($templateRootDirectory)
|
||||
&& !empty($templateVersion)
|
||||
) {
|
||||
$template->setAttribute('repositoryName', $templateRepository)
|
||||
->setAttribute('ownerName', $templateOwner)
|
||||
->setAttribute('rootDirectory', $templateRootDirectory)
|
||||
->setAttribute('version', $templateVersion);
|
||||
}
|
||||
|
||||
if (!empty($providerRepositoryId)) {
|
||||
// Deploy VCS
|
||||
$template = new Document();
|
||||
|
||||
$installation = $dbForPlatform->getDocument('installations', $function->getAttribute('installationId'));
|
||||
$deployment = $this->redeployVcsFunction(
|
||||
request: $request,
|
||||
function: $function,
|
||||
project: $project,
|
||||
installation: $installation,
|
||||
dbForProject: $dbForProject,
|
||||
queueForBuilds: $queueForBuilds,
|
||||
template: $template,
|
||||
github: $github,
|
||||
activate: true,
|
||||
reference: $providerBranch,
|
||||
referenceType: 'branch'
|
||||
);
|
||||
|
||||
$function = $function
|
||||
->setAttribute('latestDeploymentId', $deployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
|
||||
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument('functions', $function->getId(), $function);
|
||||
} elseif (!$template->isEmpty()) {
|
||||
// Deploy non-VCS from template
|
||||
$deploymentId = ID::unique();
|
||||
$deployment = $dbForProject->createDocument('deployments', new Document([
|
||||
'$id' => $deploymentId,
|
||||
'$permissions' => [
|
||||
Permission::read(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
'resourceId' => $function->getId(),
|
||||
'resourceInternalId' => $function->getInternalId(),
|
||||
'resourceType' => 'functions',
|
||||
'entrypoint' => $function->getAttribute('entrypoint', ''),
|
||||
'buildCommands' => $function->getAttribute('commands', ''),
|
||||
'type' => 'manual',
|
||||
'activate' => true,
|
||||
]));
|
||||
|
||||
$function = $function
|
||||
->setAttribute('latestDeploymentId', $deployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
|
||||
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument('functions', $function->getId(), $function);
|
||||
|
||||
$queueForBuilds
|
||||
->setType(BUILD_TYPE_DEPLOYMENT)
|
||||
->setResource($function)
|
||||
->setDeployment($deployment)
|
||||
->setTemplate($template);
|
||||
}
|
||||
|
||||
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
|
||||
if (!empty($functionsDomain)) {
|
||||
$routeSubdomain = ID::unique();
|
||||
$domain = "{$routeSubdomain}.{$functionsDomain}";
|
||||
// TODO: @christyjacob remove once we migrate the rules in 1.7.x
|
||||
$ruleId = System::getEnv('_APP_RULES_FORMAT') === 'md5' ? md5($domain) : ID::unique();
|
||||
|
||||
$rule = Authorization::skip(
|
||||
fn () => $dbForPlatform->createDocument('rules', new Document([
|
||||
'$id' => $ruleId,
|
||||
'projectId' => $project->getId(),
|
||||
'projectInternalId' => $project->getInternalId(),
|
||||
'domain' => $domain,
|
||||
'status' => 'verified',
|
||||
'type' => 'deployment',
|
||||
'trigger' => 'manual',
|
||||
'deploymentId' => !isset($deployment) || $deployment->isEmpty() ? '' : $deployment->getId(),
|
||||
'deploymentInternalId' => !isset($deployment) || $deployment->isEmpty() ? '' : $deployment->getInternalId(),
|
||||
'deploymentResourceType' => 'function',
|
||||
'deploymentResourceId' => $function->getId(),
|
||||
'deploymentResourceInternalId' => $function->getInternalId(),
|
||||
'deploymentVcsProviderBranch' => '',
|
||||
'certificateId' => '',
|
||||
'search' => implode(' ', [$ruleId, $domain]),
|
||||
'owner' => 'Appwrite',
|
||||
'region' => $project->getAttribute('region')
|
||||
]))
|
||||
);
|
||||
|
||||
$ruleModel = new Rule();
|
||||
$ruleCreate =
|
||||
$queueForEvents
|
||||
->setProject($project)
|
||||
->setEvent('rules.[ruleId].create')
|
||||
->setParam('ruleId', $rule->getId())
|
||||
->setPayload($rule->getArrayCopy(array_keys($ruleModel->getRules())));
|
||||
|
||||
/** Trigger Webhook */
|
||||
$queueForWebhooks
|
||||
->from($ruleCreate)
|
||||
->trigger();
|
||||
|
||||
/** Trigger Functions */
|
||||
$queueForFunctions
|
||||
->from($ruleCreate)
|
||||
->trigger();
|
||||
|
||||
/** Trigger Realtime Events */
|
||||
$queueForRealtime
|
||||
->from($ruleCreate)
|
||||
->setSubscribers(['console', $project->getId()])
|
||||
->trigger();
|
||||
}
|
||||
}
|
||||
|
||||
$queueForEvents->setParam('functionId', $function->getId());
|
||||
|
||||
$response
|
||||
|
|
|
|||
|
|
@ -309,6 +309,10 @@ class OpenAPI3 extends Format
|
|||
$bodyRequired = [];
|
||||
|
||||
foreach ($route->getParams() as $name => $param) { // Set params
|
||||
if ($param['deprecated']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var \Utopia\Validator $validator
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -314,6 +314,10 @@ class Swagger2 extends Format
|
|||
);
|
||||
|
||||
foreach ($parameters as $name => $param) { // Set params
|
||||
if ($param['deprecated']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @var Validator $validator */
|
||||
$validator = (\is_callable($param['validator']))
|
||||
? ($param['validator'])(...$this->app->getResources($param['injections']))
|
||||
|
|
|
|||
|
|
@ -10,6 +10,16 @@ class V19 extends Filter
|
|||
public function parse(array $content, string $model): array
|
||||
{
|
||||
switch ($model) {
|
||||
case 'functions.list':
|
||||
$content = $this->convertQueryAttribute($content, 'deployment', 'deploymentId');
|
||||
break;
|
||||
case 'functions.listDeployments':
|
||||
$content = $this->convertQueryAttribute($content, 'size', 'deploymentSize');
|
||||
break;
|
||||
case 'proxy.listRules':
|
||||
$content = $this->convertQueryAttribute($content, 'resourceType', 'deploymentResourceType');
|
||||
$content = $this->convertQueryAttribute($content, 'resourceId', 'deploymentResourceId');
|
||||
break;
|
||||
case 'functions.create':
|
||||
unset($content['templateRepository']);
|
||||
unset($content['templateOwner']);
|
||||
|
|
@ -28,4 +38,19 @@ class V19 extends Filter
|
|||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function convertQueryAttribute(array $content, string $old, string $new)
|
||||
{
|
||||
if (isset($content['queries']) && is_array($content['queries'])) {
|
||||
foreach ($content['queries'] as $index => $query) {
|
||||
$query = \json_decode($query, true);
|
||||
if (($query['attribute'] ?? '') === $old) {
|
||||
$query['attribute'] = $new;
|
||||
}
|
||||
$content['queries'][$index] = \json_encode($query);
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue