diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8fb3ac3518..ed9d7d1f19 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,57 +4,118 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +env: + IMAGE: appwrite-dev + CACHE_KEY: appwrite-dev-${{ github.event.pull_request.head.sha }} + on: [pull_request] + jobs: - tests: - name: Unit & E2E + setup: + name: Setup & Build Appwrite Image runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build Appwrite + uses: docker/build-push-action@v3 + with: + context: . + push: false + tags: ${{ env.IMAGE }} + load: true + cache-from: type=gha + cache-to: type=gha,mode=max + outputs: type=docker,dest=/tmp/${{ env.IMAGE }}.tar + build-args: | + DEBUG=false + TESTING=true + VERSION=dev + + - name: Cache Docker Image + uses: actions/cache@v3 + with: + key: ${{ env.CACHE_KEY }} + path: /tmp/${{ env.IMAGE }}.tar + + unit_test: + name: Unit Test + runs-on: ubuntu-latest + needs: setup steps: - - name: Checkout repository - uses: actions/checkout@v3 - with: - # We must fetch at least the immediate parents so that if this is - # a pull request then we can checkout the head. - fetch-depth: 2 - # Fetch submodules - submodules: recursive + - name: checkout + uses: actions/checkout@v2 - # If this run was triggered by a pull request event, then checkout - # the head of the pull request instead of the merge commit. - - run: git checkout HEAD^2 - if: ${{ github.event_name == 'pull_request' }} + - name: Load Cache + uses: actions/cache@v3 + with: + key: ${{ env.CACHE_KEY }} + path: /tmp/${{ env.IMAGE }}.tar + fail-on-cache-miss: true - # This is a separate action that sets up buildx runner - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + - name: Load and Start Appwrite + run: | + docker load --input /tmp/${{ env.IMAGE }}.tar + docker compose up -d + sleep 10 - - name: Build Appwrite - uses: docker/build-push-action@v3 - with: - context: . - push: false - tags: appwrite-dev - load: true - cache-from: type=gha - cache-to: type=gha,mode=max - build-args: | - DEBUG=false - TESTING=true - VERSION=dev + - name: Doctor + run: docker compose exec -T appwrite doctor - - name: Start Appwrite - run: | - docker compose up -d - sleep 30 + - name: Environment Variables + run: docker compose exec -T appwrite vars - - name: Doctor - run: | - docker compose logs appwrite - docker compose exec -T appwrite doctor + - name: Run Unit Tests + run: docker compose exec appwrite test /usr/src/code/tests/unit - - name: Environment Variables - run: docker compose exec -T appwrite vars + e2e_test: + name: E2E Test + runs-on: ubuntu-latest + needs: setup + strategy: + fail-fast: false + matrix: + service: + [ + Account, + Avatars, + Console, + Databases, + Functions, + GraphQL, + Health, + Locale, + Projects, + Realtime, + Storage, + Teams, + Users, + Webhooks, + ] - - name: Run Tests - run: docker compose exec -T appwrite test --debug \ No newline at end of file + steps: + - name: checkout + uses: actions/checkout@v3 + + - name: Load Cache + uses: actions/cache@v3 + with: + key: ${{ env.CACHE_KEY }} + path: /tmp/${{ env.IMAGE }}.tar + fail-on-cache-miss: true + + - name: Load and Start Appwrite + run: | + docker load --input /tmp/${{ env.IMAGE }}.tar + docker compose up -d + sleep 10 + + - name: Run ${{matrix.service}} Tests + run: docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 754fa9f80e..6570e2a620 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "app/console"] path = app/console url = https://github.com/appwrite/console - branch = 3.2.3 + branch = 3.2.4 diff --git a/.gitpod.yml b/.gitpod.yml index 4c081dd275..d740c467cb 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -8,7 +8,7 @@ tasks: command: | docker run --rm --interactive --tty \ --volume $PWD:/app \ - composer update \ + composer install \ --ignore-platform-reqs \ --optimize-autoloader \ --no-plugins \ diff --git a/CHANGES.md b/CHANGES.md index 33b41d35fa..ac405184df 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,8 @@ +# Version 1.4.7 + +## Fixes +- Fix missing body in async function execution in [#6988](https://github.com/appwrite/appwrite/pull/6988) + # Version 1.4.6 ## Changes diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 145ace7876..ccd61e742b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -89,7 +89,7 @@ $ git push origin [name_of_your_new_branch] To set up a working **development environment**, just fork the project git repository and install the backend and frontend dependencies using the proper package manager and create run the docker-compose stack. -> If you just want to install Appwrite for day-to-day use and not as a contributor, you can reference the [installation guide](https://github.com/appwrite/appwrite#installation), the [getting started guide](https://appwrite.io/docs/getting-started-for-web), or the main [README](README.md) file. +> If you just want to install Appwrite for day-to-day use and not as a contributor, you can reference the [installation guide](https://github.com/appwrite/appwrite#installation), the [getting started guide](https://appwrite.io/docs/quick-starts), or the main [README](README.md) file. ```bash git clone git@github.com:[YOUR_FORK_HERE]/appwrite.git @@ -454,7 +454,7 @@ From time to time, our team will add tutorials that will help contributors find - [Adding Support for a New OAuth2 Provider](./docs/tutorials/add-oauth2-provider.md) - [Appwrite Environment Variables](./docs/tutorials/add-environment-variable.md) -- [Running in Production](https://appwrite.io/docs/production) +- [Running in Production](https://appwrite.io/docs/advanced/self-hosting/production) - [Adding Storage Adapter](./docs/tutorials/add-storage-adapter.md) ## Other Ways to Help diff --git a/README-CN.md b/README-CN.md index 1328ef5cf4..1df799f7ef 100644 --- a/README-CN.md +++ b/README-CN.md @@ -66,7 +66,7 @@ docker run -it --rm \ --volume /var/run/docker.sock:/var/run/docker.sock \ --volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \ --entrypoint="install" \ - appwrite/appwrite:1.4.6 + appwrite/appwrite:1.4.7 ``` ### Windows @@ -78,7 +78,7 @@ docker run -it --rm ^ --volume //var/run/docker.sock:/var/run/docker.sock ^ --volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^ --entrypoint="install" ^ - appwrite/appwrite:1.4.6 + appwrite/appwrite:1.4.7 ``` #### PowerShell @@ -88,7 +88,7 @@ docker run -it --rm ` --volume /var/run/docker.sock:/var/run/docker.sock ` --volume ${pwd}/appwrite:/usr/src/code/appwrite:rw ` --entrypoint="install" ` - appwrite/appwrite:1.4.6 + appwrite/appwrite:1.4.7 ``` 运行后,可以在浏览器上访问 http://localhost 找到 Appwrite 控制台。在非 Linux 的本机主机上完成安装后,服务器可能需要几分钟才能启动。 diff --git a/README.md b/README.md index 40a4248d59..6503f6addf 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ Table of Contents: ## Installation -Appwrite is designed to run in a containerized environment. Running your server is as easy as running one command from your terminal. You can either run Appwrite on your localhost using docker-compose or on any other container orchestration tool, such as Kubernetes, Docker Swarm, or Rancher. +Appwrite is designed to run in a containerized environment. Running your server is as easy as running one command from your terminal. You can either run Appwrite on your localhost using docker-compose or on any other container orchestration tool, such as [Kubernetes](https://kubernetes.io/docs/home/), [Docker Swarm](https://docs.docker.com/engine/swarm/), or [Rancher](https://rancher.com/docs/). The easiest way to start running your Appwrite server is by running our docker-compose file. Before running the installation command, make sure you have [Docker](https://www.docker.com/products/docker-desktop) installed on your machine: @@ -76,7 +76,7 @@ docker run -it --rm \ --volume /var/run/docker.sock:/var/run/docker.sock \ --volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \ --entrypoint="install" \ - appwrite/appwrite:1.4.6 + appwrite/appwrite:1.4.7 ``` ### Windows @@ -88,7 +88,7 @@ docker run -it --rm ^ --volume //var/run/docker.sock:/var/run/docker.sock ^ --volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^ --entrypoint="install" ^ - appwrite/appwrite:1.4.6 + appwrite/appwrite:1.4.7 ``` #### PowerShell @@ -98,7 +98,7 @@ docker run -it --rm ` --volume /var/run/docker.sock:/var/run/docker.sock ` --volume ${pwd}/appwrite:/usr/src/code/appwrite:rw ` --entrypoint="install" ` - appwrite/appwrite:1.4.6 + appwrite/appwrite:1.4.7 ``` Once the Docker installation is complete, go to http://localhost to access the Appwrite console from your browser. Please note that on non-Linux native hosts, the server might take a few minutes to start after completing the installation. diff --git a/app/config/errors.php b/app/config/errors.php index 159c806175..28fb69d118 100644 --- a/app/config/errors.php +++ b/app/config/errors.php @@ -86,7 +86,7 @@ return [ Exception::GENERAL_PROTOCOL_UNSUPPORTED => [ 'name' => Exception::GENERAL_PROTOCOL_UNSUPPORTED, 'description' => 'The request cannot be fulfilled with the current protocol. Please check the value of the _APP_OPTIONS_FORCE_HTTPS environment variable.', - 'code' => 500, + 'code' => 426, ], Exception::GENERAL_CODES_DISABLED => [ 'name' => Exception::GENERAL_CODES_DISABLED, @@ -732,4 +732,21 @@ return [ 'description' => 'Migration is already in progress. You can check the status of the migration in your Appwrite Console\'s "Settings" > "Migrations".', 'code' => 409, ], + + /** Realtime */ + Exception::REALTIME_MESSAGE_FORMAT_INVALID => [ + 'name' => Exception::REALTIME_MESSAGE_FORMAT_INVALID, + 'description' => 'Message format is not valid.', + 'code' => 1003, + ], + Exception::REALTIME_POLICY_VIOLATION => [ + 'name' => Exception::REALTIME_POLICY_VIOLATION, + 'description' => 'Policy violation.', + 'code' => 1008, + ], + Exception::REALTIME_TOO_MANY_MESSAGES => [ + 'name' => Exception::REALTIME_TOO_MANY_MESSAGES, + 'description' => 'Too many messages.', + 'code' => 1013, + ], ]; diff --git a/app/init.php b/app/init.php index 16eceb1eaf..86e4790a30 100644 --- a/app/init.php +++ b/app/init.php @@ -110,7 +110,7 @@ const APP_KEY_ACCCESS = 24 * 60 * 60; // 24 hours const APP_USER_ACCCESS = 24 * 60 * 60; // 24 hours const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours const APP_CACHE_BUSTER = 514; -const APP_VERSION_STABLE = '1.4.6'; +const APP_VERSION_STABLE = '1.4.7'; const APP_DATABASE_ATTRIBUTE_EMAIL = 'email'; const APP_DATABASE_ATTRIBUTE_ENUM = 'enum'; const APP_DATABASE_ATTRIBUTE_IP = 'ip'; diff --git a/app/realtime.php b/app/realtime.php index 25b0532b42..42fa43f575 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -1,8 +1,10 @@ get('logger'); - if ($logger) { + if ($logger && !$error instanceof Exception) { $version = App::getEnv('_APP_VERSION', 'UNKNOWN'); $log = new Log(); $log->setNamespace("realtime"); - $log->setServer(\gethostname()); + $log->setServer(gethostname()); $log->setVersion($version); $log->setType(Log::TYPE_ERROR); $log->setMessage($error->getMessage()); @@ -182,7 +186,7 @@ $server->onStart(function () use ($stats, $register, $containerId, &$statsDocume $statsDocument = Authorization::skip(fn () => $database->createDocument('realtime', $document)); break; - } catch (\Throwable $th) { + } catch (Throwable) { Console::warning("Collection not ready. Retrying connection ({$attempts})..."); sleep(DATABASE_RECONNECT_SLEEP); } @@ -210,7 +214,7 @@ $server->onStart(function () use ($stats, $register, $containerId, &$statsDocume ->setAttribute('value', json_encode($payload)); Authorization::skip(fn () => $database->updateDocument('realtime', $statsDocument->getId(), $statsDocument)); - } catch (\Throwable $th) { + } catch (Throwable $th) { call_user_func($logError, $th, "updateWorkerDocument"); } finally { $register->get('pools')->reclaim(); @@ -362,7 +366,7 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats, $stats->incr($event['project'], 'messages', $num); } }); - } catch (\Throwable $th) { + } catch (Throwable $th) { call_user_func($logError, $th, "pubSubConnection"); Console::error('Pub/sub error: ' . $th->getMessage()); @@ -389,19 +393,19 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, App::setResource('response', fn() => $response); try { - /** @var \Utopia\Database\Document $project */ + /** @var Document $project */ $project = $app->getResource('project'); /* * Project Check */ if (empty($project->getId())) { - throw new Exception('Missing or unknown project ID', 1008); + throw new Exception(Exception::REALTIME_POLICY_VIOLATION, 'Missing or unknown project ID'); } $dbForProject = getProjectDB($project); - $console = $app->getResource('console'); /** @var \Utopia\Database\Document $console */ - $user = $app->getResource('user'); /** @var \Utopia\Database\Document $user */ + $console = $app->getResource('console'); /** @var Document $console */ + $user = $app->getResource('user'); /** @var Document $user */ /* * Abuse Check @@ -416,7 +420,7 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, $abuse = new Abuse($timeLimit); if (App::getEnv('_APP_OPTIONS_ABUSE', 'enabled') === 'enabled' && $abuse->check()) { - throw new Exception('Too many requests', 1013); + throw new Exception(Exception::REALTIME_TOO_MANY_MESSAGES, 'Too many requests'); } /* @@ -425,10 +429,10 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, * Skip this check for non-web platforms which are not required to send an origin header. */ $origin = $request->getOrigin(); - $originValidator = new Origin(\array_merge($project->getAttribute('platforms', []), $console->getAttribute('platforms', []))); + $originValidator = new Origin(array_merge($project->getAttribute('platforms', []), $console->getAttribute('platforms', []))); if (!$originValidator->isValid($origin) && $project->getId() !== 'console') { - throw new Exception($originValidator->getDescription(), 1008); + throw new Exception(Exception::REALTIME_POLICY_VIOLATION, $originValidator->getDescription()); } $roles = Auth::getRoles($user); @@ -439,7 +443,7 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, * Channels Check */ if (empty($channels)) { - throw new Exception('Missing channels', 1008); + throw new Exception(Exception::REALTIME_POLICY_VIOLATION, 'Missing channels'); } $realtime->subscribe($project->getId(), $connection, $roles, $channels); @@ -460,7 +464,7 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, ]); $stats->incr($project->getId(), 'connections'); $stats->incr($project->getId(), 'connectionsTotal'); - } catch (\Throwable $th) { + } catch (Throwable $th) { call_user_func($logError, $th, "initServer"); $response = [ @@ -486,7 +490,6 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server, $server->onMessage(function (int $connection, string $message) use ($server, $register, $realtime, $containerId) { try { - $app = new App('UTC'); $response = new Response(new SwooleResponse()); $projectId = $realtime->connections[$connection]['projectId']; $database = getConsoleDB(); @@ -494,6 +497,8 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re if ($projectId !== 'console') { $project = Authorization::skip(fn() => $database->getDocument('projects', $projectId)); $database = getProjectDB($project); + } else { + $project = null; } /* @@ -510,22 +515,22 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re $abuse = new Abuse($timeLimit); if ($abuse->check() && App::getEnv('_APP_OPTIONS_ABUSE', 'enabled') === 'enabled') { - throw new Exception('Too many messages', 1013); + throw new Exception(Exception::REALTIME_TOO_MANY_MESSAGES, 'Too many messages.'); } $message = json_decode($message, true); if (is_null($message) || (!array_key_exists('type', $message) && !array_key_exists('data', $message))) { - throw new Exception('Message format is not valid.', 1003); + throw new Exception(Exception::REALTIME_MESSAGE_FORMAT_INVALID, 'Message format is not valid.'); } switch ($message['type']) { - /** + /** * This type is used to authenticate. */ case 'authentication': if (!array_key_exists('session', $message['data'])) { - throw new Exception('Payload is not valid.', 1003); + throw new Exception(Exception::REALTIME_MESSAGE_FORMAT_INVALID, 'Payload is not valid.'); } $session = Auth::decodeSession($message['data']['session']); @@ -540,7 +545,7 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re || !Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret, $authDuration) // Validate user has valid login token ) { // cookie not valid - throw new Exception('Session is not valid.', 1003); + throw new Exception(Exception::REALTIME_MESSAGE_FORMAT_INVALID, 'Session is not valid.'); } $roles = Auth::getRoles($user); @@ -560,9 +565,9 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re break; default: - throw new Exception('Message type is not valid.', 1003); + throw new Exception(Exception::REALTIME_MESSAGE_FORMAT_INVALID, 'Message type is not valid.'); } - } catch (\Throwable $th) { + } catch (Throwable $th) { $response = [ 'type' => 'error', 'data' => [ diff --git a/app/worker.php b/app/worker.php index 8aa52ab931..32a8b9804e 100644 --- a/app/worker.php +++ b/app/worker.php @@ -36,7 +36,6 @@ use Utopia\Queue\Connection; Authorization::disable(); Runtime::enableCoroutine(SWOOLE_HOOK_ALL); - Server::setResource('register', fn () => $register); Server::setResource('dbForConsole', function (Cache $cache, Registry $register) { diff --git a/composer.json b/composer.json index 3ad480b88e..8475245faa 100644 --- a/composer.json +++ b/composer.json @@ -64,7 +64,7 @@ "utopia-php/preloader": "0.2.*", "utopia-php/queue": "0.5.*", "utopia-php/registry": "0.5.*", - "utopia-php/storage": "0.17.*", + "utopia-php/storage": "0.18.*", "utopia-php/swoole": "0.5.*", "utopia-php/vcs": "0.6.*", "utopia-php/websocket": "0.1.*", diff --git a/composer.lock b/composer.lock index ceb9a4770e..aa16f1b5d0 100644 --- a/composer.lock +++ b/composer.lock @@ -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": "e1face7cebc5b79288c93a04e1f98521", + "content-hash": "06c2610579f319495ea7d2d28f42d376", "packages": [ { "name": "adhocore/jwt", @@ -1906,16 +1906,16 @@ }, { "name": "utopia-php/database", - "version": "0.44.2", + "version": "0.44.4", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "591cadbc2c622a3304aae9a16ebfdbe75ef33a06" + "reference": "b0c3fd8ecfedc3646d7780f2d6b38955a66baf48" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/591cadbc2c622a3304aae9a16ebfdbe75ef33a06", - "reference": "591cadbc2c622a3304aae9a16ebfdbe75ef33a06", + "url": "https://api.github.com/repos/utopia-php/database/zipball/b0c3fd8ecfedc3646d7780f2d6b38955a66baf48", + "reference": "b0c3fd8ecfedc3646d7780f2d6b38955a66baf48", "shasum": "" }, "require": { @@ -1928,7 +1928,7 @@ }, "require-dev": { "fakerphp/faker": "^1.14", - "laravel/pint": "1.4.*", + "laravel/pint": "1.13.*", "pcov/clobber": "^2.0", "phpstan/phpstan": "1.10.*", "phpunit/phpunit": "^9.4", @@ -1956,9 +1956,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.44.2" + "source": "https://github.com/utopia-php/database/tree/0.44.4" }, - "time": "2023-10-19T07:39:00+00:00" + "time": "2023-10-26T07:08:12+00:00" }, { "name": "utopia-php/domains", @@ -2742,16 +2742,16 @@ }, { "name": "utopia-php/storage", - "version": "0.17.0", + "version": "0.18.1", "source": { "type": "git", "url": "https://github.com/utopia-php/storage.git", - "reference": "efec5376c02d3d8330f1beb1469e6d6e313e21ee" + "reference": "983e6dee137012f9f57f126d3c79aab54e4e8824" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/efec5376c02d3d8330f1beb1469e6d6e313e21ee", - "reference": "efec5376c02d3d8330f1beb1469e6d6e313e21ee", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/983e6dee137012f9f57f126d3c79aab54e4e8824", + "reference": "983e6dee137012f9f57f126d3c79aab54e4e8824", "shasum": "" }, "require": { @@ -2791,9 +2791,9 @@ ], "support": { "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.17.0" + "source": "https://github.com/utopia-php/storage/tree/0.18.1" }, - "time": "2023-08-21T11:28:36+00:00" + "time": "2023-10-24T14:44:19+00:00" }, { "name": "utopia-php/swoole", @@ -5822,5 +5822,5 @@ "platform-overrides": { "php": "8.0" }, - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/src/Appwrite/Extend/Exception.php b/src/Appwrite/Extend/Exception.php index c7ff2e73c0..dc56932cde 100644 --- a/src/Appwrite/Extend/Exception.php +++ b/src/Appwrite/Extend/Exception.php @@ -225,8 +225,13 @@ class Exception extends \Exception public const MIGRATION_ALREADY_EXISTS = 'migration_already_exists'; public const MIGRATION_IN_PROGRESS = 'migration_in_progress'; - protected $type = ''; - protected $errors = []; + /** Realtime */ + public const REALTIME_MESSAGE_FORMAT_INVALID = 'realtime_message_format_invalid'; + public const REALTIME_TOO_MANY_MESSAGES = 'realtime_too_many_messages'; + public const REALTIME_POLICY_VIOLATION = 'realtime_policy_violation'; + + protected string $type = ''; + protected array $errors = []; public function __construct(string $type = Exception::GENERAL_UNKNOWN, string $message = null, int $code = null, \Throwable $previous = null) { diff --git a/src/Appwrite/Migration/Migration.php b/src/Appwrite/Migration/Migration.php index 15098793a9..964aef66e5 100644 --- a/src/Appwrite/Migration/Migration.php +++ b/src/Appwrite/Migration/Migration.php @@ -71,6 +71,7 @@ abstract class Migration '1.4.4' => 'V19', '1.4.5' => 'V19', '1.4.6' => 'V19', + '1.4.7' => 'V19', ]; /** diff --git a/src/Appwrite/Platform/Workers/Functions.php b/src/Appwrite/Platform/Workers/Functions.php index 6b7b5efe03..7a6cfe115f 100644 --- a/src/Appwrite/Platform/Workers/Functions.php +++ b/src/Appwrite/Platform/Workers/Functions.php @@ -77,7 +77,7 @@ class Functions extends Action $type = $payload['type'] ?? ''; $events = $payload['events'] ?? []; - $data = $payload['data'] ?? ''; + $data = $payload['body'] ?? ''; $eventData = $payload['payload'] ?? ''; $project = new Document($payload['project'] ?? []); $function = new Document($payload['function'] ?? []); diff --git a/tests/e2e/Services/GraphQL/Base.php b/tests/e2e/Services/GraphQL/Base.php index 3a4b88e2c2..f705e8d77b 100644 --- a/tests/e2e/Services/GraphQL/Base.php +++ b/tests/e2e/Services/GraphQL/Base.php @@ -2,6 +2,8 @@ namespace Tests\E2E\Services\GraphQL; +use Utopia\CLI\Console; + trait Base { // Databases @@ -1933,4 +1935,13 @@ trait Base throw new \InvalidArgumentException('Invalid query type'); } + + // Function-related methods + protected string $stdout = ''; + protected string $stderr = ''; + + protected function packageCode($folder) + { + Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr); + } } diff --git a/tests/e2e/Services/GraphQL/FunctionsClientTest.php b/tests/e2e/Services/GraphQL/FunctionsClientTest.php index 363f7a0fb1..3f0ee1966a 100644 --- a/tests/e2e/Services/GraphQL/FunctionsClientTest.php +++ b/tests/e2e/Services/GraphQL/FunctionsClientTest.php @@ -82,7 +82,11 @@ class FunctionsClientTest extends Scope { $projectId = $this->getProject()['$id']; $query = $this->getQuery(self::$CREATE_DEPLOYMENT); - $code = realpath(__DIR__ . '/../../../resources/functions') . "/php/code.tar.gz"; + + $folder = 'php'; + $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; + $this->packageCode($folder); + $gqlPayload = [ 'operations' => \json_encode([ 'query' => $query, diff --git a/tests/e2e/Services/GraphQL/FunctionsServerTest.php b/tests/e2e/Services/GraphQL/FunctionsServerTest.php index 49a8fd61f2..25a671fa1c 100644 --- a/tests/e2e/Services/GraphQL/FunctionsServerTest.php +++ b/tests/e2e/Services/GraphQL/FunctionsServerTest.php @@ -81,7 +81,11 @@ class FunctionsServerTest extends Scope { $projectId = $this->getProject()['$id']; $query = $this->getQuery(self::$CREATE_DEPLOYMENT); - $code = realpath(__DIR__ . '/../../../resources/functions') . "/php/code.tar.gz"; + + $folder = 'php'; + $code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz"; + $this->packageCode($folder); + $gqlPayload = [ 'operations' => \json_encode([ 'query' => $query,