Merge branch '1.8.x' into lazy-load-relationships

This commit is contained in:
Darshan 2025-06-18 18:36:47 +05:30 committed by GitHub
commit 5e9cabf115
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 78 additions and 40 deletions

View file

@ -1286,6 +1286,7 @@ return [
]
],
],
'deployments' => [
'$collection' => ID::custom(Database::METADATA),
'$id' => ID::custom('deployments'),

View file

@ -363,6 +363,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
if (!empty($providerCommitHash) && $resource->getAttribute('providerSilentMode', false) === false) {
$resourceName = $resource->getAttribute('name');
$projectName = $project->getAttribute('name');
$region = $project->getAttribute('region', 'default');
$name = "{$resourceName} ({$projectName})";
$message = 'Starting...';
@ -377,7 +378,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
}
$owner = $github->getOwnerName($providerInstallationId);
$providerTargetUrl = $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$projectId/$resourceCollection/$resourceType-$resourceId";
$providerTargetUrl = $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$region-$projectId/$resourceCollection/$resourceType-$resourceId";
$github->updateCommitStatus($repositoryName, $providerCommitHash, $owner, 'pending', $message, $providerTargetUrl, $name);
}
@ -476,16 +477,6 @@ App::get('/v1/vcs/github/callback')
$state = \json_decode($state, true);
$projectId = $state['projectId'] ?? '';
$defaultState = [
'success' => $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$projectId/settings/git-installations",
'failure' => $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$projectId/settings/git-installations",
];
$state = \array_merge($defaultState, $state ?? []);
$redirectSuccess = $state['success'] ?? '';
$redirectFailure = $state['failure'] ?? '';
$project = $dbForPlatform->getDocument('projects', $projectId);
if ($project->isEmpty()) {
@ -502,6 +493,18 @@ App::get('/v1/vcs/github/callback')
throw new Exception(Exception::PROJECT_NOT_FOUND, $error);
}
$region = $project->getAttribute('region', 'default');
$defaultState = [
'success' => $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$region-$projectId/settings/git-installations",
'failure' => $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$region-$projectId/settings/git-installations",
];
$state = \array_merge($defaultState, $state ?? []);
$redirectSuccess = $state['success'] ?? '';
$redirectFailure = $state['failure'] ?? '';
// Create / Update installation
if (!empty($providerInstallationId)) {
$privateKey = System::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY');

View file

@ -188,7 +188,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
$resourceId = $rule->getAttribute('deploymentResourceId', '');
$type = ($resourceType === 'site') ? 'sites' : 'functions';
$exception = new AppwriteException(AppwriteException::DEPLOYMENT_NOT_FOUND, view: $errorView);
$exception->addCTA('View deployments', $url . '/console/project-' . $projectId . '/' . $type . '/' . $resourceType . '-' . $resourceId);
$exception->addCTA('View deployments', $url . '/console/project-' . $project->getAttribute('region', 'default') . '-' . $projectId . '/' . $type . '/' . $resourceType . '-' . $resourceId);
throw $exception;
}
@ -321,21 +321,22 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
$allowAnyStatus = !\is_null($apiKey) && $apiKey->isDeploymentStatusIgnored();
if (!$allowAnyStatus && $deployment->getAttribute('status') !== 'ready') {
$status = $deployment->getAttribute('status');
$region = $project->getAttribute('region', 'default');
switch ($status) {
case 'failed':
$exception = new AppwriteException(AppwriteException::BUILD_FAILED, view: $errorView);
$ctaUrl = '/console/project-' . $project->getId() . '/sites/site-' . $resource->getId() . '/deployments/deployment-' . $deployment->getId();
$ctaUrl = '/console/project-' . $region . '-' . $project->getId() . '/sites/site-' . $resource->getId() . '/deployments/deployment-' . $deployment->getId();
$exception->addCTA('View logs', $url . $ctaUrl);
break;
case 'canceled':
$exception = new AppwriteException(AppwriteException::BUILD_CANCELED, view: $errorView);
$ctaUrl = '/console/project-' . $project->getId() . '/sites/site-' . $resource->getId() . '/deployments';
$ctaUrl = '/console/project-' . $region . '-' . $project->getId() . '/sites/site-' . $resource->getId() . '/deployments';
$exception->addCTA('View deployments', $url . $ctaUrl);
break;
default:
$exception = new AppwriteException(AppwriteException::BUILD_NOT_READY, view: $errorView);
$ctaUrl = '/console/project-' . $project->getId() . '/sites/site-' . $resource->getId() . '/deployments/deployment-' . $deployment->getId();
$ctaUrl = '/console/project-' . $region . '-' . $project->getId() . '/sites/site-' . $resource->getId() . '/deployments/deployment-' . $deployment->getId();
$exception->addCTA('Reload', '/');
$exception->addCTA('View logs', $url . $ctaUrl);
break;
@ -347,7 +348,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
$permissions = $resource->getAttribute('execute');
if (!(\in_array('any', $permissions)) && !(\in_array('guests', $permissions))) {
$exception = new AppwriteException(AppwriteException::FUNCTION_EXECUTE_PERMISSION_MISSING, view: $errorView);
$exception->addCTA('View settings', $url . '/console/project-' . $project->getId() . '/functions/function-' . $resource->getId() . '/settings');
$exception->addCTA('View settings', $url . '/console/project-' . $project->getAttribute('region', 'default') . '-' . $project->getId() . '/functions/function-' . $resource->getId() . '/settings');
throw $exception;
}
}

View file

@ -1441,10 +1441,11 @@ class Builds extends Action
$hostname = System::getEnv('_APP_DOMAIN');
$projectId = $project->getId();
$region = $project->getAttribute('region', 'default');
$resourceId = $resource->getId();
$providerTargetUrl = match ($resource->getCollection()) {
'functions' => "{$protocol}://{$hostname}/console/project-{$projectId}/functions/function-{$resourceId}",
'sites' => "{$protocol}://{$hostname}/console/project-{$projectId}/sites/site-{$resourceId}",
'functions' => "{$protocol}://{$hostname}/console/project-{$region}-{$projectId}/functions/function-{$resourceId}",
'sites' => "{$protocol}://{$hostname}/console/project-{$region}-{$projectId}/sites/site-{$resourceId}",
default => throw new \Exception('Invalid resource type')
};

View file

@ -495,7 +495,7 @@ class Deletes extends Action
* @throws Authorization
* @throws DatabaseException
*/
protected function deleteProject(Database $dbForPlatform, callable $getProjectDB, Device $deviceForFiles, Device $deviceForSites, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, CertificatesAdapter $certificates, Document $document): void
private function deleteProject(Database $dbForPlatform, callable $getProjectDB, Device $deviceForFiles, Device $deviceForSites, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, CertificatesAdapter $certificates, Document $document): void
{
$projectInternalId = $document->getSequence();
$projectId = $document->getId();

View file

@ -185,13 +185,33 @@ class Migrations extends Action
*/
protected function updateMigrationDocument(Document $migration, Document $project, Realtime $queueForRealtime): Document
{
$errorMessages = [];
$clonedMigrationDocument = clone $migration;
// we cannot use #sensitive because
// `errors` is nested which requires an override.
$errors = $clonedMigrationDocument->getAttribute('errors', []);
foreach ($errors as $error) {
$decoded = json_decode($error, true);
if (is_array($decoded) && isset($decoded['trace'])) {
unset($decoded['trace']);
$errorMessages[] = json_encode($decoded);
}
}
// set the errors back without trace
$clonedMigrationDocument->setAttribute('errors', $errorMessages);
/** Trigger Realtime Events */
$queueForRealtime
->setProject($project)
->setSubscribers(['console', $project->getId()])
->setEvent('migrations.[migrationId].update')
->setParam('migrationId', $migration->getId())
->setPayload($migration->getArrayCopy())
->setPayload($clonedMigrationDocument->getArrayCopy(), ['options', 'credentials'])
->trigger();
return $this->dbForProject->updateDocument('migrations', $migration->getId(), $migration);
@ -306,26 +326,13 @@ class Migrations extends Action
$errorMessages = [];
foreach ($sourceErrors as $error) {
$message = "Error occurred while fetching '{$error->getResourceName()}:{$error->getResourceId()}' from source with message: '{$error->getMessage()}'";
if ($error->getPrevious()) {
$message .= " Message: ".$error->getPrevious()->getMessage() . " File: ".$error->getPrevious()->getFile() . " Line: ".$error->getPrevious()->getLine();
}
$errorMessages[] = $message;
$errorMessages[] = json_encode($error);
}
foreach ($destinationErrors as $error) {
$message = "Error occurred while pushing '{$error->getResourceName()}:{$error->getResourceId()}' to destination with message: '{$error->getMessage()}'";
if ($error->getPrevious()) {
$message .= " Message: ".$error->getPrevious()->getMessage() . " File: ".$error->getPrevious()->getFile() . " Line: ".$error->getPrevious()->getLine();
}
/** @var MigrationException $error */
$errorMessages[] = $message;
$errorMessages[] = json_encode($error);
}
$migration->setAttribute('errors', $errorMessages);
$this->updateMigrationDocument($migration, $projectDocument, $queueForRealtime);
return;
}
@ -355,12 +362,10 @@ class Migrations extends Action
$errorMessages = [];
foreach ($sourceErrors as $error) {
/** @var MigrationException $error */
$errorMessages[] = "Error occurred while fetching '{$error->getResourceName()}:{$error->getResourceId()}' from source with message '{$error->getMessage()}'";
$errorMessages[] = json_encode($error);
}
foreach ($destinationErrors as $error) {
/** @var MigrationException $error */
$errorMessages[] = "Error occurred while pushing '{$error->getResourceName()}:{$error->getResourceId()}' to destination with message '{$error->getMessage()}'";
$errorMessages[] = json_encode($error);
}
$migration->setAttribute('errors', $errorMessages);

View file

@ -219,6 +219,7 @@ class Webhooks extends Action
]);
$projectId = $project->getId();
$region = $project->getAttribute('region', 'default');
$webhookId = $webhook->getId();
$template = Template::fromFile(__DIR__ . '/../../../../app/config/locale/templates/email-webhook-failed.tpl');
@ -227,7 +228,7 @@ class Webhooks extends Action
$template->setParam('{{project}}', $project->getAttribute('name'));
$template->setParam('{{url}}', $webhook->getAttribute('url'));
$template->setParam('{{error}}', $curlError ?? 'The server returned ' . $statusCode . ' status code');
$template->setParam('{{path}}', "/console/project-$projectId/settings/webhooks/$webhookId");
$template->setParam('{{path}}', "/console/project-$region-$projectId/settings/webhooks/$webhookId");
$template->setParam('{{attempts}}', $attempts);
$template->setParam('{{logoUrl}}', $plan['logoUrl'] ?? APP_EMAIL_LOGO_URL);

View file

@ -4,6 +4,7 @@ namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
use Utopia\Database\Document;
class Migration extends Model
{
@ -107,4 +108,29 @@ class Migration extends Model
{
return Response::MODEL_MIGRATION;
}
public function filter(Document $document): Document
{
$errors = $document->getAttribute('errors', []);
if (empty($errors)) {
return $document;
}
foreach ($errors as $index => $error) {
$decoded = json_decode($error, true);
// frontend doesn't need too many details.
if (is_array($decoded)) {
$errors[$index] = json_encode([
'code' => $decoded['code'] ?? 0,
'message' => $decoded['message'] ?? null,
]);
}
}
// errors now only have code and message.
$document->setAttribute('errors', $errors);
return $document;
}
}