1
0
Fork 0
mirror of synced 2024-09-29 17:01:37 +13:00

More PR review changes

This commit is contained in:
Matej Bačo 2023-07-28 10:27:16 +02:00
parent 1bd226ab81
commit 37c0cc122a
7 changed files with 194 additions and 238 deletions

View file

@ -3662,27 +3662,6 @@ $collections = [
'lengths' => [128],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_agent'),
'type' => Database::INDEX_KEY,
'attributes' => ['agent'],
'lengths' => [2048],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_path'),
'type' => Database::INDEX_KEY,
'attributes' => ['path'],
'lengths' => [2048],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_method'),
'type' => Database::INDEX_KEY,
'attributes' => ['method'],
'lengths' => [128],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_status'),
'type' => Database::INDEX_KEY,

View file

@ -546,26 +546,11 @@ return [
'description' => 'The project key has expired. Please generate a new key using the Appwrite console.',
'code' => 401,
],
Exception::ROUTER_INVALID_TYPE => [
'name' => Exception::ROUTER_INVALID_TYPE,
'description' => 'Invalid domain configuration. Route type is not supported.',
'code' => 400,
],
Exception::ROUTER_UNKNOWN_HOST => [
'name' => Exception::ROUTER_UNKNOWN_HOST,
'description' => 'Host is not trusted. Add a custom domain to your project first.',
'code' => 400,
],
Exception::RULE_RESOURCE_ID_MISSING => [
'name' => Exception::RULE_RESOURCE_ID_MISSING,
'description' => 'With resourceType you provided, the resourceId is required.',
'code' => 400,
],
Exception::RULE_CONFIGURATION_MISSING => [
'name' => Exception::RULE_CONFIGURATION_MISSING,
'description' => '_APP_DOMAIN_TARGET must be a public domain.',
'code' => 501,
],
Exception::RULE_RESOURCE_NOT_FOUND => [
'name' => Exception::RULE_RESOURCE_NOT_FOUND,
'description' => 'Resource could not be found. Check resourceId and resourceType.',

View file

@ -67,7 +67,7 @@ App::post('/v1/proxy/rules')
if ($resourceType == 'function') {
if (empty($resourceId)) {
throw new Exception(Exception::RULE_RESOURCE_ID_MISSING);
throw new Exception(Exception::FUNCTION_NOT_FOUND);
}
$function = $dbForProject->getDocument('functions', $resourceId);
@ -238,9 +238,7 @@ App::delete('/v1/proxy/rules/:ruleId')
throw new Exception(Exception::RULE_NOT_FOUND);
}
if (!$dbForConsole->deleteDocument('rules', $rule->getId())) {
throw new Exception(Exception::RULE_CONFIGURATION_MISSING);
}
$dbForConsole->deleteDocument('rules', $rule->getId());
$deletes
->setType(DELETE_TYPE_DOCUMENT)
@ -279,7 +277,7 @@ App::patch('/v1/proxy/rules/:ruleId/verification')
$target = new Domain(App::getEnv('_APP_DOMAIN_TARGET', ''));
if (!$target->isKnown() || $target->isTest()) {
throw new Exception(Exception::RULE_CONFIGURATION_MISSING);
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Domain target must be configured as environment variable.');
}
if ($rule->getAttribute('verification') === true) {

View file

@ -37,6 +37,195 @@ use Utopia\Validator\Boolean;
use function Swoole\Coroutine\batch;
$createGitDeployments = function (GitHub $github, string $installationId, array $vcsRepos, string $branchName, string $vcsCommitHash, string $pullRequest, bool $external, Database $dbForConsole, callable $getProjectDB, Request $request) {
foreach ($vcsRepos as $resource) {
$resourceType = $resource->getAttribute('resourceType');
if ($resourceType === "function") {
$projectId = $resource->getAttribute('projectId');
$project = Authorization::skip(fn () => $dbForConsole->getDocument('projects', $projectId));
$dbForProject = $getProjectDB($project);
$functionId = $resource->getAttribute('resourceId');
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
$deploymentId = ID::unique();
$vcsRepoId = $resource->getId();
$vcsRepoInternalId = $resource->getInternalId();
$repositoryId = $resource->getAttribute('repositoryId');
$vcsInstallationId = $resource->getAttribute('vcsInstallationId');
$vcsInstallationInternalId = $resource->getAttribute('vcsInstallationInternalId');
$productionBranch = $function->getAttribute('vcsBranch');
$activate = false;
if ($branchName == $productionBranch && $external === false) {
$activate = true;
}
$latestCommentId = '';
if (!empty($pullRequest)) {
$latestComment = Authorization::skip(fn () => $dbForConsole->findOne('vcsComments', [
Query::equal('vcsInstallationInternalId', [$vcsInstallationInternalId]),
Query::equal('projectInternalId', [$project->getInternalId()]),
Query::equal('repositoryId', [$repositoryId]),
Query::equal('pullRequestId', [$pullRequest]),
Query::orderDesc('$createdAt'),
]));
if ($latestComment !== false && !$latestComment->isEmpty()) {
$latestCommentId = $latestComment->getAttribute('commentId', '');
}
} elseif (!empty($branchName)) {
$latestComment = Authorization::skip(fn () => $dbForConsole->findOne('vcsComments', [
Query::equal('vcsInstallationInternalId', [$vcsInstallationInternalId]),
Query::equal('projectInternalId', [$project->getInternalId()]),
Query::equal('repositoryId', [$repositoryId]),
Query::equal('branch', [$branchName]),
Query::orderDesc('$createdAt'),
]));
if ($latestComment !== false && !$latestComment->isEmpty()) {
$latestCommentId = $latestComment->getAttribute('commentId', '');
}
}
$owner = $github->getOwnerName($installationId) ?? '';
$repositoryName = $github->getRepositoryName($repositoryId) ?? '';
if (empty($repositoryName)) {
throw new Exception(Exception::REPOSITORY_NOT_FOUND);
}
$isAuthorized = !$external;
if (!$isAuthorized && !empty($pullRequest)) {
if (\in_array($pullRequest, $resource->getAttribute('pullRequests', []))) {
$isAuthorized = true;
}
}
$commentStatus = $isAuthorized ? 'waiting' : 'failed';
if (empty($latestCommentId)) {
$comment = new Comment();
$comment->addBuild($project, $function, $commentStatus, $deploymentId);
if (!empty($pullRequest)) {
$latestCommentId = \strval($github->createComment($owner, $repositoryName, $pullRequest, $comment->generateComment()));
} elseif (!empty($branchName)) {
$gitPullRequest = $github->getBranchPullRequest($owner, $repositoryName, $branchName);
$pullRequest = \strval($gitPullRequest['number'] ?? '');
if (!empty($pullRequest)) {
$latestCommentId = \strval($github->createComment($owner, $repositoryName, $pullRequest, $comment->generateComment()));
}
}
if (!empty($latestCommentId)) {
$teamId = $project->getAttribute('teamId', '');
$latestComment = Authorization::skip(fn () => $dbForConsole->createDocument('vcsComments', new Document([
'$id' => ID::unique(),
'$permissions' => [
Permission::read(Role::team(ID::custom($teamId))),
Permission::update(Role::team(ID::custom($teamId), 'owner')),
Permission::update(Role::team(ID::custom($teamId), 'developer')),
Permission::delete(Role::team(ID::custom($teamId), 'owner')),
Permission::delete(Role::team(ID::custom($teamId), 'developer')),
],
'vcsInstallationInternalId' => $vcsInstallationInternalId,
'vcsInstallationId' => $vcsInstallationId,
'projectInternalId' => $project->getInternalId(),
'projectId' => $project->getId(),
'repositoryId' => $repositoryId,
'branch' => $branchName,
'pullRequestId' => $pullRequest,
'commentId' => $latestCommentId
])));
}
} else {
$comment = new Comment();
$comment->parseComment($github->getComment($owner, $repositoryName, $latestCommentId));
$comment->addBuild($project, $function, $commentStatus, $deploymentId);
$latestCommentId = \strval($github->updateComment($owner, $repositoryName, $latestCommentId, $comment->generateComment()));
}
if (!$isAuthorized) {
$functionName = $function->getAttribute('name');
$projectName = $project->getAttribute('name');
$name = "{$functionName} ({$projectName})";
$message = 'Authorization required for external contributor.';
$vcsTargetUrl = $request->getProtocol() . '://' . $request->getHostname() . "/git/authorize-contributor?projectId={$projectId}&installationId={$vcsInstallationId}&vcsRepositoryId={$vcsRepoId}&pullRequest={$pullRequest}";
$repositoryId = $resource->getAttribute('repositoryId');
$repositoryName = $github->getRepositoryName($repositoryId);
$owner = $github->getOwnerName($installationId);
$github->updateCommitStatus($repositoryName, $vcsCommitHash, $owner, 'failure', $message, $vcsTargetUrl, $name);
continue;
}
$deployment = $dbForProject->createDocument('deployments', new Document([
'$id' => $deploymentId,
'$permissions' => [
Permission::read(Role::any()),
Permission::update(Role::any()),
Permission::delete(Role::any()),
],
'resourceId' => $functionId,
'resourceType' => 'functions',
'entrypoint' => $function->getAttribute('entrypoint'),
'commands' => $function->getAttribute('commands'),
'type' => 'vcs',
'vcsInstallationId' => $vcsInstallationId,
'vcsInstallationInternalId' => $vcsInstallationInternalId,
'vcsRepositoryId' => $repositoryId,
'vcsRepositoryDocId' => $vcsRepoId,
'vcsRepositoryDocInternalId' => $vcsRepoInternalId,
'vcsCommentId' => \strval($latestCommentId),
'vcsBranch' => $branchName,
'search' => implode(' ', [$deploymentId, $function->getAttribute('entrypoint')]),
'activate' => $activate,
]));
$vcsTargetUrl = $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$projectId/functions/function-$functionId";
if (!empty($vcsCommitHash) && $function->getAttribute('vcsSilentMode', false) === false) {
$functionName = $function->getAttribute('name');
$projectName = $project->getAttribute('name');
$name = "{$functionName} ({$projectName})";
$message = 'Starting...';
$repositoryId = $resource->getAttribute('repositoryId');
$repositoryName = $github->getRepositoryName($repositoryId);
$owner = $github->getOwnerName($installationId);
$github->updateCommitStatus($repositoryName, $vcsCommitHash, $owner, 'pending', $message, $vcsTargetUrl, $name);
}
$contribution = new Document([]);
if ($external) {
$pullRequestResponse = $github->getPullRequest($owner, $repositoryName, $pullRequest);
$contribution->setAttribute('ownerName', $pullRequestResponse['head']['repo']['owner']['login']);
$contribution->setAttribute('repositoryName', $pullRequestResponse['head']['repo']['name']);
}
$buildEvent = new Build();
$buildEvent
->setType(BUILD_TYPE_DEPLOYMENT)
->setResource($function)
->setVcsContribution($contribution)
->setDeployment($deployment)
->setVcsTargetUrl($vcsTargetUrl)
->setVcsCommitHash($vcsCommitHash)
->setProject($project)
->trigger();
//TODO: Add event?
}
}
};
App::get('/v1/vcs/github/installations')
->desc('Install GitHub App')
->groups(['api', 'vcs'])
@ -515,195 +704,6 @@ App::get('/v1/vcs/github/installations/:installationId/repositories/:repositoryI
]), Response::MODEL_BRANCH_LIST);
});
$createGitDeployments = function (GitHub $github, string $installationId, array $vcsRepos, string $branchName, string $vcsCommitHash, string $pullRequest, bool $external, Database $dbForConsole, callable $getProjectDB, Request $request) {
foreach ($vcsRepos as $resource) {
$resourceType = $resource->getAttribute('resourceType');
if ($resourceType === "function") {
$projectId = $resource->getAttribute('projectId');
$project = Authorization::skip(fn () => $dbForConsole->getDocument('projects', $projectId));
$dbForProject = $getProjectDB($project);
$functionId = $resource->getAttribute('resourceId');
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
$deploymentId = ID::unique();
$vcsRepoId = $resource->getId();
$vcsRepoInternalId = $resource->getInternalId();
$repositoryId = $resource->getAttribute('repositoryId');
$vcsInstallationId = $resource->getAttribute('vcsInstallationId');
$vcsInstallationInternalId = $resource->getAttribute('vcsInstallationInternalId');
$productionBranch = $function->getAttribute('vcsBranch');
$activate = false;
if ($branchName == $productionBranch && $external === false) {
$activate = true;
}
$latestCommentId = '';
if (!empty($pullRequest)) {
$latestComment = Authorization::skip(fn () => $dbForConsole->findOne('vcsComments', [
Query::equal('vcsInstallationInternalId', [$vcsInstallationInternalId]),
Query::equal('projectInternalId', [$project->getInternalId()]),
Query::equal('repositoryId', [$repositoryId]),
Query::equal('pullRequestId', [$pullRequest]),
Query::orderDesc('$createdAt'),
]));
if ($latestComment !== false && !$latestComment->isEmpty()) {
$latestCommentId = $latestComment->getAttribute('commentId', '');
}
} elseif (!empty($branchName)) {
$latestComment = Authorization::skip(fn () => $dbForConsole->findOne('vcsComments', [
Query::equal('vcsInstallationInternalId', [$vcsInstallationInternalId]),
Query::equal('projectInternalId', [$project->getInternalId()]),
Query::equal('repositoryId', [$repositoryId]),
Query::equal('branch', [$branchName]),
Query::orderDesc('$createdAt'),
]));
if ($latestComment !== false && !$latestComment->isEmpty()) {
$latestCommentId = $latestComment->getAttribute('commentId', '');
}
}
$owner = $github->getOwnerName($installationId) ?? '';
$repositoryName = $github->getRepositoryName($repositoryId) ?? '';
if (empty($repositoryName)) {
throw new Exception(Exception::REPOSITORY_NOT_FOUND);
}
$isAuthorized = !$external;
if (!$isAuthorized && !empty($pullRequest)) {
if (\in_array($pullRequest, $resource->getAttribute('pullRequests', []))) {
$isAuthorized = true;
}
}
$commentStatus = $isAuthorized ? 'waiting' : 'failed';
if (empty($latestCommentId)) {
$comment = new Comment();
$comment->addBuild($project, $function, $commentStatus, $deploymentId);
if (!empty($pullRequest)) {
$latestCommentId = \strval($github->createComment($owner, $repositoryName, $pullRequest, $comment->generateComment()));
} elseif (!empty($branchName)) {
$gitPullRequest = $github->getBranchPullRequest($owner, $repositoryName, $branchName);
$pullRequest = \strval($gitPullRequest['number'] ?? '');
if (!empty($pullRequest)) {
$latestCommentId = \strval($github->createComment($owner, $repositoryName, $pullRequest, $comment->generateComment()));
}
}
if (!empty($latestCommentId)) {
$teamId = $project->getAttribute('teamId', '');
$latestComment = Authorization::skip(fn () => $dbForConsole->createDocument('vcsComments', new Document([
'$id' => ID::unique(),
'$permissions' => [
Permission::read(Role::team(ID::custom($teamId))),
Permission::update(Role::team(ID::custom($teamId), 'owner')),
Permission::update(Role::team(ID::custom($teamId), 'developer')),
Permission::delete(Role::team(ID::custom($teamId), 'owner')),
Permission::delete(Role::team(ID::custom($teamId), 'developer')),
],
'vcsInstallationInternalId' => $vcsInstallationInternalId,
'vcsInstallationId' => $vcsInstallationId,
'projectInternalId' => $project->getInternalId(),
'projectId' => $project->getId(),
'repositoryId' => $repositoryId,
'branch' => $branchName,
'pullRequestId' => $pullRequest,
'commentId' => $latestCommentId
])));
}
} else {
$comment = new Comment();
$comment->parseComment($github->getComment($owner, $repositoryName, $latestCommentId));
$comment->addBuild($project, $function, $commentStatus, $deploymentId);
$latestCommentId = \strval($github->updateComment($owner, $repositoryName, $latestCommentId, $comment->generateComment()));
}
if (!$isAuthorized) {
$functionName = $function->getAttribute('name');
$projectName = $project->getAttribute('name');
$name = "{$functionName} ({$projectName})";
$message = 'Authorization required for external contributor.';
$vcsTargetUrl = $request->getProtocol() . '://' . $request->getHostname() . "/git/authorize-contributor?projectId={$projectId}&installationId={$vcsInstallationId}&vcsRepositoryId={$vcsRepoId}&pullRequest={$pullRequest}";
$repositoryId = $resource->getAttribute('repositoryId');
$repositoryName = $github->getRepositoryName($repositoryId);
$owner = $github->getOwnerName($installationId);
$github->updateCommitStatus($repositoryName, $vcsCommitHash, $owner, 'failure', $message, $vcsTargetUrl, $name);
continue;
}
$deployment = $dbForProject->createDocument('deployments', new Document([
'$id' => $deploymentId,
'$permissions' => [
Permission::read(Role::any()),
Permission::update(Role::any()),
Permission::delete(Role::any()),
],
'resourceId' => $functionId,
'resourceType' => 'functions',
'entrypoint' => $function->getAttribute('entrypoint'),
'commands' => $function->getAttribute('commands'),
'type' => 'vcs',
'vcsInstallationId' => $vcsInstallationId,
'vcsInstallationInternalId' => $vcsInstallationInternalId,
'vcsRepositoryId' => $repositoryId,
'vcsRepositoryDocId' => $vcsRepoId,
'vcsRepositoryDocInternalId' => $vcsRepoInternalId,
'vcsCommentId' => \strval($latestCommentId),
'vcsBranch' => $branchName,
'search' => implode(' ', [$deploymentId, $function->getAttribute('entrypoint')]),
'activate' => $activate,
]));
$vcsTargetUrl = $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$projectId/functions/function-$functionId";
if (!empty($vcsCommitHash) && $function->getAttribute('vcsSilentMode', false) === false) {
$functionName = $function->getAttribute('name');
$projectName = $project->getAttribute('name');
$name = "{$functionName} ({$projectName})";
$message = 'Starting...';
$repositoryId = $resource->getAttribute('repositoryId');
$repositoryName = $github->getRepositoryName($repositoryId);
$owner = $github->getOwnerName($installationId);
$github->updateCommitStatus($repositoryName, $vcsCommitHash, $owner, 'pending', $message, $vcsTargetUrl, $name);
}
$contribution = new Document([]);
if ($external) {
$pullRequestResponse = $github->getPullRequest($owner, $repositoryName, $pullRequest);
$contribution->setAttribute('ownerName', $pullRequestResponse['head']['repo']['owner']['login']);
$contribution->setAttribute('repositoryName', $pullRequestResponse['head']['repo']['name']);
}
$buildEvent = new Build();
$buildEvent
->setType(BUILD_TYPE_DEPLOYMENT)
->setResource($function)
->setVcsContribution($contribution)
->setDeployment($deployment)
->setVcsTargetUrl($vcsTargetUrl)
->setVcsCommitHash($vcsCommitHash)
->setProject($project)
->trigger();
//TODO: Add event?
}
}
};
App::post('/v1/vcs/github/events')
->desc('Create Event')
->groups(['api', 'vcs'])

View file

@ -145,7 +145,7 @@ function router(App $utopia, Database $dbForConsole, SwooleRequest $swooleReques
} elseif ($type === 'api') {
return false;
} else {
throw new AppwriteException(AppwriteException::ROUTER_INVALID_TYPE);
throw new AppwriteException(AppwriteException::GENERAL_SERVER_ERROR, 'Unknown resource type ' . $type);
}
return false;

View file

@ -173,11 +173,8 @@ class Exception extends \Exception
/** Router */
public const ROUTER_UNKNOWN_HOST = 'router_unknown_host';
public const ROUTER_INVALID_TYPE = 'router_unknown_type';
/** Proxy */
public const RULE_CONFIGURATION_MISSING = 'rule_configuration_missing';
public const RULE_RESOURCE_ID_MISSING = 'rule_resource_id_missing';
public const RULE_RESOURCE_NOT_FOUND = 'rule_resource_not_found';
public const RULE_NOT_FOUND = 'rule_not_found';
public const RULE_ALREADY_EXISTS = 'rule_already_exists';

View file

@ -6,9 +6,6 @@ class Executions extends Base
{
public const ALLOWED_ATTRIBUTES = [
'trigger',
'method',
'path',
'agent',
'status',
'statusCode',
'duration'