Merge pull request #6150 from appwrite/fix-global-vars

Fix: Global variables
This commit is contained in:
Christy Jacob
2023-09-06 13:51:13 -04:00
committed by GitHub
11 changed files with 72 additions and 64 deletions
+11
View File
@@ -1944,6 +1944,17 @@ $projectCollections = array_merge([
'array' => false,
'filters' => ['subQueryVariables'],
],
[
'$id' => ID::custom('varsProject'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16384,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => ['subQueryProjectVariables'],
],
[
'$id' => ID::custom('events'),
'type' => Database::VAR_STRING,
+12 -28
View File
@@ -927,10 +927,9 @@ App::patch('/v1/functions/:functionId/deployments/:deploymentId')
->param('deploymentId', '', new UID(), 'Deployment ID.')
->inject('response')
->inject('dbForProject')
->inject('project')
->inject('events')
->inject('dbForConsole')
->action(function (string $functionId, string $deploymentId, Response $response, Database $dbForProject, Document $project, Event $events, Database $dbForConsole) {
->action(function (string $functionId, string $deploymentId, Response $response, Database $dbForProject, Event $events, Database $dbForConsole) {
$function = $dbForProject->getDocument('functions', $functionId);
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
@@ -990,9 +989,8 @@ App::delete('/v1/functions/:functionId')
->inject('dbForProject')
->inject('deletes')
->inject('events')
->inject('project')
->inject('dbForConsole')
->action(function (string $functionId, Response $response, Database $dbForProject, Delete $deletes, Event $events, Document $project, Database $dbForConsole) {
->action(function (string $functionId, Response $response, Database $dbForProject, Delete $deletes, Event $events, Database $dbForConsole) {
$function = $dbForProject->getDocument('functions', $functionId);
@@ -1434,11 +1432,9 @@ App::post('/v1/functions/:functionId/deployments/:deploymentId/builds/:buildId')
->inject('request')
->inject('response')
->inject('dbForProject')
->inject('dbForConsole')
->inject('project')
->inject('gitHub')
->inject('events')
->action(function (string $functionId, string $deploymentId, string $buildId, Request $request, Response $response, Database $dbForProject, Database $dbForConsole, Document $project, GitHub $github, Event $events) use ($redeployVcs) {
->action(function (string $functionId, string $deploymentId, string $buildId, Request $request, Response $response, Database $dbForProject, Document $project, Event $events) use ($redeployVcs) {
$function = $dbForProject->getDocument('functions', $functionId);
@@ -1662,15 +1658,14 @@ App::post('/v1/functions/:functionId/executions')
$vars = [];
// Shared vars
foreach ($project->getAttribute('variables', []) as $var) {
foreach ($function->getAttribute('varsProject', []) as $var) {
$vars[$var->getAttribute('key')] = $var->getAttribute('value', '');
}
// Function vars
$vars = \array_merge($vars, array_reduce($function->getAttribute('vars', []), function (array $carry, Document $var) {
$carry[$var->getAttribute('key')] = $var->getAttribute('value') ?? '';
return $carry;
}, []));
foreach ($function->getAttribute('vars', []) as $var) {
$vars[$var->getAttribute('key')] = $var->getAttribute('value', '');
}
// Appwrite vars
$vars = \array_merge($vars, [
@@ -1905,11 +1900,10 @@ App::post('/v1/functions/:functionId/variables')
->param('functionId', '', new UID(), 'Function unique ID.', false)
->param('key', null, new Text(Database::LENGTH_KEY), 'Variable key. Max length: ' . Database::LENGTH_KEY . ' chars.', false)
->param('value', null, new Text(8192, 0), 'Variable value. Max length: 8192 chars.', false)
->inject('project')
->inject('response')
->inject('dbForProject')
->inject('dbForConsole')
->action(function (string $functionId, string $key, string $value, Document $project, Response $response, Database $dbForProject, Database $dbForConsole) {
->action(function (string $functionId, string $key, string $value, Response $response, Database $dbForProject, Database $dbForConsole) {
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
@@ -1938,7 +1932,6 @@ App::post('/v1/functions/:functionId/variables')
} catch (DuplicateException $th) {
throw new Exception(Exception::VARIABLE_ALREADY_EXISTS);
}
$dbForConsole->deleteCachedDocument('projects', $project->getId());
$dbForProject->updateDocument('functions', $function->getId(), $function->setAttribute('live', false));
@@ -1950,8 +1943,6 @@ App::post('/v1/functions/:functionId/variables')
->setAttribute('active', !empty($function->getAttribute('schedule')) && !empty($function->getAttribute('deployment')));
Authorization::skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule));
$dbForProject->deleteCachedDocument('functions', $function->getId());
$response
->setStatusCode(Response::STATUS_CODE_CREATED)
->dynamic($variable, Response::MODEL_VARIABLE);
@@ -1979,8 +1970,8 @@ App::get('/v1/functions/:functionId/variables')
}
$response->dynamic(new Document([
'variables' => $function->getAttribute('vars'),
'total' => \count($function->getAttribute('vars')),
'variables' => $function->getAttribute('vars', []),
'total' => \count($function->getAttribute('vars', [])),
]), Response::MODEL_VARIABLE_LIST);
});
@@ -2040,11 +2031,10 @@ App::put('/v1/functions/:functionId/variables/:variableId')
->param('variableId', '', new UID(), 'Variable unique ID.', false)
->param('key', null, new Text(255), 'Variable key. Max length: 255 chars.', false)
->param('value', null, new Text(8192, 0), 'Variable value. Max length: 8192 chars.', true)
->inject('project')
->inject('response')
->inject('dbForProject')
->inject('dbForConsole')
->action(function (string $functionId, string $variableId, string $key, ?string $value, Document $project, Response $response, Database $dbForProject, Database $dbForConsole) {
->action(function (string $functionId, string $variableId, string $key, ?string $value, Response $response, Database $dbForProject, Database $dbForConsole) {
$function = $dbForProject->getDocument('functions', $functionId);
@@ -2071,7 +2061,6 @@ App::put('/v1/functions/:functionId/variables/:variableId')
} catch (DuplicateException $th) {
throw new Exception(Exception::VARIABLE_ALREADY_EXISTS);
}
$dbForConsole->deleteCachedDocument('projects', $project->getId());
$dbForProject->updateDocument('functions', $function->getId(), $function->setAttribute('live', false));
@@ -2083,8 +2072,6 @@ App::put('/v1/functions/:functionId/variables/:variableId')
->setAttribute('active', !empty($function->getAttribute('schedule')) && !empty($function->getAttribute('deployment')));
Authorization::skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule));
$dbForProject->deleteCachedDocument('functions', $function->getId());
$response->dynamic($variable, Response::MODEL_VARIABLE);
});
@@ -2102,11 +2089,10 @@ App::delete('/v1/functions/:functionId/variables/:variableId')
->label('sdk.response.model', Response::MODEL_NONE)
->param('functionId', '', new UID(), 'Function unique ID.', false)
->param('variableId', '', new UID(), 'Variable unique ID.', false)
->inject('project')
->inject('response')
->inject('dbForProject')
->inject('dbForConsole')
->action(function (string $functionId, string $variableId, Document $project, Response $response, Database $dbForProject, Database $dbForConsole) {
->action(function (string $functionId, string $variableId, Response $response, Database $dbForProject, Database $dbForConsole) {
$function = $dbForProject->getDocument('functions', $functionId);
if ($function->isEmpty()) {
@@ -2134,7 +2120,5 @@ App::delete('/v1/functions/:functionId/variables/:variableId')
->setAttribute('active', !empty($function->getAttribute('schedule')) && !empty($function->getAttribute('deployment')));
Authorization::skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule));
$dbForProject->deleteCachedDocument('functions', $function->getId());
$response->noContent();
});
+2 -9
View File
@@ -161,7 +161,6 @@ App::post('/v1/project/variables')
} catch (DuplicateException $th) {
throw new Exception(Exception::VARIABLE_ALREADY_EXISTS);
}
$dbForConsole->deleteCachedDocument('projects', $project->getId());
$functions = $dbForProject->find('functions', [
Query::limit(APP_LIMIT_SUBQUERY)
@@ -171,8 +170,6 @@ App::post('/v1/project/variables')
$dbForProject->updateDocument('functions', $function->getId(), $function->setAttribute('live', false));
}
$dbForProject->deleteCachedDocument('projects', $project->getId());
$response
->setStatusCode(Response::STATUS_CODE_CREATED)
->dynamic($variable, Response::MODEL_VARIABLE);
@@ -261,7 +258,6 @@ App::put('/v1/project/variables/:variableId')
} catch (DuplicateException $th) {
throw new Exception(Exception::VARIABLE_ALREADY_EXISTS);
}
$dbForConsole->deleteCachedDocument('projects', $project->getId());
$functions = $dbForProject->find('functions', [
Query::limit(APP_LIMIT_SUBQUERY)
@@ -271,8 +267,6 @@ App::put('/v1/project/variables/:variableId')
$dbForProject->updateDocument('functions', $function->getId(), $function->setAttribute('live', false));
}
$dbForProject->deleteCachedDocument('projects', $project->getId());
$response->dynamic($variable, Response::MODEL_VARIABLE);
});
@@ -296,6 +290,8 @@ App::delete('/v1/project/variables/:variableId')
throw new Exception(Exception::VARIABLE_NOT_FOUND);
}
$dbForProject->deleteDocument('variables', $variable->getId());
$functions = $dbForProject->find('functions', [
Query::limit(APP_LIMIT_SUBQUERY)
]);
@@ -304,8 +300,5 @@ App::delete('/v1/project/variables/:variableId')
$dbForProject->updateDocument('functions', $function->getId(), $function->setAttribute('live', false));
}
$dbForProject->deleteDocument('variables', $variable->getId());
$dbForProject->deleteCachedDocument('projects', $project->getId());
$response->noContent();
});
+6
View File
@@ -228,6 +228,7 @@ App::get('/v1/vcs/github/authorize')
->groups(['api', 'vcs'])
->label('scope', 'vcs.read')
->label('sdk.namespace', 'vcs')
->label('error', __DIR__ . '/../../views/general/error.phtml')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.method', 'createGitHubInstallation')
->label('sdk.description', '')
@@ -248,6 +249,11 @@ App::get('/v1/vcs/github/authorize')
]);
$appName = App::getEnv('_APP_VCS_GITHUB_APP_NAME');
if (empty($appName)) {
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'GitHub App name is not configured. Please configure VCS (Version Control System) variables in .env file.');
}
$url = "https://github.com/apps/$appName/installations/new?" . \http_build_query([
'state' => $state,
'redirect_uri' => $request->getProtocol() . '://' . $request->getHostname() . "/v1/vcs/github/callback"
-1
View File
@@ -493,7 +493,6 @@ Database::addFilter(
}
);
// READ-ONLY! TO update, write directly to 'variables' collection. After update to vars, make sure to deleteCachedDocument()
Database::addFilter(
'subQueryProjectVariables',
function (mixed $value) {
+6 -12
View File
@@ -321,21 +321,15 @@ class BuildsV1 extends Worker
$vars = [];
// Global vars
$varsFromProject = $dbForProject->find('variables', [
Query::equal('resourceType', ['project']),
Query::limit(APP_LIMIT_SUBQUERY)
]);
foreach ($varsFromProject as $var) {
$vars[$var->getAttribute('key')] = $var->getAttribute('value') ?? '';
// Shared vars
foreach ($function->getAttribute('varsProject', []) as $var) {
$vars[$var->getAttribute('key')] = $var->getAttribute('value', '');
}
// Function vars
$vars = \array_merge($vars, array_reduce($function->getAttribute('vars', []), function (array $carry, Document $var) {
$carry[$var->getAttribute('key')] = $var->getAttribute('value');
return $carry;
}, []));
foreach ($function->getAttribute('vars', []) as $var) {
$vars[$var->getAttribute('key')] = $var->getAttribute('value', '');
}
// Appwrite vars
$vars = \array_merge($vars, [
+6 -9
View File
@@ -143,17 +143,14 @@ Server::setResource('execute', function () {
$vars = [];
// Shared vars
$varsShared = $project->getAttribute('variables', []);
$vars = \array_merge($vars, \array_reduce($varsShared, function (array $carry, Document $var) {
$carry[$var->getAttribute('key')] = $var->getAttribute('value') ?? '';
return $carry;
}, []));
foreach ($function->getAttribute('varsProject', []) as $var) {
$vars[$var->getAttribute('key')] = $var->getAttribute('value', '');
}
// Function vars
$vars = \array_merge($vars, array_reduce($function->getAttribute('vars', []), function (array $carry, Document $var) {
$carry[$var->getAttribute('key')] = $var->getAttribute('value');
return $carry;
}, []));
foreach ($function->getAttribute('vars', []) as $var) {
$vars[$var->getAttribute('key')] = $var->getAttribute('value', '');
}
// Appwrite vars
$vars = \array_merge($vars, [
+7 -4
View File
@@ -17,14 +17,17 @@ class Exception extends AppwriteException
$decoded = json_decode($response, true);
if (\is_array($decoded)) {
if (\is_array($decoded['error'] ?? '')) {
$this->error = $decoded['error']['status'];
$this->errorDescription = $decoded['error']['message'];
$this->message = $this->error . ': ' . $this->errorDescription;
$this->error = $decoded['error']['status'] ?? 'Unknown error';
$this->errorDescription = $decoded['error']['message'] ?? 'No description';
} elseif (\is_array($decoded['errors'] ?? '')) {
$this->error = $decoded['error'] ?? $decoded['message'] ?? 'Unknown error';
$this->errorDescription = $decoded['errors'][0]['message'] ?? 'No description';
} else {
$this->error = $decoded['error'] ?? $decoded['message'] ?? 'Unknown error';
$this->errorDescription = $decoded['error_description'] ?? 'No description';
$this->message = $this->error . ': ' . $this->errorDescription;
}
$this->message = $this->error . ': ' . $this->errorDescription;
}
$type = match ($code) {
400 => AppwriteException::USER_OAUTH2_BAD_REQUEST,
+1
View File
@@ -408,6 +408,7 @@ class V19 extends Migration
'version',
'entrypoint',
'commands',
'varsProject'
];
foreach ($attributesToCreate as $attribute) {
try {
@@ -343,6 +343,24 @@ class FunctionsCustomServerTest extends Scope
$this->assertEquals('0 0 1 1 *', $response1['body']['schedule']);
$this->assertEquals(15, $response1['body']['timeout']);
/**
* Create global variable to test in execution later
*/
$headers = [
'content-type' => 'application/json',
'origin' => 'http://localhost',
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-mode' => 'admin',
];
$variable = $this->client->call(Client::METHOD_POST, '/project/variables', $headers, [
'key' => 'GLOBAL_VARIABLE',
'value' => 'Global Variable Value',
]);
$this->assertEquals(201, $variable['headers']['status-code']);
/**
* Test for FAILURE
*/
@@ -640,6 +658,7 @@ class FunctionsCustomServerTest extends Scope
$this->assertStringContainsString('http', $execution['body']['responseBody']);
$this->assertStringContainsString('PHP', $execution['body']['responseBody']);
$this->assertStringContainsString('8.0', $execution['body']['responseBody']);
$this->assertStringContainsString('Global Variable Value', $execution['body']['responseBody']);
// $this->assertStringContainsString('êä', $execution['body']['responseBody']); // tests unknown utf-8 chars
$this->assertEquals('', $execution['body']['errors']);
$this->assertEquals('', $execution['body']['logs']);
+2 -1
View File
@@ -8,6 +8,7 @@ return function ($context) {
'APPWRITE_FUNCTION_TRIGGER' => $context->req->headers['x-appwrite-trigger'] ?? '',
'APPWRITE_FUNCTION_RUNTIME_NAME' => \getenv('APPWRITE_FUNCTION_RUNTIME_NAME') ?: '',
'APPWRITE_FUNCTION_RUNTIME_VERSION' => \getenv('APPWRITE_FUNCTION_RUNTIME_VERSION') ?: '',
'UNICODE_TEST' => "êä"
'UNICODE_TEST' => "êä",
'GLOBAL_VARIABLE' => \getenv('GLOBAL_VARIABLE') ?: ''
]);
};