mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Add state to comment, webhook bug fixing
This commit is contained in:
@@ -1091,7 +1091,7 @@ App::get('/v1/functions/:functionId/deployments/:deploymentId')
|
||||
}
|
||||
|
||||
$build = $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', ''));
|
||||
$deployment->setAttribute('status', $build->getAttribute('status', 'processing'));
|
||||
$deployment->setAttribute('status', $build->getAttribute('status', 'waiting'));
|
||||
$deployment->setAttribute('buildStderr', $build->getAttribute('stderr', ''));
|
||||
$deployment->setAttribute('buildStdout', $build->getAttribute('stdout', ''));
|
||||
|
||||
|
||||
+59
-27
@@ -12,6 +12,7 @@ use Utopia\VCS\Adapter\Git\GitHub;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\Host;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Installations;
|
||||
use Appwrite\Vcs\Comment;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\ID;
|
||||
use Utopia\Database\Permission;
|
||||
@@ -30,7 +31,7 @@ App::get('/v1/vcs/github/installations')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_MOVED_PERMANENTLY)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_HTML)
|
||||
->label('sdk.methodType', 'webAuth')
|
||||
->param('redirect', '', fn($clients) => new Host($clients), 'URL to redirect back to your Git authorization. Only console hostnames are allowed.', true, ['clients'])
|
||||
->param('redirect', '', fn ($clients) => new Host($clients), 'URL to redirect back to your Git authorization. Only console hostnames are allowed.', true, ['clients'])
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->action(function (string $redirect, Response $response, Document $project) {
|
||||
@@ -225,24 +226,22 @@ App::get('v1/vcs/github/installations/:installationId/repositories/:repositoryId
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'branches' => \array_map(function ($branch) {
|
||||
return [ 'name' => $branch ];
|
||||
return ['name' => $branch];
|
||||
}, $branches),
|
||||
'total' => \count($branches),
|
||||
]), Response::MODEL_BRANCH_LIST);
|
||||
});
|
||||
|
||||
$createGitDeployments = function (array $vcsRepos, string $branchName, string $SHA, Database $dbForConsole, callable $getProjectDB, Request $request) {
|
||||
$createGitDeployments = function (array $vcsRepos, string $branchName, string $SHA, string $commentId, Database $dbForConsole, callable $getProjectDB, Request $request) {
|
||||
foreach ($vcsRepos as $resource) {
|
||||
$resourceType = $resource->getAttribute('resourceType');
|
||||
|
||||
if ($resourceType === "function") {
|
||||
$projectId = $resource->getAttribute('projectId');
|
||||
//TODO: Why is Authorization::skip needed?
|
||||
$project = Authorization::skip(fn () => $dbForConsole->getDocument('projects', $projectId));
|
||||
$dbForProject = $getProjectDB($project);
|
||||
|
||||
$functionId = $resource->getAttribute('resourceId');
|
||||
//TODO: Why is Authorization::skip needed?
|
||||
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
|
||||
$deploymentId = ID::unique();
|
||||
$vcsRepoId = $resource->getId();
|
||||
@@ -256,6 +255,18 @@ $createGitDeployments = function (array $vcsRepos, string $branchName, string $S
|
||||
$activate = true;
|
||||
}
|
||||
|
||||
if (empty($commentId)) {
|
||||
$latestDeployment = Authorization::skip(fn () => $dbForProject->findOne('deployments', [
|
||||
Query::equal('vcsRepositoryId', [$vcsRepoId]),
|
||||
Query::equal('branch', [$branchName]),
|
||||
Query::equal('resourceType', ['functions']),
|
||||
Query::orderDesc('$createdAt'),
|
||||
]));
|
||||
if ($latestDeployment !== false && !$latestDeployment->isEmpty()) {
|
||||
$commentId = $latestDeployment->getAttribute('vcsCommentId', '');
|
||||
}
|
||||
}
|
||||
|
||||
$deployment = $dbForProject->createDocument('deployments', new Document([
|
||||
'$id' => $deploymentId,
|
||||
'$permissions' => [
|
||||
@@ -273,6 +284,7 @@ $createGitDeployments = function (array $vcsRepos, string $branchName, string $S
|
||||
'vcsInstallationInternalId' => $vcsInstallationInternalId,
|
||||
'vcsRepositoryId' => $vcsRepoId,
|
||||
'vcsRepositoryInternalId' => $vcsRepoInternalId,
|
||||
'vcsCommentId' => $commentId,
|
||||
'branch' => $branchName,
|
||||
'search' => implode(' ', [$deploymentId, $function->getAttribute('entrypoint')]),
|
||||
'activate' => $activate,
|
||||
@@ -326,7 +338,7 @@ App::post('/v1/vcs/github/incomingwebhook')
|
||||
Query::limit(100),
|
||||
]);
|
||||
|
||||
$createGitDeployments($vcsRepos, $branchName, $SHA, $dbForConsole, $getProjectDB, $request);
|
||||
$createGitDeployments($vcsRepos, $branchName, $SHA, '', $dbForConsole, $getProjectDB, $request);
|
||||
} elseif ($event == $github::EVENT_INSTALLATION) {
|
||||
if ($parsedPayload["action"] == "deleted") {
|
||||
// TODO: Use worker for this job instead (update function as well)
|
||||
@@ -365,30 +377,50 @@ App::post('/v1/vcs/github/incomingwebhook')
|
||||
Query::orderDesc('$createdAt')
|
||||
]);
|
||||
|
||||
if (\count($vcsRepos) === 0) {
|
||||
$createGitDeployments($vcsRepos, $branchName, '', $dbForConsole, $getProjectDB, $request);
|
||||
}
|
||||
if (\count($vcsRepos) !== 0) {
|
||||
$comment = new Comment();
|
||||
|
||||
// TODO: Use for loop instead
|
||||
$vcsRepo = $vcsRepos[0];
|
||||
foreach ($vcsRepos as $vcsRepo) {
|
||||
$projectId = $vcsRepo->getAttribute('projectId');
|
||||
$project = Authorization::skip(fn () => $dbForConsole->getDocument('projects', $projectId));
|
||||
$dbForProject = $getProjectDB($project);
|
||||
|
||||
$projectId = $vcsRepo->getAttribute('projectId');
|
||||
//TODO: Why is Authorization::skip needed?
|
||||
$project = Authorization::skip(fn () => $dbForConsole->getDocument('projects', $projectId));
|
||||
$dbForProject = $getProjectDB($project);
|
||||
$vcsRepoId = $vcsRepo->getId();
|
||||
$deployment = Authorization::skip(fn () => $dbForProject->findOne('deployments', [
|
||||
Query::equal('vcsRepositoryId', [$vcsRepoId]),
|
||||
Query::equal('branch', [$branchName]),
|
||||
Query::orderDesc('$createdAt'),
|
||||
]));
|
||||
$vcsRepoId = $vcsRepo->getId();
|
||||
|
||||
if ($deployment !== false && !$deployment->isEmpty()) {
|
||||
$buildId = $deployment->getAttribute('buildId');
|
||||
$build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $buildId));
|
||||
$buildStatus = $build->getAttribute('status');
|
||||
$comment = "| Build Status |\r\n | --------------- |\r\n | $buildStatus |";
|
||||
$github->addComment($owner, $repositoryName, $pullRequestNumber, $comment);
|
||||
$deployment = Authorization::skip(fn () => $dbForProject->findOne('deployments', [
|
||||
Query::equal('vcsRepositoryId', [$vcsRepoId]),
|
||||
Query::equal('branch', [$branchName]),
|
||||
Query::equal('resourceType', ['functions']),
|
||||
Query::orderDesc('$createdAt'),
|
||||
]));
|
||||
|
||||
if (!$deployment || $deployment->isEmpty()) {
|
||||
$function = Authorization::skip(fn () => $dbForProject->findOne('functions', [
|
||||
Query::equal('vcsRepositoryId', [$vcsRepoId]),
|
||||
Query::orderDesc('$createdAt'),
|
||||
]));
|
||||
$build = new Document([]);
|
||||
} else {
|
||||
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $deployment->getAttribute('resourceId', '')));
|
||||
$build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', '')));
|
||||
}
|
||||
|
||||
if (!$function || $function->isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$status = !$build || $build->isEmpty() ? 'waiting' : $build->getAttribute('status', 'waiting');
|
||||
$deploymentId = !$build || $build->isEmpty() ? '' : $build->getAttribute('deploymentId', '');
|
||||
|
||||
$comment->addBuild($project, $function, $status, $deploymentId);
|
||||
}
|
||||
|
||||
$commentId = '';
|
||||
if (!$comment->isEmpty()) {
|
||||
$commentId = $github->createComment($owner, $repositoryName, $pullRequestNumber, $comment->generateComment());
|
||||
}
|
||||
|
||||
$createGitDeployments($vcsRepos, $branchName, '', $commentId, $dbForConsole, $getProjectDB, $request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
-10
@@ -7,6 +7,7 @@ use Appwrite\Resque\Worker;
|
||||
use Appwrite\Utopia\Response\Model\Deployment;
|
||||
use Executor\Executor;
|
||||
use Appwrite\Usage\Stats;
|
||||
use Appwrite\Vcs\Comment;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\App;
|
||||
use Utopia\CLI\Console;
|
||||
@@ -163,9 +164,10 @@ class BuildsV1 extends Worker
|
||||
}
|
||||
$commentId = $deployment->getAttribute('vcsCommentId');
|
||||
if ($commentId) {
|
||||
$comment = "| Build Status |\r\n | --------------- |\r\n | Processing |";
|
||||
|
||||
$github->updateComment($owner, $repositoryName, $commentId, $comment);
|
||||
$comment = new Comment();
|
||||
$comment->parseComment($github->getComment($owner, $repositoryName, $commentId));
|
||||
$comment->addBuild($project, $function, 'processing', $deployment->getId());
|
||||
$github->updateComment($owner, $repositoryName, $commentId, $comment->generateComment());
|
||||
}
|
||||
} else {
|
||||
$build = $dbForProject->createDocument('builds', new Document([
|
||||
@@ -201,8 +203,10 @@ class BuildsV1 extends Worker
|
||||
if ($isVcsEnabled) {
|
||||
$commentId = $deployment->getAttribute('vcsCommentId');
|
||||
if ($commentId) {
|
||||
$comment = "| Build Status |\r\n | --------------- |\r\n | Building |";
|
||||
$github->updateComment($owner, $repositoryName, $commentId, $comment);
|
||||
$comment = new Comment();
|
||||
$comment->parseComment($github->getComment($owner, $repositoryName, $commentId));
|
||||
$comment->addBuild($project, $function, 'building', $deployment->getId());
|
||||
$github->updateComment($owner, $repositoryName, $commentId, $comment->generateComment());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,15 +307,16 @@ class BuildsV1 extends Worker
|
||||
$build->setAttribute('stdout', $response['stdout']);
|
||||
|
||||
if ($isVcsEnabled) {
|
||||
$status = 'ready';
|
||||
if ($SHA !== "" && $owner !== "") {
|
||||
$github->updateCommitStatus($repositoryName, $SHA, $owner, "success", "Deployment is successful!", $targetUrl, "Appwrite Deployment");
|
||||
}
|
||||
|
||||
$commentId = $deployment->getAttribute('vcsCommentId');
|
||||
if ($commentId) {
|
||||
$comment = "| Build Status |\r\n | --------------- |\r\n | $status |";
|
||||
$github->updateComment($owner, $repositoryName, $commentId, $comment);
|
||||
$comment = new Comment();
|
||||
$comment->parseComment($github->getComment($owner, $repositoryName, $commentId));
|
||||
$comment->addBuild($project, $function, 'ready', $deployment->getId());
|
||||
$github->updateComment($owner, $repositoryName, $commentId, $comment->generateComment());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,8 +360,10 @@ class BuildsV1 extends Worker
|
||||
|
||||
$commentId = $deployment->getAttribute('vcsCommentId');
|
||||
if ($commentId) {
|
||||
$comment = "| Build Status |\r\n | --------------- |\r\n | $status |";
|
||||
$github->updateComment($owner, $repositoryName, $commentId, $comment);
|
||||
$comment = new Comment();
|
||||
$comment->parseComment($github->getComment($owner, $repositoryName, $commentId));
|
||||
$comment->addBuild($project, $function, 'failed', $deployment->getId());
|
||||
$github->updateComment($owner, $repositoryName, $commentId, $comment->generateComment());
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
|
||||
Generated
+2
-2
@@ -3090,7 +3090,7 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/vcs.git",
|
||||
"reference": "1331193f6ba0443a87f4fd665a8f91dc07817370"
|
||||
"reference": "9215381b4fde95e26ab1f01d5add6d2d428d6fd7"
|
||||
},
|
||||
"require": {
|
||||
"adhocore/jwt": "^1.1",
|
||||
@@ -3135,7 +3135,7 @@
|
||||
"utopia",
|
||||
"vcs"
|
||||
],
|
||||
"time": "2023-05-26T08:41:54+00:00"
|
||||
"time": "2023-05-28T10:14:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/websocket",
|
||||
|
||||
@@ -66,7 +66,7 @@ class Deployment extends Model
|
||||
])
|
||||
->addRule('status', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'The deployment status. Possible values are "processing", "building", "pending", "ready", and "failed".',
|
||||
'description' => 'The deployment status. Possible values are "processing", "building", "waiting", "ready", and "failed".',
|
||||
'default' => '',
|
||||
'example' => 'ready',
|
||||
])
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Vcs;
|
||||
|
||||
use Utopia\Database\Document;
|
||||
|
||||
class Comment
|
||||
{
|
||||
protected string $statePrefix = '[appwrite]: #';
|
||||
|
||||
/**
|
||||
* @var mixed[] $builds
|
||||
*/
|
||||
protected array $builds = [];
|
||||
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return \count($this->builds) === 0;
|
||||
}
|
||||
|
||||
public function addBuild(Document $project, Document $function, string $buildStatus, string $deploymentId): void
|
||||
{
|
||||
// Unique index
|
||||
$id = $project->getId() . '_' . $function->getId();
|
||||
|
||||
$this->builds[$id] = [
|
||||
'projectName' => $project->getAttribute('name'),
|
||||
'projectId' => $project->getId(),
|
||||
'functionName' => $function->getAttribute('name'),
|
||||
'functionId' => $function->getId(),
|
||||
'buildStatus' => $buildStatus,
|
||||
'deploymentId' => $deploymentId
|
||||
];
|
||||
}
|
||||
|
||||
public function generateComment(): string
|
||||
{
|
||||
$json = \json_encode($this->builds);
|
||||
|
||||
$text = $this->statePrefix . \base64_encode($json) . "\n\n";
|
||||
|
||||
$projects = [];
|
||||
|
||||
foreach ($this->builds as $id => $build) {
|
||||
if (!\array_key_exists($build['projectId'], $projects)) {
|
||||
$projects[$build['projectId']] = [
|
||||
'name' => $build['projectName'],
|
||||
'functions' => []
|
||||
];
|
||||
}
|
||||
|
||||
$projects[$build['projectId']]['functions'][$build['functionId']] = [
|
||||
'name' => $build['functionName'],
|
||||
'status' => $build['buildStatus'],
|
||||
'deploymentId' => $build['deploymentId']
|
||||
];
|
||||
}
|
||||
|
||||
$text .= "> Bored? Read random [Wikipedia Page](https://en.wikipedia.org/wiki/Special:Random).\n\n";
|
||||
|
||||
foreach ($projects as $projectId => $project) {
|
||||
$text .= "### {$project['name']} `{$projectId}`\n\n";
|
||||
$text .= "| Function | Status | Execute |\n";
|
||||
$text .= "| :- | :- | :- |\n";
|
||||
|
||||
foreach ($project['functions'] as $functionId => $function) {
|
||||
$status = match ($function['status']) {
|
||||
'waiting' => '⌛ Waiting',
|
||||
'processing' => '🤔 Processing',
|
||||
'building' => '🛠️ Building',
|
||||
'ready' => '✅ Ready',
|
||||
'failed' => '❌ Failed',
|
||||
};
|
||||
|
||||
$execute = $function['status'] === 'ready' ? "[HTTP](#) \\| [Console](#)" : '_Build must be ready first_';
|
||||
|
||||
$text .= "| **{$function['name']}** `{$functionId}` | {$status} ([Logs](#)) | {$execute} |\n";
|
||||
}
|
||||
|
||||
$text .= "\n";
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
public function parseComment(string $comment): self
|
||||
{
|
||||
$state = \explode("\n", $comment)[0] ?? '';
|
||||
$state = substr($state, strlen($this->statePrefix));
|
||||
|
||||
$json = \base64_decode($state);
|
||||
|
||||
$builds = \json_decode($json, true);
|
||||
$this->builds = $builds;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user