1
0
Fork 0
mirror of synced 2024-06-26 10:10:57 +12:00

Merge pull request #7605 from appwrite/feat-cancel-build-deployment

Added cancel build endpoint
This commit is contained in:
Christy Jacob 2024-06-13 19:06:03 +05:30 committed by GitHub
commit 83d60612f2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 254 additions and 76 deletions

View file

@ -541,6 +541,11 @@ return [
'description' => 'Build with the requested ID is already in progress. Please wait before you can retry.',
'code' => 400,
],
Exception::BUILD_ALREADY_COMPLETED => [
'name' => Exception::BUILD_ALREADY_COMPLETED,
'description' => 'Build with the requested ID is already completed and cannot be canceled.',
'code' => 400,
],
/** Deployments */
Exception::DEPLOYMENT_NOT_FOUND => [

View file

@ -1444,7 +1444,6 @@ App::post('/v1/functions/:functionId/deployments/:deploymentId/build')
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'createBuild')
->label('sdk.description', '/docs/references/functions/create-build.md')
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
->label('sdk.response.model', Response::MODEL_NONE)
->param('functionId', '', new UID(), 'Function ID.')
@ -1462,7 +1461,6 @@ App::post('/v1/functions/:functionId/deployments/:deploymentId/build')
if ($function->isEmpty()) {
throw new Exception(Exception::FUNCTION_NOT_FOUND);
}
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
if ($deployment->isEmpty()) {
@ -1493,6 +1491,86 @@ App::post('/v1/functions/:functionId/deployments/:deploymentId/build')
$response->noContent();
});
App::patch('/v1/functions/:functionId/deployments/:deploymentId/build')
->groups(['api', 'functions'])
->desc('Cancel deployment')
->label('scope', 'functions.write')
->label('audits.event', 'deployment.update')
->label('audits.resource', 'function/{request.functionId}')
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'updateDeploymentBuild')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_BUILD)
->param('functionId', '', new UID(), 'Function ID.')
->param('deploymentId', '', new UID(), 'Deployment ID.')
->inject('response')
->inject('dbForProject')
->inject('project')
->inject('queueForEvents')
->action(function (string $functionId, string $deploymentId, Response $response, Database $dbForProject, Document $project, Event $queueForEvents) {
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
throw new Exception(Exception::FUNCTION_NOT_FOUND);
}
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
if ($deployment->isEmpty()) {
throw new Exception(Exception::DEPLOYMENT_NOT_FOUND);
}
$build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', '')));
if ($build->isEmpty()) {
$buildId = ID::unique();
$build = $dbForProject->createDocument('builds', new Document([
'$id' => $buildId,
'$permissions' => [],
'startTime' => DateTime::now(),
'deploymentInternalId' => $deployment->getInternalId(),
'deploymentId' => $deployment->getId(),
'status' => 'canceled',
'path' => '',
'runtime' => $function->getAttribute('runtime'),
'source' => $deployment->getAttribute('path', ''),
'sourceType' => '',
'logs' => '',
'duration' => 0,
'size' => 0
]));
$deployment->setAttribute('buildId', $build->getId());
$deployment->setAttribute('buildInternalId', $build->getInternalId());
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
} else {
if (\in_array($build->getAttribute('status'), ['ready', 'failed'])) {
throw new Exception(Exception::BUILD_ALREADY_COMPLETED);
}
$startTime = new \DateTime($build->getAttribute('startTime'));
$endTime = new \DateTime('now');
$duration = $endTime->getTimestamp() - $startTime->getTimestamp();
$build = $dbForProject->updateDocument('builds', $build->getId(), $build->setAttributes([
'endTime' => DateTime::now(),
'duration' => $duration,
'status' => 'canceled'
]));
}
$executor = new Executor(App::getEnv('_APP_EXECUTOR_HOST'));
$deleteBuild = $executor->deleteRuntime($project->getId(), $deploymentId . "-build");
$queueForEvents
->setParam('functionId', $function->getId())
->setParam('deploymentId', $deployment->getId());
$response->dynamic($build, Response::MODEL_BUILD);
});
App::post('/v1/functions/:functionId/executions')
->groups(['api', 'functions'])
->desc('Create execution')

121
composer.lock generated
View file

@ -822,16 +822,16 @@
},
{
"name": "paragonie/constant_time_encoding",
"version": "v2.6.3",
"version": "v2.7.0",
"source": {
"type": "git",
"url": "https://github.com/paragonie/constant_time_encoding.git",
"reference": "58c3f47f650c94ec05a151692652a868995d2938"
"reference": "52a0d99e69f56b9ec27ace92ba56897fe6993105"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938",
"reference": "58c3f47f650c94ec05a151692652a868995d2938",
"url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/52a0d99e69f56b9ec27ace92ba56897fe6993105",
"reference": "52a0d99e69f56b9ec27ace92ba56897fe6993105",
"shasum": ""
},
"require": {
@ -885,7 +885,7 @@
"issues": "https://github.com/paragonie/constant_time_encoding/issues",
"source": "https://github.com/paragonie/constant_time_encoding"
},
"time": "2022-06-14T06:56:20+00:00"
"time": "2024-05-08T12:18:48+00:00"
},
{
"name": "phpmailer/phpmailer",
@ -1672,16 +1672,16 @@
},
{
"name": "utopia-php/dsn",
"version": "0.2.0",
"version": "0.2.1",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/dsn.git",
"reference": "c11f37a12c3f6aaf9fea97ca7cb363dcc93668d7"
"reference": "42ee37a3d1785100b2f69091c9d4affadb6846eb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/dsn/zipball/c11f37a12c3f6aaf9fea97ca7cb363dcc93668d7",
"reference": "c11f37a12c3f6aaf9fea97ca7cb363dcc93668d7",
"url": "https://api.github.com/repos/utopia-php/dsn/zipball/42ee37a3d1785100b2f69091c9d4affadb6846eb",
"reference": "42ee37a3d1785100b2f69091c9d4affadb6846eb",
"shasum": ""
},
"require": {
@ -1713,9 +1713,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/dsn/issues",
"source": "https://github.com/utopia-php/dsn/tree/0.2.0"
"source": "https://github.com/utopia-php/dsn/tree/0.2.1"
},
"time": "2023-11-02T12:01:43+00:00"
"time": "2024-05-07T02:01:25+00:00"
},
{
"name": "utopia-php/framework",
@ -1966,22 +1966,21 @@
},
{
"name": "utopia-php/migration",
"version": "0.4.1",
"version": "0.4.4",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/migration.git",
"reference": "ae3cfe93f6d313105d226aeb68806660c806a925"
"reference": "a8a5d392bebf082faf289f4dfe09d9fd76844c33"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/migration/zipball/ae3cfe93f6d313105d226aeb68806660c806a925",
"reference": "ae3cfe93f6d313105d226aeb68806660c806a925",
"url": "https://api.github.com/repos/utopia-php/migration/zipball/a8a5d392bebf082faf289f4dfe09d9fd76844c33",
"reference": "a8a5d392bebf082faf289f4dfe09d9fd76844c33",
"shasum": ""
},
"require": {
"appwrite/appwrite": "10.1.0",
"php": "8.*",
"utopia-php/cli": "0.*"
"php": "8.*"
},
"require-dev": {
"laravel/pint": "1.*",
@ -2008,9 +2007,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/migration/issues",
"source": "https://github.com/utopia-php/migration/tree/0.4.1"
"source": "https://github.com/utopia-php/migration/tree/0.4.4"
},
"time": "2024-05-01T13:19:18+00:00"
"time": "2024-05-17T05:25:31+00:00"
},
{
"name": "utopia-php/mongo",
@ -2124,16 +2123,16 @@
},
{
"name": "utopia-php/platform",
"version": "0.5.1",
"version": "0.5.2",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/platform.git",
"reference": "3eceef0b6593fe0f7d2efd36d40402a395a4c285"
"reference": "b9feabc79b92dc2b05683a986ad43bce5c1583e3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/platform/zipball/3eceef0b6593fe0f7d2efd36d40402a395a4c285",
"reference": "3eceef0b6593fe0f7d2efd36d40402a395a4c285",
"url": "https://api.github.com/repos/utopia-php/platform/zipball/b9feabc79b92dc2b05683a986ad43bce5c1583e3",
"reference": "b9feabc79b92dc2b05683a986ad43bce5c1583e3",
"shasum": ""
},
"require": {
@ -2141,7 +2140,7 @@
"ext-redis": "*",
"php": ">=8.0",
"utopia-php/cli": "0.15.*",
"utopia-php/framework": "0.*.*"
"utopia-php/framework": "0.33.*"
},
"require-dev": {
"laravel/pint": "1.2.*",
@ -2167,9 +2166,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/platform/issues",
"source": "https://github.com/utopia-php/platform/tree/0.5.1"
"source": "https://github.com/utopia-php/platform/tree/0.5.2"
},
"time": "2023-12-26T16:14:41+00:00"
"time": "2024-05-22T12:50:35+00:00"
},
{
"name": "utopia-php/pools",
@ -2499,16 +2498,16 @@
},
{
"name": "utopia-php/vcs",
"version": "0.6.5",
"version": "0.6.6",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/vcs.git",
"reference": "104e47ea8e38c156ec0e0bd415caa3dcd5046fe2"
"reference": "e538264cfee5e3efdfe1771efba04750cf20b2c4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/vcs/zipball/104e47ea8e38c156ec0e0bd415caa3dcd5046fe2",
"reference": "104e47ea8e38c156ec0e0bd415caa3dcd5046fe2",
"url": "https://api.github.com/repos/utopia-php/vcs/zipball/e538264cfee5e3efdfe1771efba04750cf20b2c4",
"reference": "e538264cfee5e3efdfe1771efba04750cf20b2c4",
"shasum": ""
},
"require": {
@ -2542,9 +2541,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/vcs/issues",
"source": "https://github.com/utopia-php/vcs/tree/0.6.5"
"source": "https://github.com/utopia-php/vcs/tree/0.6.6"
},
"time": "2024-01-08T17:11:12+00:00"
"time": "2024-05-17T09:36:30+00:00"
},
{
"name": "utopia-php/websocket",
@ -2731,16 +2730,16 @@
"packages-dev": [
{
"name": "appwrite/sdk-generator",
"version": "0.38.2",
"version": "0.38.6",
"source": {
"type": "git",
"url": "https://github.com/appwrite/sdk-generator.git",
"reference": "51284668529e2b10ed933412a42b603c76cded23"
"reference": "d7016d6d72545e84709892faca972eb4bf5bd699"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/51284668529e2b10ed933412a42b603c76cded23",
"reference": "51284668529e2b10ed933412a42b603c76cded23",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/d7016d6d72545e84709892faca972eb4bf5bd699",
"reference": "d7016d6d72545e84709892faca972eb4bf5bd699",
"shasum": ""
},
"require": {
@ -2776,9 +2775,9 @@
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
"support": {
"issues": "https://github.com/appwrite/sdk-generator/issues",
"source": "https://github.com/appwrite/sdk-generator/tree/0.38.2"
"source": "https://github.com/appwrite/sdk-generator/tree/0.38.6"
},
"time": "2024-04-25T07:49:29+00:00"
"time": "2024-05-20T18:00:16+00:00"
},
{
"name": "doctrine/deprecations",
@ -2899,16 +2898,16 @@
},
{
"name": "laravel/pint",
"version": "v1.15.3",
"version": "v1.16.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/pint.git",
"reference": "3600b5d17aff52f6100ea4921849deacbbeb8656"
"reference": "1b3a3dc5bc6a81ff52828ba7277621f1d49d6d98"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/pint/zipball/3600b5d17aff52f6100ea4921849deacbbeb8656",
"reference": "3600b5d17aff52f6100ea4921849deacbbeb8656",
"url": "https://api.github.com/repos/laravel/pint/zipball/1b3a3dc5bc6a81ff52828ba7277621f1d49d6d98",
"reference": "1b3a3dc5bc6a81ff52828ba7277621f1d49d6d98",
"shasum": ""
},
"require": {
@ -2919,11 +2918,11 @@
"php": "^8.1.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.54.0",
"illuminate/view": "^10.48.8",
"larastan/larastan": "^2.9.5",
"laravel-zero/framework": "^10.3.0",
"mockery/mockery": "^1.6.11",
"friendsofphp/php-cs-fixer": "^3.57.1",
"illuminate/view": "^10.48.10",
"larastan/larastan": "^2.9.6",
"laravel-zero/framework": "^10.4.0",
"mockery/mockery": "^1.6.12",
"nunomaduro/termwind": "^1.15.1",
"pestphp/pest": "^2.34.7"
},
@ -2961,7 +2960,7 @@
"issues": "https://github.com/laravel/pint/issues",
"source": "https://github.com/laravel/pint"
},
"time": "2024-04-30T15:02:26+00:00"
"time": "2024-05-21T18:08:25+00:00"
},
{
"name": "matthiasmullie/minify",
@ -3377,16 +3376,16 @@
},
{
"name": "phpdocumentor/reflection-docblock",
"version": "5.4.0",
"version": "5.4.1",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
"reference": "298d2febfe79d03fe714eb871d5538da55205b1a"
"reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/298d2febfe79d03fe714eb871d5538da55205b1a",
"reference": "298d2febfe79d03fe714eb871d5538da55205b1a",
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c",
"reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c",
"shasum": ""
},
"require": {
@ -3435,9 +3434,9 @@
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
"support": {
"issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
"source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.4.0"
"source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.4.1"
},
"time": "2024-04-09T21:13:58+00:00"
"time": "2024-05-21T05:55:05+00:00"
},
{
"name": "phpdocumentor/type-resolver",
@ -3568,16 +3567,16 @@
},
{
"name": "phpstan/phpdoc-parser",
"version": "1.28.0",
"version": "1.29.0",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpdoc-parser.git",
"reference": "cd06d6b1a1b3c75b0b83f97577869fd85a3cd4fb"
"reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/cd06d6b1a1b3c75b0b83f97577869fd85a3cd4fb",
"reference": "cd06d6b1a1b3c75b0b83f97577869fd85a3cd4fb",
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/536889f2b340489d328f5ffb7b02bb6b183ddedc",
"reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc",
"shasum": ""
},
"require": {
@ -3609,9 +3608,9 @@
"description": "PHPDoc parser with support for nullable, intersection and generic types",
"support": {
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.28.0"
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.0"
},
"time": "2024-04-03T18:51:33+00:00"
"time": "2024-05-06T12:04:23+00:00"
},
{
"name": "phpunit/php-code-coverage",
@ -5476,5 +5475,5 @@
"platform-overrides": {
"php": "8.3"
},
"plugin-api-version": "2.6.0"
"plugin-api-version": "2.3.0"
}

View file

@ -1 +0,0 @@
Create a new build for an Appwrite Function deployment. This endpoint can be used to retry a failed build.

View file

@ -163,6 +163,7 @@ class Exception extends \Exception
public const BUILD_NOT_FOUND = 'build_not_found';
public const BUILD_NOT_READY = 'build_not_ready';
public const BUILD_IN_PROGRESS = 'build_in_progress';
public const BUILD_ALREADY_COMPLETED = 'build_already_completed';
/** Execution */
public const EXECUTION_NOT_FOUND = 'execution_not_found';

View file

@ -8,6 +8,7 @@ use Appwrite\Event\Usage;
use Appwrite\Messaging\Adapter\Realtime;
use Appwrite\Utopia\Response\Model\Deployment;
use Appwrite\Vcs\Comment;
use Exception;
use Executor\Executor;
use Swoole\Coroutine as Co;
use Utopia\Cache\Cache;
@ -156,9 +157,9 @@ class Builds extends Action
$startTime = DateTime::now();
$durationStart = \microtime(true);
$buildId = $deployment->getAttribute('buildId', '');
$build = $dbForProject->getDocument('builds', $buildId);
$isNewBuild = empty($buildId);
if ($isNewBuild) {
if ($build->isEmpty()) {
$buildId = ID::unique();
$build = $dbForProject->createDocument('builds', new Document([
'$id' => $buildId,
@ -180,6 +181,9 @@ class Builds extends Action
$deployment->setAttribute('buildId', $build->getId());
$deployment->setAttribute('buildInternalId', $build->getInternalId());
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
} elseif ($build->getAttribute('status') === 'canceled') {
Console::info('Build has been canceled');
return;
} else {
$build = $dbForProject->getDocument('builds', $buildId);
}
@ -221,6 +225,12 @@ class Builds extends Action
$stdout = '';
$stderr = '';
Console::execute('mkdir -p /tmp/builds/' . \escapeshellcmd($buildId), '', $stdout, $stderr);
if ($dbForProject->getDocument('builds', $buildId)->getAttribute('status') === 'canceled') {
Console::info('Build has been canceled');
return;
}
$exit = Console::execute($gitCloneCommand, '', $stdout, $stderr);
if ($exit !== 0) {
@ -397,6 +407,11 @@ class Builds extends Action
$response = null;
$err = null;
if ($dbForProject->getDocument('builds', $buildId)->getAttribute('status') === 'canceled') {
Console::info('Build has been canceled');
return;
}
Co::join([
Co\go(function () use ($executor, &$response, $project, $deployment, $source, $function, $runtime, $vars, $command, &$err) {
try {
@ -463,6 +478,10 @@ class Builds extends Action
]);
if ($err) {
if ($dbForProject->getDocument('builds', $buildId)->getAttribute('status') === 'canceled') {
Console::info('Build has been canceled');
return;
}
throw $err;
}
@ -492,6 +511,11 @@ class Builds extends Action
$function = $dbForProject->updateDocument('functions', $function->getId(), $function);
}
if ($dbForProject->getDocument('builds', $buildId)->getAttribute('status') === 'canceled') {
Console::info('Build has been canceled');
return;
}
/** Update function schedule */
// Inform scheduler if function is still active
@ -502,6 +526,11 @@ class Builds extends Action
->setAttribute('active', !empty($function->getAttribute('schedule')) && !empty($function->getAttribute('deployment')));
Authorization::skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule));
} catch (\Throwable $th) {
if ($dbForProject->getDocument('builds', $buildId)->getAttribute('status') === 'canceled') {
Console::info('Build has been canceled');
return;
}
$endTime = DateTime::now();
$durationEnd = \microtime(true);
$build->setAttribute('endTime', $endTime);

View file

@ -434,6 +434,73 @@ class FunctionsCustomServerTest extends Scope
return array_merge($data, ['deploymentId' => $deploymentId]);
}
/**
* @depends testUpdate
*/
public function testCancelDeploymentBuild($data): void
{
// Create a new deployment to cancel
$folder = 'php';
$code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz";
$this->packageCode($folder);
$deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/deployments', array_merge([
'content-type' => 'multipart/form-data',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'code' => new CURLFile($code, 'application/x-gzip', \basename($code)),
'activate' => true
]);
$deploymentId = $deployment['body']['$id'] ?? '';
$this->assertEquals(202, $deployment['headers']['status-code']);
$this->assertNotEmpty($deployment['body']['$id']);
$this->assertEquals(true, (new DatetimeValidator())->isValid($deployment['body']['$createdAt']));
$this->assertEquals('index.php', $deployment['body']['entrypoint']);
// Poll until deployment is in progress
while (true) {
$deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments/' . $deploymentId, [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
]);
if (
$deployment['headers']['status-code'] >= 400
|| $deployment['body']['status'] === 'building'
) {
break;
}
\sleep(1);
}
$this->assertEquals(200, $deployment['headers']['status-code']);
$this->assertEquals('building', $deployment['body']['status']);
// Cancel the deployment build
$cancel = $this->client->call(Client::METHOD_PATCH, '/functions/' . $data['functionId'] . '/deployments/' . $deploymentId . '/build', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
]);
$this->assertEquals(200, $cancel['headers']['status-code']);
$this->assertEquals('canceled', $cancel['body']['status']);
// Confirm the deployment is canceled
$deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments/' . $deploymentId, [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
]);
$this->assertEquals(200, $deployment['headers']['status-code']);
$this->assertEquals('canceled', $deployment['body']['status']);
}
/**
* @depends testUpdate
*/
@ -523,9 +590,9 @@ class FunctionsCustomServerTest extends Scope
], $this->getHeaders()));
$this->assertEquals($function['headers']['status-code'], 200);
$this->assertEquals($function['body']['total'], 2);
$this->assertEquals($function['body']['total'], 3);
$this->assertIsArray($function['body']['deployments']);
$this->assertCount(2, $function['body']['deployments']);
$this->assertCount(3, $function['body']['deployments']);
/**
* Test search queries
@ -538,9 +605,9 @@ class FunctionsCustomServerTest extends Scope
]));
$this->assertEquals($function['headers']['status-code'], 200);
$this->assertEquals(2, $function['body']['total']);
$this->assertEquals(3, $function['body']['total']);
$this->assertIsArray($function['body']['deployments']);
$this->assertCount(2, $function['body']['deployments']);
$this->assertCount(3, $function['body']['deployments']);
$this->assertEquals($function['body']['deployments'][0]['$id'], $data['deploymentId']);
$function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments', array_merge([
@ -565,7 +632,7 @@ class FunctionsCustomServerTest extends Scope
]);
$this->assertEquals($function['headers']['status-code'], 200);
$this->assertCount(1, $function['body']['deployments']);
$this->assertCount(2, $function['body']['deployments']);
$function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments', array_merge([
'content-type' => 'application/json',
@ -577,7 +644,7 @@ class FunctionsCustomServerTest extends Scope
]);
$this->assertEquals($function['headers']['status-code'], 200);
$this->assertCount(2, $function['body']['deployments']);
$this->assertCount(3, $function['body']['deployments']);
$function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments', array_merge([
'content-type' => 'application/json',
@ -599,9 +666,9 @@ class FunctionsCustomServerTest extends Scope
]));
$this->assertEquals($function['headers']['status-code'], 200);
$this->assertEquals(2, $function['body']['total']);
$this->assertEquals(3, $function['body']['total']);
$this->assertIsArray($function['body']['deployments']);
$this->assertCount(2, $function['body']['deployments']);
$this->assertCount(3, $function['body']['deployments']);
$this->assertEquals($function['body']['deployments'][0]['$id'], $data['deploymentId']);
$function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments', array_merge([
@ -612,9 +679,9 @@ class FunctionsCustomServerTest extends Scope
]));
$this->assertEquals($function['headers']['status-code'], 200);
$this->assertEquals(2, $function['body']['total']);
$this->assertEquals(3, $function['body']['total']);
$this->assertIsArray($function['body']['deployments']);
$this->assertCount(2, $function['body']['deployments']);
$this->assertCount(3, $function['body']['deployments']);
$this->assertEquals($function['body']['deployments'][0]['$id'], $data['deploymentId']);
return $data;