1
0
Fork 0
mirror of synced 2024-10-01 17:58:02 +13:00

Fix bugs with comment, improve git checks logic

This commit is contained in:
Matej Bačo 2023-05-29 13:51:03 +02:00
parent fb02e12db2
commit 5d2d14df6e
2 changed files with 87 additions and 54 deletions

View file

@ -232,7 +232,7 @@ App::get('v1/vcs/github/installations/:installationId/repositories/:repositoryId
]), Response::MODEL_BRANCH_LIST);
});
$createGitDeployments = function (array $vcsRepos, string $branchName, string $SHA, string $commentId, Database $dbForConsole, callable $getProjectDB, Request $request) {
$createGitDeployments = function (GitHub $github, string $installationId, array $vcsRepos, string $branchName, string $SHA, string $commentId, Database $dbForConsole, callable $getProjectDB, Request $request) {
foreach ($vcsRepos as $resource) {
$resourceType = $resource->getAttribute('resourceType');
@ -242,7 +242,6 @@ $createGitDeployments = function (array $vcsRepos, string $branchName, string $S
$dbForProject = $getProjectDB($project);
$functionId = $resource->getAttribute('resourceId');
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
$deploymentId = ID::unique();
$vcsRepoId = $resource->getId();
$vcsRepoInternalId = $resource->getInternalId();
@ -255,18 +254,31 @@ $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'),
]));
$latestDeployment = Authorization::skip(fn () => $dbForProject->findOne('deployments', [
Query::equal('vcsRepositoryId', [$vcsRepoId]),
Query::equal('branch', [$branchName]),
Query::equal('resourceType', ['functions']),
Query::orderDesc('$createdAt'),
]));
$latestCommentId = $commentId ?? '';
if (empty($latestCommentId)) {
// Empty comment ID is push event. We try to take ID from last deplyoment
if ($latestDeployment !== false && !$latestDeployment->isEmpty()) {
$commentId = $latestDeployment->getAttribute('vcsCommentId', '');
$latestCommentId = $latestDeployment->getAttribute('vcsCommentId', '');
}
} else {
// Known comment ID is pull request event. If deployment exists already, we skip
if ($latestDeployment !== false && !$latestDeployment->isEmpty()) {
$latestDeployment->setAttribute('vcsCommentId', $latestCommentId);
Authorization::skip(fn () => $dbForProject->updateDocument('deployments', $latestDeployment->getId(), $latestDeployment));
continue;
}
}
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
$deployment = $dbForProject->createDocument('deployments', new Document([
'$id' => $deploymentId,
'$permissions' => [
@ -284,7 +296,7 @@ $createGitDeployments = function (array $vcsRepos, string $branchName, string $S
'vcsInstallationInternalId' => $vcsInstallationInternalId,
'vcsRepositoryId' => $vcsRepoId,
'vcsRepositoryInternalId' => $vcsRepoInternalId,
'vcsCommentId' => $commentId,
'vcsCommentId' => $latestCommentId,
'branch' => $branchName,
'search' => implode(' ', [$deploymentId, $function->getAttribute('entrypoint')]),
'activate' => $activate,
@ -293,6 +305,19 @@ $createGitDeployments = function (array $vcsRepos, string $branchName, string $S
// TODO: Figure out port
$targetUrl = $request->getProtocol() . '://' . $request->getHostname() . ":3000/console/project-$projectId/functions/function-$functionId";
if (!empty($SHA)) {
$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, $SHA, $owner, 'pending', $message, $targetUrl, $name);
}
$buildEvent = new Build();
$buildEvent
->setType(BUILD_TYPE_DEPLOYMENT)
@ -332,13 +357,15 @@ App::post('/v1/vcs/github/incomingwebhook')
$SHA = $parsedPayload["SHA"];
$owner = $parsedPayload["owner"];
$github->initialiseVariables($installationId, $privateKey, $githubAppId);
//find functionId from functions table
$vcsRepos = $dbForConsole->find('vcs_repos', [
Query::equal('repositoryId', [$repositoryId]),
Query::limit(100),
]);
$createGitDeployments($vcsRepos, $branchName, $SHA, '', $dbForConsole, $getProjectDB, $request);
$createGitDeployments($github, $installationId, $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)
@ -370,6 +397,7 @@ App::post('/v1/vcs/github/incomingwebhook')
$pullRequestNumber = $parsedPayload["pullRequestNumber"];
$repositoryName = $parsedPayload["repositoryName"];
$owner = $parsedPayload["owner"];
$github->initialiseVariables($installationId, $privateKey, $githubAppId);
$vcsRepos = $dbForConsole->find('vcs_repos', [
@ -420,7 +448,7 @@ App::post('/v1/vcs/github/incomingwebhook')
$commentId = $github->createComment($owner, $repositoryName, $pullRequestNumber, $comment->generateComment());
}
$createGitDeployments($vcsRepos, $branchName, '', $commentId, $dbForConsole, $getProjectDB, $request);
$createGitDeployments($github, $installationId, $vcsRepos, $branchName, '', $commentId, $dbForConsole, $getProjectDB, $request);
}
}
}

View file

@ -15,6 +15,7 @@ use Utopia\Database\ID;
use Utopia\DSN\DSN;
use Utopia\Database\Document;
use Utopia\Config\Config;
use Utopia\Database\Database;
use Utopia\Storage\Storage;
use Utopia\Database\Validator\Authorization;
use Utopia\VCS\Adapter\Git\GitHub;
@ -110,8 +111,7 @@ class BuildsV1 extends Worker
$vcsRepos = Authorization::skip(fn () => $dbForConsole
->getDocument('vcs_repos', $vcsRepoId));
$repositoryId = $vcsRepos->getAttribute('repositoryId');
$vcsInstallations = Authorization::skip(fn () => $dbForConsole
->getDocument('vcs_installations', $vcsInstallationId));
$vcsInstallations = Authorization::skip(fn () => $dbForConsole->getDocument('vcs_installations', $vcsInstallationId));
$installationId = $vcsInstallations->getAttribute('installationId');
$privateKey = App::getEnv('VCS_GITHUB_PRIVATE_KEY');
@ -159,15 +159,9 @@ class BuildsV1 extends Worker
'endTime' => null,
'duration' => 0
]));
if ($SHA !== "" && $owner !== "") {
$github->updateCommitStatus($repositoryName, $SHA, $owner, "pending", "Deployment is being processed..", $targetUrl, "Appwrite Deployment");
}
$commentId = $deployment->getAttribute('vcsCommentId');
if ($commentId) {
$comment = new Comment();
$comment->parseComment($github->getComment($owner, $repositoryName, $commentId));
$comment->addBuild($project, $function, 'processing', $deployment->getId());
$github->updateComment($owner, $repositoryName, $commentId, $comment->generateComment());
if ($isVcsEnabled) {
$this->runGitAction('processing', $github, $SHA, $owner, $repositoryName, $targetUrl, $project, $function, $deployment->getId(), $dbForProject);
}
} else {
$build = $dbForProject->createDocument('builds', new Document([
@ -201,13 +195,7 @@ class BuildsV1 extends Worker
$build = $dbForProject->updateDocument('builds', $buildId, $build);
if ($isVcsEnabled) {
$commentId = $deployment->getAttribute('vcsCommentId');
if ($commentId) {
$comment = new Comment();
$comment->parseComment($github->getComment($owner, $repositoryName, $commentId));
$comment->addBuild($project, $function, 'building', $deployment->getId());
$github->updateComment($owner, $repositoryName, $commentId, $comment->generateComment());
}
$this->runGitAction('building', $github, $SHA, $owner, $repositoryName, $targetUrl, $project, $function, $deployment->getId(), $dbForProject);
}
/** Trigger Webhook */
@ -307,17 +295,7 @@ class BuildsV1 extends Worker
$build->setAttribute('stdout', $response['stdout']);
if ($isVcsEnabled) {
if ($SHA !== "" && $owner !== "") {
$github->updateCommitStatus($repositoryName, $SHA, $owner, "success", "Deployment is successful!", $targetUrl, "Appwrite Deployment");
}
$commentId = $deployment->getAttribute('vcsCommentId');
if ($commentId) {
$comment = new Comment();
$comment->parseComment($github->getComment($owner, $repositoryName, $commentId));
$comment->addBuild($project, $function, 'ready', $deployment->getId());
$github->updateComment($owner, $repositoryName, $commentId, $comment->generateComment());
}
$this->runGitAction('ready', $github, $SHA, $owner, $repositoryName, $targetUrl, $project, $function, $deployment->getId(), $dbForProject);
}
/* Also update the deployment buildTime */
@ -353,18 +331,7 @@ class BuildsV1 extends Worker
Console::error($th->getMessage());
if ($isVcsEnabled) {
$status = 'failed';
if ($SHA !== "" && $owner !== "") {
$github->updateCommitStatus($repositoryName, $SHA, $owner, "failure", "Deployment failed.", $targetUrl, "Appwrite Deployment");
}
$commentId = $deployment->getAttribute('vcsCommentId');
if ($commentId) {
$comment = new Comment();
$comment->parseComment($github->getComment($owner, $repositoryName, $commentId));
$comment->addBuild($project, $function, 'failed', $deployment->getId());
$github->updateComment($owner, $repositoryName, $commentId, $comment->generateComment());
}
$this->runGitAction('failed', $github, $SHA, $owner, $repositoryName, $targetUrl, $project, $function, $deployment->getId(), $dbForProject);
}
} finally {
$build = $dbForProject->updateDocument('builds', $buildId, $build);
@ -404,6 +371,44 @@ class BuildsV1 extends Worker
}
}
protected function runGitAction(string $status, GitHub $github, string $SHA, string $owner, string $repositoryName, string $targetUrl, Document $project, Document $function, string $deploymentId, Database $dbForProject)
{
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
$commentId = $deployment->getAttribute('vcsCommentId', '');
if (empty($commentId)) {
return;
}
if (!empty($SHA)) {
$message = match ($status) {
'ready' => 'Build succeeded.',
'failed' => 'Build failed.',
'processing' => 'Building...',
default => $status
};
$state = match ($status) {
'ready' => 'success',
'failed' => 'failure',
'processing' => 'pending',
default => $status
};
$functionName = $function->getAttribute('name');
$projectName = $project->getAttribute('name');
$name = "{$functionName} ({$projectName})";
$github->updateCommitStatus($repositoryName, $SHA, $owner, $state, $message, $targetUrl, $name);
}
$comment = new Comment();
$comment->parseComment($github->getComment($owner, $repositoryName, $commentId));
$comment->addBuild($project, $function, $status, $deployment->getId());
$github->updateComment($owner, $repositoryName, $commentId, $comment->generateComment());
}
public function shutdown(): void
{
}