From bd2999037dfd679422dee4967a0f5ed71e53ee1d Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Mon, 9 Oct 2023 15:15:36 +0530 Subject: [PATCH 01/19] WIP: Add VCS tests --- composer.lock | 80 +++++----- tests/e2e/Services/VCS/VCSBase.php | 8 + .../e2e/Services/VCS/VCSConsoleClientTest.php | 140 ++++++++++++++++++ 3 files changed, 183 insertions(+), 45 deletions(-) create mode 100644 tests/e2e/Services/VCS/VCSBase.php create mode 100644 tests/e2e/Services/VCS/VCSConsoleClientTest.php diff --git a/composer.lock b/composer.lock index a345b65c45..25589427e0 100644 --- a/composer.lock +++ b/composer.lock @@ -1050,16 +1050,16 @@ }, { "name": "matomo/device-detector", - "version": "6.1.5", + "version": "6.1.6", "source": { "type": "git", "url": "https://github.com/matomo-org/device-detector.git", - "reference": "40ca2990dba2c1719e5c62168e822e0b86c167d4" + "reference": "5cbea85106e561c7138d03603eb6e05128480409" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/matomo-org/device-detector/zipball/40ca2990dba2c1719e5c62168e822e0b86c167d4", - "reference": "40ca2990dba2c1719e5c62168e822e0b86c167d4", + "url": "https://api.github.com/repos/matomo-org/device-detector/zipball/5cbea85106e561c7138d03603eb6e05128480409", + "reference": "5cbea85106e561c7138d03603eb6e05128480409", "shasum": "" }, "require": { @@ -1115,7 +1115,7 @@ "source": "https://github.com/matomo-org/matomo", "wiki": "https://dev.matomo.org/" }, - "time": "2023-08-17T16:17:41+00:00" + "time": "2023-10-02T10:01:54+00:00" }, { "name": "mongodb/mongodb", @@ -1318,16 +1318,16 @@ }, { "name": "psr/http-client", - "version": "1.0.2", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/php-fig/http-client.git", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", "shasum": "" }, "require": { @@ -1364,9 +1364,9 @@ "psr-18" ], "support": { - "source": "https://github.com/php-fig/http-client/tree/1.0.2" + "source": "https://github.com/php-fig/http-client" }, - "time": "2023-04-10T20:12:12+00:00" + "time": "2023-09-23T14:17:50+00:00" }, { "name": "psr/http-factory", @@ -2152,16 +2152,16 @@ }, { "name": "utopia-php/database", - "version": "0.43.2", + "version": "0.43.4", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "f2626acd42665a9987c94af1c93bf20c28d55c9d" + "reference": "cabdd02e8dc1732eb0b22007c511e7bb3caa5c8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/f2626acd42665a9987c94af1c93bf20c28d55c9d", - "reference": "f2626acd42665a9987c94af1c93bf20c28d55c9d", + "url": "https://api.github.com/repos/utopia-php/database/zipball/cabdd02e8dc1732eb0b22007c511e7bb3caa5c8c", + "reference": "cabdd02e8dc1732eb0b22007c511e7bb3caa5c8c", "shasum": "" }, "require": { @@ -2202,9 +2202,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.43.2" + "source": "https://github.com/utopia-php/database/tree/0.43.4" }, - "time": "2023-09-07T19:04:33+00:00" + "time": "2023-09-28T09:00:05+00:00" }, { "name": "utopia-php/domains", @@ -2564,16 +2564,16 @@ }, { "name": "utopia-php/migration", - "version": "0.3.4", + "version": "0.3.5", "source": { "type": "git", "url": "https://github.com/utopia-php/migration.git", - "reference": "ade836d61b3e1547bc9f0dc300ee75b24ab49f7a" + "reference": "b2fd3a8310296f4e44ff0e85b0eb0230ad9a2f83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/migration/zipball/ade836d61b3e1547bc9f0dc300ee75b24ab49f7a", - "reference": "ade836d61b3e1547bc9f0dc300ee75b24ab49f7a", + "url": "https://api.github.com/repos/utopia-php/migration/zipball/b2fd3a8310296f4e44ff0e85b0eb0230ad9a2f83", + "reference": "b2fd3a8310296f4e44ff0e85b0eb0230ad9a2f83", "shasum": "" }, "require": { @@ -2596,16 +2596,6 @@ "license": [ "MIT" ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Bradley Schofield", - "email": "bradley@appwrite.io" - } - ], "description": "A simple library to migrate resources between services.", "keywords": [ "framework", @@ -2616,9 +2606,9 @@ ], "support": { "issues": "https://github.com/utopia-php/migration/issues", - "source": "https://github.com/utopia-php/migration/tree/0.3.4" + "source": "https://github.com/utopia-php/migration/tree/0.3.5" }, - "time": "2023-09-14T17:17:55+00:00" + "time": "2023-09-25T16:51:47+00:00" }, { "name": "utopia-php/mongo", @@ -3444,16 +3434,16 @@ }, { "name": "doctrine/deprecations", - "version": "v1.1.1", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3" + "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", - "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/4f2d4f2836e7ec4e7a8625e75c6aa916004db931", + "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931", "shasum": "" }, "require": { @@ -3485,9 +3475,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/v1.1.1" + "source": "https://github.com/doctrine/deprecations/tree/1.1.2" }, - "time": "2023-06-03T09:27:29+00:00" + "time": "2023-09-27T20:04:15+00:00" }, { "name": "doctrine/instantiator", @@ -4147,16 +4137,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.24.1", + "version": "1.24.2", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "9f854d275c2dbf84915a5c0ec9a2d17d2cd86b01" + "reference": "bcad8d995980440892759db0c32acae7c8e79442" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/9f854d275c2dbf84915a5c0ec9a2d17d2cd86b01", - "reference": "9f854d275c2dbf84915a5c0ec9a2d17d2cd86b01", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/bcad8d995980440892759db0c32acae7c8e79442", + "reference": "bcad8d995980440892759db0c32acae7c8e79442", "shasum": "" }, "require": { @@ -4188,9 +4178,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.2" }, - "time": "2023-09-18T12:18:02+00:00" + "time": "2023-09-26T12:28:12+00:00" }, { "name": "phpunit/php-code-coverage", diff --git a/tests/e2e/Services/VCS/VCSBase.php b/tests/e2e/Services/VCS/VCSBase.php new file mode 100644 index 0000000000..e26a113b04 --- /dev/null +++ b/tests/e2e/Services/VCS/VCSBase.php @@ -0,0 +1,8 @@ +client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $providerRepositoryId . '/detection', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'installationId' => $installationId, + 'providerRepositoryId' => $providerRepositoryId + ]); + + $this->assertEquals(200, $runtime['headers']['status-code']); + $this->assertEquals($runtime['body']['runtime'], 'ruby-3.1'); + + /** + * Test for FAILURE + */ + + // $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $providerRepositoryId .'/detection', array_merge([ + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ], $this->getHeaders()), [ + // 'installationId' => $installationId, + // 'providerRepositoryId' => $providerRepositoryId, + // 'providerRootDirectory' => 'src' + // ]); + + // $this->assertEquals(404, $runtime['headers']['status-code']); + } + + public function testListRepositories(string $installationId = '651c6d27dac46cc3bc99') + { + /** + * Test for SUCCESS + */ + + $repositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'installationId' => $installationId + ]); + + $this->assertEquals(200, $repositories['headers']['status-code']); + $this->assertEquals($repositories['body']['total'], 3); + + $searchedRepositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'installationId' => $installationId, + 'search' => 'func' + ]); + + $this->assertEquals(200, $searchedRepositories['headers']['status-code']); + $this->assertEquals($searchedRepositories['body']['total'], 1); + } + + public function testGetRepository(string $installationId = '651c6d27dac46cc3bc99', string $providerRepositoryId = '700022615', string $providerRepositoryId2 = '700020051') + { + /** + * Test for SUCCESS + */ + + $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $providerRepositoryId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'installationId' => $installationId, + 'providerRepositoryId' => $providerRepositoryId + ]); + + $this->assertEquals(200, $repository['headers']['status-code']); + $this->assertEquals($repository['body']['name'], 'ruby-starter'); + + $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $providerRepositoryId2, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'installationId' => $installationId, + 'providerRepositoryId' => $providerRepositoryId2 + ]); + + $this->assertEquals(200, $repository['headers']['status-code']); + $this->assertEquals($repository['body']['name'], 'function-1.4'); + } + + public function testListRepositoryBranches(string $installationId = '651c6d27dac46cc3bc99', string $providerRepositoryId = '700020051') + { + /** + * Test for SUCCESS + */ + + $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $providerRepositoryId . '/branches', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'installationId' => $installationId, + 'providerRepositoryId' => $providerRepositoryId + ]); + + $this->assertEquals(200, $repositoryBranches['headers']['status-code']); + $this->assertEquals($repositoryBranches['body']['total'], 2); + $this->assertEquals($repositoryBranches['body']['branches'][0]['name'], 'main'); + $this->assertEquals($repositoryBranches['body']['branches'][1]['name'], 'test'); + } + + // public function testGetInstallation(string $installationId = '651c6d27dac46cc3bc99') + // { + // /** + // * Test for SUCCESS + // */ + + // $installation = $this->client->call(Client::METHOD_GET, '/vcs/installations/' . $installationId, array_merge([ + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ], $this->getHeaders()), [ + // 'installationId' => $installationId + // ]); + + // $this->assertEquals(200, $installation['headers']['status-code']); + // } +} From 1f97bb39b381c8a0c2436d6c0280b746540d70b6 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Wed, 11 Oct 2023 01:31:22 +0530 Subject: [PATCH 02/19] WIP: VCS tests --- .env | 2 + docker-compose.yml | 2 + .../e2e/Services/VCS/VCSConsoleClientTest.php | 75 +++++++++++-------- 3 files changed, 47 insertions(+), 32 deletions(-) diff --git a/.env b/.env index feeb74d849..6c97639b66 100644 --- a/.env +++ b/.env @@ -96,6 +96,8 @@ _APP_VCS_GITHUB_APP_ID= _APP_VCS_GITHUB_CLIENT_ID= _APP_VCS_GITHUB_CLIENT_SECRET= _APP_VCS_GITHUB_WEBHOOK_SECRET= +_APP_VCS_TEST_INSTALLATION_ID= +_APP_VCS_TEST_PROVIDER_REPOSITORY_ID= _APP_MIGRATIONS_FIREBASE_CLIENT_ID= _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET= _APP_ASSISTANT_OPENAI_API_KEY= \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index a18dc83662..df4c2d756e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -185,6 +185,8 @@ services: - _APP_VCS_GITHUB_WEBHOOK_SECRET - _APP_VCS_GITHUB_CLIENT_SECRET - _APP_VCS_GITHUB_CLIENT_ID + - _APP_VCS_TEST_INSTALLATION_ID + - _APP_VCS_TEST_PROVIDER_REPOSITORY_ID - _APP_MIGRATIONS_FIREBASE_CLIENT_ID - _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET - _APP_ASSISTANT_OPENAI_API_KEY diff --git a/tests/e2e/Services/VCS/VCSConsoleClientTest.php b/tests/e2e/Services/VCS/VCSConsoleClientTest.php index e0c1fcda6e..178d6de86d 100644 --- a/tests/e2e/Services/VCS/VCSConsoleClientTest.php +++ b/tests/e2e/Services/VCS/VCSConsoleClientTest.php @@ -6,24 +6,35 @@ use Tests\E2E\Scopes\Scope; use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\SideConsole; +use Utopia\App; class VCSConsoleClientTest extends Scope { use ProjectCustom; use SideConsole; - public function testDetectRuntime(string $installationId = '651c6d27dac46cc3bc99', string $providerRepositoryId = '700022615') + public ?string $installationId = null; + public ?string $providerRepositoryId = null; + + protected function setUp(): void + { + parent::setUp(); + $this->installationId = App::getEnv('_APP_VCS_TEST_INSTALLATION_ID'); + $this->providerRepositoryId = App::getEnv('_APP_VCS_TEST_PROVIDER_REPOSITORY_ID'); + } + + public function testDetectRuntime() { /** * Test for SUCCESS */ - $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $providerRepositoryId . '/detection', array_merge([ + $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/' . $this->providerRepositoryId . '/detection', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'installationId' => $installationId, - 'providerRepositoryId' => $providerRepositoryId + 'installationId' => $this->installationId, + 'providerRepositoryId' => $this->providerRepositoryId ]); $this->assertEquals(200, $runtime['headers']['status-code']); @@ -45,27 +56,27 @@ class VCSConsoleClientTest extends Scope // $this->assertEquals(404, $runtime['headers']['status-code']); } - public function testListRepositories(string $installationId = '651c6d27dac46cc3bc99') + public function testListRepositories() { /** * Test for SUCCESS */ - $repositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories', array_merge([ + $repositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'installationId' => $installationId + 'installationId' => $this->installationId ]); $this->assertEquals(200, $repositories['headers']['status-code']); $this->assertEquals($repositories['body']['total'], 3); - $searchedRepositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories', array_merge([ + $searchedRepositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'installationId' => $installationId, + 'installationId' => $this->installationId, 'search' => 'func' ]); @@ -73,28 +84,28 @@ class VCSConsoleClientTest extends Scope $this->assertEquals($searchedRepositories['body']['total'], 1); } - public function testGetRepository(string $installationId = '651c6d27dac46cc3bc99', string $providerRepositoryId = '700022615', string $providerRepositoryId2 = '700020051') + public function testGetRepository(string $providerRepositoryId2 = '700020051') { /** * Test for SUCCESS */ - $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $providerRepositoryId, array_merge([ + $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/' . $this->providerRepositoryId, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'installationId' => $installationId, - 'providerRepositoryId' => $providerRepositoryId + 'installationId' => $this->installationId, + 'providerRepositoryId' => $this->providerRepositoryId ]); $this->assertEquals(200, $repository['headers']['status-code']); $this->assertEquals($repository['body']['name'], 'ruby-starter'); - $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $providerRepositoryId2, array_merge([ + $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/' . $providerRepositoryId2, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'installationId' => $installationId, + 'installationId' => $this->installationId, 'providerRepositoryId' => $providerRepositoryId2 ]); @@ -102,18 +113,18 @@ class VCSConsoleClientTest extends Scope $this->assertEquals($repository['body']['name'], 'function-1.4'); } - public function testListRepositoryBranches(string $installationId = '651c6d27dac46cc3bc99', string $providerRepositoryId = '700020051') + public function testListRepositoryBranches() { /** * Test for SUCCESS */ - $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $providerRepositoryId . '/branches', array_merge([ + $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/' . $this->providerRepositoryId . '/branches', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'installationId' => $installationId, - 'providerRepositoryId' => $providerRepositoryId + 'installationId' => $this->installationId, + 'providerRepositoryId' => $this->providerRepositoryId ]); $this->assertEquals(200, $repositoryBranches['headers']['status-code']); @@ -122,19 +133,19 @@ class VCSConsoleClientTest extends Scope $this->assertEquals($repositoryBranches['body']['branches'][1]['name'], 'test'); } - // public function testGetInstallation(string $installationId = '651c6d27dac46cc3bc99') - // { - // /** - // * Test for SUCCESS - // */ + public function testGetInstallation() + { + /** + * Test for SUCCESS + */ - // $installation = $this->client->call(Client::METHOD_GET, '/vcs/installations/' . $installationId, array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'], - // ], $this->getHeaders()), [ - // 'installationId' => $installationId - // ]); + $installation = $this->client->call(Client::METHOD_GET, '/vcs/installations/' . $this->installationId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'installationId' => $this->installationId + ]); - // $this->assertEquals(200, $installation['headers']['status-code']); - // } + $this->assertEquals(200, $installation['headers']['status-code']); + } } From dbd6dbcb5b62c637e78de732262a4d76f127ad5e Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Wed, 11 Oct 2023 02:56:15 +0530 Subject: [PATCH 03/19] WIP: Progress with VCS tests --- .../e2e/Services/VCS/VCSConsoleClientTest.php | 84 +++++++++++++++---- 1 file changed, 69 insertions(+), 15 deletions(-) diff --git a/tests/e2e/Services/VCS/VCSConsoleClientTest.php b/tests/e2e/Services/VCS/VCSConsoleClientTest.php index 178d6de86d..b9df0197f4 100644 --- a/tests/e2e/Services/VCS/VCSConsoleClientTest.php +++ b/tests/e2e/Services/VCS/VCSConsoleClientTest.php @@ -44,13 +44,24 @@ class VCSConsoleClientTest extends Scope * Test for FAILURE */ - // $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $providerRepositoryId .'/detection', array_merge([ + // $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/1234/detection', array_merge([ // 'content-type' => 'application/json', // 'x-appwrite-project' => $this->getProject()['$id'], // ], $this->getHeaders()), [ - // 'installationId' => $installationId, - // 'providerRepositoryId' => $providerRepositoryId, - // 'providerRootDirectory' => 'src' + // 'installationId' => $this->installationId, + // 'providerRepositoryId' => 1234 + // ]); + + // $this->assertEquals(404, $runtime['headers']['status-code']); + // TODO: throw 404 from GitHub.php if repo not found + + // $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/' . $this->providerRepositoryId .'/detection', array_merge([ + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ], $this->getHeaders()), [ + // 'installationId' => $this->installationId, + // 'providerRepositoryId' => $this->providerRepositoryId, + // 'providerRootDirectory' => ''̦ // ]); // $this->assertEquals(404, $runtime['headers']['status-code']); @@ -82,6 +93,19 @@ class VCSConsoleClientTest extends Scope $this->assertEquals(200, $searchedRepositories['headers']['status-code']); $this->assertEquals($searchedRepositories['body']['total'], 1); + + /** + * Test for FAILURE + */ + + $repositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/1234/providerRepositories', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'installationId' => 1234 + ]); + + $this->assertEquals(404, $repositories['headers']['status-code']); } public function testGetRepository(string $providerRepositoryId2 = '700020051') @@ -111,6 +135,21 @@ class VCSConsoleClientTest extends Scope $this->assertEquals(200, $repository['headers']['status-code']); $this->assertEquals($repository['body']['name'], 'function-1.4'); + + /** + * Test for FAILURE + */ + + // $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/1234', array_merge([ + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ], $this->getHeaders()), [ + // 'installationId' => $this->installationId, + // 'providerRepositoryId' => 1234 + // ]); + + // $this->assertEquals(404, $repository['headers']['status-code']); + // TODO: Throw 404 if repository not found } public function testListRepositoryBranches() @@ -131,21 +170,36 @@ class VCSConsoleClientTest extends Scope $this->assertEquals($repositoryBranches['body']['total'], 2); $this->assertEquals($repositoryBranches['body']['branches'][0]['name'], 'main'); $this->assertEquals($repositoryBranches['body']['branches'][1]['name'], 'test'); - } - public function testGetInstallation() - { /** - * Test for SUCCESS + * Test for FAILURE */ - $installation = $this->client->call(Client::METHOD_GET, '/vcs/installations/' . $this->installationId, array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'installationId' => $this->installationId - ]); + // $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/1234/branches', array_merge([ + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ], $this->getHeaders()), [ + // 'installationId' => $this->installationId, + // 'providerRepositoryId' => 1234 + // ]); - $this->assertEquals(200, $installation['headers']['status-code']); + // $this->assertEquals(404, $repositoryBranches['headers']['status-code']); + // TODO: Check why it's throwing 500 server error } + + // public function testGetInstallation() + // { + // /** + // * Test for SUCCESS + // */ + + // $installation = $this->client->call(Client::METHOD_GET, '/vcs/installations/' . $this->installationId, array_merge([ + // 'content-type' => 'application/json', + // 'x-appwrite-project' => $this->getProject()['$id'], + // ], $this->getHeaders()), [ + // 'installationId' => $this->installationId + // ]); + + // $this->assertEquals(200, $installation['headers']['status-code']); + // } } From bb75036efef7e082c52a3a5eeb465a2af708eafa Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Fri, 13 Oct 2023 01:45:27 +0530 Subject: [PATCH 04/19] WIP: Mocked GitHub installation --- .env | 2 +- app/controllers/api/vcs.php | 3 +- app/controllers/mock.php | 66 ++++++++++ docker-compose.yml | 2 +- .../e2e/Services/VCS/VCSConsoleClientTest.php | 115 +++++++++++------- 5 files changed, 142 insertions(+), 46 deletions(-) diff --git a/.env b/.env index 6c97639b66..c34e165208 100644 --- a/.env +++ b/.env @@ -96,7 +96,7 @@ _APP_VCS_GITHUB_APP_ID= _APP_VCS_GITHUB_CLIENT_ID= _APP_VCS_GITHUB_CLIENT_SECRET= _APP_VCS_GITHUB_WEBHOOK_SECRET= -_APP_VCS_TEST_INSTALLATION_ID= +_APP_VCS_TEST_GITHUB_INSTALLATION_ID= _APP_VCS_TEST_PROVIDER_REPOSITORY_ID= _APP_MIGRATIONS_FIREBASE_CLIENT_ID= _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET= diff --git a/app/controllers/api/vcs.php b/app/controllers/api/vcs.php index b0050c61d4..f3dcceb887 100644 --- a/app/controllers/api/vcs.php +++ b/app/controllers/api/vcs.php @@ -22,7 +22,6 @@ use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; -use Utopia\Database\Validator\UID; use Utopia\Detector\Adapter\Bun; use Utopia\Detector\Adapter\CPP; use Utopia\Detector\Adapter\Dart; @@ -274,7 +273,7 @@ App::get('/v1/vcs/github/callback') ->label('scope', 'public') ->label('error', __DIR__ . '/../../views/general/error.phtml') ->param('installation_id', '', new Text(256, 0), 'GitHub installation ID', true) - ->param('setup_action', '', new Text(256, 0), 'GitHub setup actuon type', true) + ->param('setup_action', '', new Text(256, 0), 'GitHub setup action type', true) ->param('state', '', new Text(2048), 'GitHub state. Contains info sent when starting authorization flow.', true) ->param('code', '', new Text(2048, 0), 'OAuth2 code. This is a temporary code that the will be later exchanged for an access token.', true) ->inject('gitHub') diff --git a/app/controllers/mock.php b/app/controllers/mock.php index 593063ae84..319861d69b 100644 --- a/app/controllers/mock.php +++ b/app/controllers/mock.php @@ -17,6 +17,9 @@ use Utopia\Validator\WhiteList; use Utopia\Database\Helpers\ID; use Utopia\Database\Validator\UID; use Utopia\Validator\Nullable; +use Utopia\VCS\Adapter\Git\GitHub; +use Utopia\Database\Helpers\Permission; +use Utopia\Database\Helpers\Role; App::get('/v1/mock/tests/foo') ->desc('Get Foo') @@ -646,6 +649,69 @@ App::patch('/v1/mock/functions-v2') $response->noContent(); }); + App::get('/v1/mock/github/callback') + ->desc('Create installation document using GitHub installation id') + ->groups(['mock', 'api', 'vcs']) + ->label('scope', 'public') + ->param('installation_id', '', new Text(256, 0), 'GitHub installation ID', true) + ->param('projectId', '', new Text(2048), 'Project ID of the project where app is to be installed', true) + ->inject('gitHub') + ->inject('project') + ->inject('response') + ->inject('dbForConsole') + ->action(function (string $providerInstallationId, string $projectId, GitHub $github, Document $project, Response $response, Database $dbForConsole) { + if (empty($projectId)) { + $error = 'Installation requests from organisation members for the Appwrite GitHub App are currently unsupported. To proceed with the installation, login to the Appwrite Console and install the GitHub App.'; + throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $error); + } + + $project = $dbForConsole->getDocument('projects', $projectId); + + if ($project->isEmpty()) { + $error = 'Project with the ID from state could not be found.'; + throw new Exception(Exception::PROJECT_NOT_FOUND, $error); + } + + // Create / Update installation + if (!empty($providerInstallationId)) { + $privateKey = App::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY'); + $githubAppId = App::getEnv('_APP_VCS_GITHUB_APP_ID'); + $github->initializeVariables($providerInstallationId, $privateKey, $githubAppId); + $owner = $github->getOwnerName($providerInstallationId) ?? ''; + + $projectInternalId = $project->getInternalId(); + + $teamId = $project->getAttribute('teamId', ''); + + $installation = 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')), + ], + 'providerInstallationId' => $providerInstallationId, + 'projectId' => $projectId, + 'projectInternalId' => $projectInternalId, + 'provider' => 'github', + 'organization' => $owner, + 'personal' => true + ]); + + $installation = $dbForConsole->createDocument('installations', $installation); + } else { + $error = 'Installation of the Appwrite GitHub App on organization accounts is restricted to organization owners. As a member of the organization, you do not have the necessary permissions to install this GitHub App. Please contact the organization owner to create the installation from the Appwrite console.'; + + throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $error); + } + + $response->json([ + 'installationId' => $installation->getId(), + ]); + }); + App::shutdown() ->groups(['mock']) ->inject('utopia') diff --git a/docker-compose.yml b/docker-compose.yml index df4c2d756e..c6a3f56616 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -185,7 +185,7 @@ services: - _APP_VCS_GITHUB_WEBHOOK_SECRET - _APP_VCS_GITHUB_CLIENT_SECRET - _APP_VCS_GITHUB_CLIENT_ID - - _APP_VCS_TEST_INSTALLATION_ID + - _APP_VCS_TEST_GITHUB_INSTALLATION_ID - _APP_VCS_TEST_PROVIDER_REPOSITORY_ID - _APP_MIGRATIONS_FIREBASE_CLIENT_ID - _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET diff --git a/tests/e2e/Services/VCS/VCSConsoleClientTest.php b/tests/e2e/Services/VCS/VCSConsoleClientTest.php index b9df0197f4..14a4fc0272 100644 --- a/tests/e2e/Services/VCS/VCSConsoleClientTest.php +++ b/tests/e2e/Services/VCS/VCSConsoleClientTest.php @@ -13,27 +13,65 @@ class VCSConsoleClientTest extends Scope use ProjectCustom; use SideConsole; - public ?string $installationId = null; public ?string $providerRepositoryId = null; protected function setUp(): void { parent::setUp(); - $this->installationId = App::getEnv('_APP_VCS_TEST_INSTALLATION_ID'); $this->providerRepositoryId = App::getEnv('_APP_VCS_TEST_PROVIDER_REPOSITORY_ID'); } - public function testDetectRuntime() + public function testGitHubAuthorize() + { + /** + * Test for SUCCESS + */ + $response = $this->client->call(Client::METHOD_GET, '/mock/github/callback', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'installation_id' => App::getEnv('_APP_VCS_TEST_GITHUB_INSTALLATION_ID'), + 'projectId' => $this->getProject()['$id'], + ]); + + $this->assertNotEmpty($response['body']['installationId']); + $installationId = $response['body']['installationId']; + return $installationId; + } + + /** + * @depends testGitHubAuthorize + */ + public function testGetInstallation(string $installationId) { /** * Test for SUCCESS */ - $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/' . $this->providerRepositoryId . '/detection', array_merge([ + $installation = $this->client->call(Client::METHOD_GET, '/vcs/installations/' . $installationId, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'installationId' => $this->installationId, + 'installationId' => $installationId + ]); + + $this->assertEquals(200, $installation['headers']['status-code']); + } + + /** + * @depends testGitHubAuthorize + */ + public function testDetectRuntime(string $installationId) + { + /** + * Test for SUCCESS + */ + + $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $this->providerRepositoryId . '/detection', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'installationId' => $installationId, 'providerRepositoryId' => $this->providerRepositoryId ]); @@ -44,22 +82,22 @@ class VCSConsoleClientTest extends Scope * Test for FAILURE */ - // $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/1234/detection', array_merge([ + // $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories/1234/detection', array_merge([ // 'content-type' => 'application/json', // 'x-appwrite-project' => $this->getProject()['$id'], // ], $this->getHeaders()), [ - // 'installationId' => $this->installationId, + // 'installationId' => $installationId, // 'providerRepositoryId' => 1234 // ]); // $this->assertEquals(404, $runtime['headers']['status-code']); // TODO: throw 404 from GitHub.php if repo not found - // $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/' . $this->providerRepositoryId .'/detection', array_merge([ + // $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $this->providerRepositoryId .'/detection', array_merge([ // 'content-type' => 'application/json', // 'x-appwrite-project' => $this->getProject()['$id'], // ], $this->getHeaders()), [ - // 'installationId' => $this->installationId, + // 'installationId' => $installationId, // 'providerRepositoryId' => $this->providerRepositoryId, // 'providerRootDirectory' => ''̦ // ]); @@ -67,27 +105,30 @@ class VCSConsoleClientTest extends Scope // $this->assertEquals(404, $runtime['headers']['status-code']); } - public function testListRepositories() + /** + * @depends testGitHubAuthorize + */ + public function testListRepositories(string $installationId) { /** * Test for SUCCESS */ - $repositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories', array_merge([ + $repositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'installationId' => $this->installationId + 'installationId' => $installationId ]); $this->assertEquals(200, $repositories['headers']['status-code']); $this->assertEquals($repositories['body']['total'], 3); - $searchedRepositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories', array_merge([ + $searchedRepositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'installationId' => $this->installationId, + 'installationId' => $installationId, 'search' => 'func' ]); @@ -108,28 +149,31 @@ class VCSConsoleClientTest extends Scope $this->assertEquals(404, $repositories['headers']['status-code']); } - public function testGetRepository(string $providerRepositoryId2 = '700020051') + /** + * @depends testGitHubAuthorize + */ + public function testGetRepository(string $installationId, string $providerRepositoryId2 = '700020051') { /** * Test for SUCCESS */ - $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/' . $this->providerRepositoryId, array_merge([ + $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $this->providerRepositoryId, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'installationId' => $this->installationId, + 'installationId' => $installationId, 'providerRepositoryId' => $this->providerRepositoryId ]); $this->assertEquals(200, $repository['headers']['status-code']); $this->assertEquals($repository['body']['name'], 'ruby-starter'); - $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/' . $providerRepositoryId2, array_merge([ + $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $providerRepositoryId2, array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'installationId' => $this->installationId, + 'installationId' => $installationId, 'providerRepositoryId' => $providerRepositoryId2 ]); @@ -140,11 +184,11 @@ class VCSConsoleClientTest extends Scope * Test for FAILURE */ - // $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/1234', array_merge([ + // $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/1234', array_merge([ // 'content-type' => 'application/json', // 'x-appwrite-project' => $this->getProject()['$id'], // ], $this->getHeaders()), [ - // 'installationId' => $this->installationId, + // 'installationId' => $installationId, // 'providerRepositoryId' => 1234 // ]); @@ -152,17 +196,20 @@ class VCSConsoleClientTest extends Scope // TODO: Throw 404 if repository not found } - public function testListRepositoryBranches() + /** + * @depends testGitHubAuthorize + */ + public function testListRepositoryBranches(string $installationId) { /** * Test for SUCCESS */ - $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/' . $this->providerRepositoryId . '/branches', array_merge([ + $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $this->providerRepositoryId . '/branches', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'installationId' => $this->installationId, + 'installationId' => $installationId, 'providerRepositoryId' => $this->providerRepositoryId ]); @@ -175,31 +222,15 @@ class VCSConsoleClientTest extends Scope * Test for FAILURE */ - // $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $this->installationId . '/providerRepositories/1234/branches', array_merge([ + // $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/1234/branches', array_merge([ // 'content-type' => 'application/json', // 'x-appwrite-project' => $this->getProject()['$id'], // ], $this->getHeaders()), [ - // 'installationId' => $this->installationId, + // 'installationId' => $installationId, // 'providerRepositoryId' => 1234 // ]); // $this->assertEquals(404, $repositoryBranches['headers']['status-code']); // TODO: Check why it's throwing 500 server error } - - // public function testGetInstallation() - // { - // /** - // * Test for SUCCESS - // */ - - // $installation = $this->client->call(Client::METHOD_GET, '/vcs/installations/' . $this->installationId, array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'], - // ], $this->getHeaders()), [ - // 'installationId' => $this->installationId - // ]); - - // $this->assertEquals(200, $installation['headers']['status-code']); - // } } From 615bd5148e2bf7f89cd82dade250e5bab62029ab Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Fri, 13 Oct 2023 03:11:31 +0530 Subject: [PATCH 05/19] Test for create and update function using VCS --- .../e2e/Services/VCS/VCSConsoleClientTest.php | 83 +++++++++++++++++-- 1 file changed, 74 insertions(+), 9 deletions(-) diff --git a/tests/e2e/Services/VCS/VCSConsoleClientTest.php b/tests/e2e/Services/VCS/VCSConsoleClientTest.php index 14a4fc0272..5a4782867c 100644 --- a/tests/e2e/Services/VCS/VCSConsoleClientTest.php +++ b/tests/e2e/Services/VCS/VCSConsoleClientTest.php @@ -7,6 +7,8 @@ use Tests\E2E\Client; use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\SideConsole; use Utopia\App; +use Utopia\Database\Helpers\ID; +use Utopia\Database\Helpers\Role; class VCSConsoleClientTest extends Scope { @@ -82,12 +84,12 @@ class VCSConsoleClientTest extends Scope * Test for FAILURE */ - // $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories/1234/detection', array_merge([ + // $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories/randomRepositoryId/detection', array_merge([ // 'content-type' => 'application/json', // 'x-appwrite-project' => $this->getProject()['$id'], // ], $this->getHeaders()), [ // 'installationId' => $installationId, - // 'providerRepositoryId' => 1234 + // 'providerRepositoryId' => 'randomRepositoryId' // ]); // $this->assertEquals(404, $runtime['headers']['status-code']); @@ -139,11 +141,11 @@ class VCSConsoleClientTest extends Scope * Test for FAILURE */ - $repositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/1234/providerRepositories', array_merge([ + $repositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/randomInstallationId/providerRepositories', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'installationId' => 1234 + 'installationId' => 'randomInstallationId' ]); $this->assertEquals(404, $repositories['headers']['status-code']); @@ -184,12 +186,12 @@ class VCSConsoleClientTest extends Scope * Test for FAILURE */ - // $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/1234', array_merge([ + // $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/randomRepositoryId', array_merge([ // 'content-type' => 'application/json', // 'x-appwrite-project' => $this->getProject()['$id'], // ], $this->getHeaders()), [ // 'installationId' => $installationId, - // 'providerRepositoryId' => 1234 + // 'providerRepositoryId' => 'randomRepositoryId' // ]); // $this->assertEquals(404, $repository['headers']['status-code']); @@ -222,15 +224,78 @@ class VCSConsoleClientTest extends Scope * Test for FAILURE */ - // $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/1234/branches', array_merge([ + // $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/randomRepositoryId/branches', array_merge([ // 'content-type' => 'application/json', // 'x-appwrite-project' => $this->getProject()['$id'], // ], $this->getHeaders()), [ // 'installationId' => $installationId, - // 'providerRepositoryId' => 1234 + // 'providerRepositoryId' => 'randomRepositoryId' // ]); // $this->assertEquals(404, $repositoryBranches['headers']['status-code']); - // TODO: Check why it's throwing 500 server error + // TODO: Throw error from listBranches + } + + /** + * @depends testGitHubAuthorize + */ + public function testCreateFunctionUsingVCS(string $installationId) + { + $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'functionId' => ID::unique(), + 'name' => 'Test', + 'execute' => [Role::user($this->getUser()['$id'])->toString()], + 'runtime' => 'php-8.0', + 'entrypoint' => 'index.php', + 'events' => [ + 'users.*.create', + 'users.*.delete', + ], + 'schedule' => '0 0 1 1 *', + 'timeout' => 10, + 'installationId' => $installationId, + 'providerRepositoryId' => $this->providerRepositoryId, + 'providerBranch' => 'main', + ]); + + $this->assertEquals(201, $function['headers']['status-code']); + + return [ + 'installationId' => $installationId, + 'functionId' => $function['body']['$id'] + ]; + } + + /** + * @depends testCreateFunctionUsingVCS + */ + public function testUpdateFunctionUsingVCS(array $data, string $providerRepositoryId2 = '700020051') + { + $function = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'], array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'functionId' => ID::unique(), + 'name' => 'Test', + 'execute' => [Role::user($this->getUser()['$id'])->toString()], + 'runtime' => 'php-8.0', + 'entrypoint' => 'index.php', + 'events' => [ + 'users.*.create', + 'users.*.delete', + ], + 'schedule' => '0 0 1 1 *', + 'timeout' => 10, + 'installationId' => $data['installationId'], + 'providerRepositoryId' => $providerRepositoryId2, + 'providerBranch' => 'main', + ]); + + $this->assertEquals(200, $function['headers']['status-code']); + + return $function['body']['$id']; } } From 66ec7f2e1d96292ffc98cbe2de44522333c6331b Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Fri, 13 Oct 2023 18:50:58 +0530 Subject: [PATCH 06/19] VCS tests --- app/controllers/api/vcs.php | 19 +++--- app/controllers/mock.php | 2 +- composer.json | 2 +- composer.lock | 26 ++++---- tests/e2e/Services/VCS/VCSBase.php | 1 - .../e2e/Services/VCS/VCSConsoleClientTest.php | 62 +++++++------------ 6 files changed, 49 insertions(+), 63 deletions(-) diff --git a/app/controllers/api/vcs.php b/app/controllers/api/vcs.php index f3dcceb887..9b74f66cbe 100644 --- a/app/controllers/api/vcs.php +++ b/app/controllers/api/vcs.php @@ -35,6 +35,7 @@ use Utopia\Detector\Adapter\Ruby; use Utopia\Detector\Adapter\Swift; use Utopia\Detector\Detector; use Utopia\Validator\Boolean; +use Utopia\VCS\Exception\RepositoryNotFound; use function Swoole\Coroutine\batch; @@ -458,9 +459,9 @@ App::post('/v1/vcs/github/installations/:installationId/providerRepositories/:pr $github->initializeVariables($providerInstallationId, $privateKey, $githubAppId); $owner = $github->getOwnerName($providerInstallationId); - $repositoryName = $github->getRepositoryName($providerRepositoryId); - - if (empty($repositoryName)) { + try { + $repositoryName = $github->getRepositoryName($providerRepositoryId); + } catch (RepositoryNotFound $e) { throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); } @@ -720,9 +721,9 @@ App::get('/v1/vcs/github/installations/:installationId/providerRepositories/:pro $github->initializeVariables($providerInstallationId, $privateKey, $githubAppId); $owner = $github->getOwnerName($providerInstallationId) ?? ''; - $repositoryName = $github->getRepositoryName($providerRepositoryId) ?? ''; - - if (empty($repositoryName)) { + try { + $repositoryName = $github->getRepositoryName($providerRepositoryId) ?? ''; + } catch (RepositoryNotFound $e) { throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); } @@ -766,9 +767,9 @@ App::get('/v1/vcs/github/installations/:installationId/providerRepositories/:pro $github->initializeVariables($providerInstallationId, $privateKey, $githubAppId); $owner = $github->getOwnerName($providerInstallationId) ?? ''; - $repositoryName = $github->getRepositoryName($providerRepositoryId) ?? ''; - - if (empty($repositoryName)) { + try { + $repositoryName = $github->getRepositoryName($providerRepositoryId) ?? ''; + } catch (RepositoryNotFound $e) { throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); } diff --git a/app/controllers/mock.php b/app/controllers/mock.php index 319861d69b..271bf2b2b4 100644 --- a/app/controllers/mock.php +++ b/app/controllers/mock.php @@ -649,7 +649,7 @@ App::patch('/v1/mock/functions-v2') $response->noContent(); }); - App::get('/v1/mock/github/callback') +App::get('/v1/mock/github/callback') ->desc('Create installation document using GitHub installation id') ->groups(['mock', 'api', 'vcs']) ->label('scope', 'public') diff --git a/composer.json b/composer.json index 0d415677ce..dc8880c21b 100644 --- a/composer.json +++ b/composer.json @@ -66,7 +66,7 @@ "utopia-php/registry": "0.5.*", "utopia-php/storage": "0.17.*", "utopia-php/swoole": "0.5.*", - "utopia-php/vcs": "0.5.*", + "utopia-php/vcs": "0.6.*", "utopia-php/websocket": "0.1.*", "resque/php-resque": "1.3.6", "matomo/device-detector": "6.1.*", diff --git a/composer.lock b/composer.lock index 25589427e0..d01efe4f88 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "13a3bdc7c1dec5756bf58ec73a49753d", + "content-hash": "9fef5fb0274738d369f80b48741a2524", "packages": [ { "name": "adhocore/jwt", @@ -2152,16 +2152,16 @@ }, { "name": "utopia-php/database", - "version": "0.43.4", + "version": "0.43.5", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "cabdd02e8dc1732eb0b22007c511e7bb3caa5c8c" + "reference": "5f7b05189cfbcc0506090498c580c5765375a00a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/cabdd02e8dc1732eb0b22007c511e7bb3caa5c8c", - "reference": "cabdd02e8dc1732eb0b22007c511e7bb3caa5c8c", + "url": "https://api.github.com/repos/utopia-php/database/zipball/5f7b05189cfbcc0506090498c580c5765375a00a", + "reference": "5f7b05189cfbcc0506090498c580c5765375a00a", "shasum": "" }, "require": { @@ -2202,9 +2202,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.43.4" + "source": "https://github.com/utopia-php/database/tree/0.43.5" }, - "time": "2023-09-28T09:00:05+00:00" + "time": "2023-10-06T06:49:47+00:00" }, { "name": "utopia-php/domains", @@ -3151,16 +3151,16 @@ }, { "name": "utopia-php/vcs", - "version": "0.5.0", + "version": "0.6.0", "source": { "type": "git", "url": "https://github.com/utopia-php/vcs.git", - "reference": "47144f272030b7ed1b05471f2cb3aabeb8cb831c" + "reference": "be866170c42912f0d371421346a69f4f575eb116" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/vcs/zipball/47144f272030b7ed1b05471f2cb3aabeb8cb831c", - "reference": "47144f272030b7ed1b05471f2cb3aabeb8cb831c", + "url": "https://api.github.com/repos/utopia-php/vcs/zipball/be866170c42912f0d371421346a69f4f575eb116", + "reference": "be866170c42912f0d371421346a69f4f575eb116", "shasum": "" }, "require": { @@ -3194,9 +3194,9 @@ ], "support": { "issues": "https://github.com/utopia-php/vcs/issues", - "source": "https://github.com/utopia-php/vcs/tree/0.5.0" + "source": "https://github.com/utopia-php/vcs/tree/0.6.0" }, - "time": "2023-09-13T19:05:52+00:00" + "time": "2023-10-13T13:07:13+00:00" }, { "name": "utopia-php/websocket", diff --git a/tests/e2e/Services/VCS/VCSBase.php b/tests/e2e/Services/VCS/VCSBase.php index e26a113b04..66f1158027 100644 --- a/tests/e2e/Services/VCS/VCSBase.php +++ b/tests/e2e/Services/VCS/VCSBase.php @@ -4,5 +4,4 @@ namespace Tests\E2E\Services\VCS; trait VCSBase { - } diff --git a/tests/e2e/Services/VCS/VCSConsoleClientTest.php b/tests/e2e/Services/VCS/VCSConsoleClientTest.php index 5a4782867c..9375f89266 100644 --- a/tests/e2e/Services/VCS/VCSConsoleClientTest.php +++ b/tests/e2e/Services/VCS/VCSConsoleClientTest.php @@ -84,27 +84,15 @@ class VCSConsoleClientTest extends Scope * Test for FAILURE */ - // $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories/randomRepositoryId/detection', array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'], - // ], $this->getHeaders()), [ - // 'installationId' => $installationId, - // 'providerRepositoryId' => 'randomRepositoryId' - // ]); + $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories/randomRepositoryId/detection', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'installationId' => $installationId, + 'providerRepositoryId' => 'randomRepositoryId' + ]); - // $this->assertEquals(404, $runtime['headers']['status-code']); - // TODO: throw 404 from GitHub.php if repo not found - - // $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $this->providerRepositoryId .'/detection', array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'], - // ], $this->getHeaders()), [ - // 'installationId' => $installationId, - // 'providerRepositoryId' => $this->providerRepositoryId, - // 'providerRootDirectory' => ''̦ - // ]); - - // $this->assertEquals(404, $runtime['headers']['status-code']); + $this->assertEquals(404, $runtime['headers']['status-code']); } /** @@ -186,16 +174,15 @@ class VCSConsoleClientTest extends Scope * Test for FAILURE */ - // $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/randomRepositoryId', array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'], - // ], $this->getHeaders()), [ - // 'installationId' => $installationId, - // 'providerRepositoryId' => 'randomRepositoryId' - // ]); + $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/randomRepositoryId', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'installationId' => $installationId, + 'providerRepositoryId' => 'randomRepositoryId' + ]); - // $this->assertEquals(404, $repository['headers']['status-code']); - // TODO: Throw 404 if repository not found + $this->assertEquals(404, $repository['headers']['status-code']); } /** @@ -224,16 +211,15 @@ class VCSConsoleClientTest extends Scope * Test for FAILURE */ - // $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/randomRepositoryId/branches', array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'], - // ], $this->getHeaders()), [ - // 'installationId' => $installationId, - // 'providerRepositoryId' => 'randomRepositoryId' - // ]); + $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/randomRepositoryId/branches', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'installationId' => $installationId, + 'providerRepositoryId' => 'randomRepositoryId' + ]); - // $this->assertEquals(404, $repositoryBranches['headers']['status-code']); - // TODO: Throw error from listBranches + $this->assertEquals(404, $repositoryBranches['headers']['status-code']); } /** From fe7aa60a11cae95864ccaed27f1ac9176a5f7cec Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Fri, 13 Oct 2023 18:55:33 +0530 Subject: [PATCH 07/19] Updated composer.json --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 60424b89a4..d01efe4f88 100644 --- a/composer.lock +++ b/composer.lock @@ -2152,16 +2152,16 @@ }, { "name": "utopia-php/database", - "version": "0.43.4", + "version": "0.43.5", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "cabdd02e8dc1732eb0b22007c511e7bb3caa5c8c" + "reference": "5f7b05189cfbcc0506090498c580c5765375a00a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/cabdd02e8dc1732eb0b22007c511e7bb3caa5c8c", - "reference": "cabdd02e8dc1732eb0b22007c511e7bb3caa5c8c", + "url": "https://api.github.com/repos/utopia-php/database/zipball/5f7b05189cfbcc0506090498c580c5765375a00a", + "reference": "5f7b05189cfbcc0506090498c580c5765375a00a", "shasum": "" }, "require": { @@ -2202,9 +2202,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.43.4" + "source": "https://github.com/utopia-php/database/tree/0.43.5" }, - "time": "2023-09-28T09:00:05+00:00" + "time": "2023-10-06T06:49:47+00:00" }, { "name": "utopia-php/domains", From 2914a4d1c56315d0bb87f3aaf439b5cba104fe69 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Wed, 18 Oct 2023 13:24:32 +0530 Subject: [PATCH 08/19] Add test for createRepo endpoint --- app/controllers/mock.php | 2 +- docker-compose.yml | 1 - .../e2e/Services/VCS/VCSConsoleClientTest.php | 35 +++++++++++++++++-- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/app/controllers/mock.php b/app/controllers/mock.php index 271bf2b2b4..3ec8f42dd1 100644 --- a/app/controllers/mock.php +++ b/app/controllers/mock.php @@ -697,7 +697,7 @@ App::get('/v1/mock/github/callback') 'projectInternalId' => $projectInternalId, 'provider' => 'github', 'organization' => $owner, - 'personal' => true + 'personal' => false ]); $installation = $dbForConsole->createDocument('installations', $installation); diff --git a/docker-compose.yml b/docker-compose.yml index 3da0a68658..3054ddacda 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -186,7 +186,6 @@ services: - _APP_VCS_GITHUB_CLIENT_SECRET - _APP_VCS_GITHUB_CLIENT_ID - _APP_VCS_TEST_GITHUB_INSTALLATION_ID - - _APP_VCS_TEST_PROVIDER_REPOSITORY_ID - _APP_MIGRATIONS_FIREBASE_CLIENT_ID - _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET - _APP_ASSISTANT_OPENAI_API_KEY diff --git a/tests/e2e/Services/VCS/VCSConsoleClientTest.php b/tests/e2e/Services/VCS/VCSConsoleClientTest.php index 9375f89266..d610ddeb05 100644 --- a/tests/e2e/Services/VCS/VCSConsoleClientTest.php +++ b/tests/e2e/Services/VCS/VCSConsoleClientTest.php @@ -9,6 +9,9 @@ use Tests\E2E\Scopes\SideConsole; use Utopia\App; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Role; +use Utopia\VCS\Adapter\Git\GitHub; +use Utopia\Cache\Adapter\None; +use Utopia\Cache\Cache; class VCSConsoleClientTest extends Scope { @@ -20,7 +23,7 @@ class VCSConsoleClientTest extends Scope protected function setUp(): void { parent::setUp(); - $this->providerRepositoryId = App::getEnv('_APP_VCS_TEST_PROVIDER_REPOSITORY_ID'); + $this->providerRepositoryId = '705764267'; } public function testGitHubAuthorize() @@ -142,7 +145,7 @@ class VCSConsoleClientTest extends Scope /** * @depends testGitHubAuthorize */ - public function testGetRepository(string $installationId, string $providerRepositoryId2 = '700020051') + public function testGetRepository(string $installationId, string $providerRepositoryId2 = '705764449') { /** * Test for SUCCESS @@ -258,7 +261,7 @@ class VCSConsoleClientTest extends Scope /** * @depends testCreateFunctionUsingVCS */ - public function testUpdateFunctionUsingVCS(array $data, string $providerRepositoryId2 = '700020051') + public function testUpdateFunctionUsingVCS(array $data, string $providerRepositoryId2 = '705764449') { $function = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'], array_merge([ 'content-type' => 'application/json', @@ -284,4 +287,30 @@ class VCSConsoleClientTest extends Scope return $function['body']['$id']; } + + /** + * @depends testGitHubAuthorize + */ + public function testCreateRepository(string $installationId) + { + $github = new GitHub(new Cache(new None())); + $githubInstallationId = App::getEnv('_APP_VCS_TEST_GITHUB_INSTALLATION_ID'); + $privateKey = App::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY'); + $githubAppId = App::getEnv('_APP_VCS_GITHUB_APP_ID'); + $github->initializeVariables($githubInstallationId, $privateKey, $githubAppId); + + $repository = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'installationId' => $installationId, + 'name' => 'test-repo-1', + 'private' => true + ]); + + $this->assertEquals('test-repo-1', $repository['body']['name']); + + $result = $github->deleteRepository('appwrite-test', 'test-repo-1'); + // $this->assertEquals($result, true); + } } From eac911a006c4210a91d20514242d8eed17b8966e Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Wed, 18 Oct 2023 13:27:29 +0530 Subject: [PATCH 09/19] Remove VCS repo id from env variables --- .env | 1 - 1 file changed, 1 deletion(-) diff --git a/.env b/.env index c34e165208..513c54b14b 100644 --- a/.env +++ b/.env @@ -97,7 +97,6 @@ _APP_VCS_GITHUB_CLIENT_ID= _APP_VCS_GITHUB_CLIENT_SECRET= _APP_VCS_GITHUB_WEBHOOK_SECRET= _APP_VCS_TEST_GITHUB_INSTALLATION_ID= -_APP_VCS_TEST_PROVIDER_REPOSITORY_ID= _APP_MIGRATIONS_FIREBASE_CLIENT_ID= _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET= _APP_ASSISTANT_OPENAI_API_KEY= \ No newline at end of file From 97c1099961babfcd454e707ea9e54a2f9a9f592d Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Mon, 23 Oct 2023 15:03:24 +0530 Subject: [PATCH 10/19] Refactor code and add more assertions --- .env | 1 - app/controllers/mock.php | 25 ++-- composer.lock | 31 ++-- .../e2e/Services/VCS/VCSConsoleClientTest.php | 136 +++++++++--------- 4 files changed, 95 insertions(+), 98 deletions(-) diff --git a/.env b/.env index 513c54b14b..feeb74d849 100644 --- a/.env +++ b/.env @@ -96,7 +96,6 @@ _APP_VCS_GITHUB_APP_ID= _APP_VCS_GITHUB_CLIENT_ID= _APP_VCS_GITHUB_CLIENT_SECRET= _APP_VCS_GITHUB_WEBHOOK_SECRET= -_APP_VCS_TEST_GITHUB_INSTALLATION_ID= _APP_MIGRATIONS_FIREBASE_CLIENT_ID= _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET= _APP_ASSISTANT_OPENAI_API_KEY= \ No newline at end of file diff --git a/app/controllers/mock.php b/app/controllers/mock.php index 3ec8f42dd1..bc4f463b5c 100644 --- a/app/controllers/mock.php +++ b/app/controllers/mock.php @@ -251,8 +251,7 @@ App::get('/v1/mock/tests/general/download') ->addHeader('Content-Disposition', 'attachment; filename="test.txt"') ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache ->addHeader('X-Peak', \memory_get_peak_usage()) - ->send("GET:/v1/mock/tests/general/download:passed") - ; + ->send("GET:/v1/mock/tests/general/download:passed"); }); App::post('/v1/mock/tests/general/upload') @@ -334,7 +333,7 @@ App::post('/v1/mock/tests/general/upload') } if ($file['size'] !== 38756) { - throw new Exception(Exception::GENERAL_MOCK, 'Wrong file size'); + throw new Exception(Exception::GENERAL_MOCK, 'Wrong file size'); } if (\md5(\file_get_contents($file['tmp_name'])) !== 'd80e7e6999a3eb2ae0d631a96fe135a4') { @@ -509,8 +508,7 @@ App::get('/v1/mock/tests/general/502-error') $response ->setStatusCode(502) - ->text('This is a text error') - ; + ->text('This is a text error'); }); App::get('/v1/mock/tests/general/oauth2') @@ -653,16 +651,18 @@ App::get('/v1/mock/github/callback') ->desc('Create installation document using GitHub installation id') ->groups(['mock', 'api', 'vcs']) ->label('scope', 'public') - ->param('installation_id', '', new Text(256, 0), 'GitHub installation ID', true) - ->param('projectId', '', new Text(2048), 'Project ID of the project where app is to be installed', true) + ->label('docs', false) + ->param('providerInstallationId', '', new UID(), 'GitHub installation ID') + ->param('projectId', '', new UID(), 'Project ID of the project where app is to be installed') ->inject('gitHub') ->inject('project') ->inject('response') ->inject('dbForConsole') ->action(function (string $providerInstallationId, string $projectId, GitHub $github, Document $project, Response $response, Database $dbForConsole) { - if (empty($projectId)) { - $error = 'Installation requests from organisation members for the Appwrite GitHub App are currently unsupported. To proceed with the installation, login to the Appwrite Console and install the GitHub App.'; - throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $error); + $isDevelopment = App::getEnv('_APP_ENV', 'development') === 'development'; + + if (!$isDevelopment) { + throw new Exception(Exception::GENERAL_NOT_IMPLEMENTED); } $project = $dbForConsole->getDocument('projects', $projectId); @@ -672,7 +672,6 @@ App::get('/v1/mock/github/callback') throw new Exception(Exception::PROJECT_NOT_FOUND, $error); } - // Create / Update installation if (!empty($providerInstallationId)) { $privateKey = App::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY'); $githubAppId = App::getEnv('_APP_VCS_GITHUB_APP_ID'); @@ -701,10 +700,6 @@ App::get('/v1/mock/github/callback') ]); $installation = $dbForConsole->createDocument('installations', $installation); - } else { - $error = 'Installation of the Appwrite GitHub App on organization accounts is restricted to organization owners. As a member of the organization, you do not have the necessary permissions to install this GitHub App. Please contact the organization owner to create the installation from the Appwrite console.'; - - throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $error); } $response->json([ diff --git a/composer.lock b/composer.lock index d01efe4f88..ccaa106bae 100644 --- a/composer.lock +++ b/composer.lock @@ -156,11 +156,11 @@ }, { "name": "appwrite/php-runtimes", - "version": "0.13.0", + "version": "0.13.1", "source": { "type": "git", "url": "https://github.com/appwrite/runtimes.git", - "reference": "5ab496b3908992b39275994a23783701c4b3de84" + "reference": "b584d19cdcd82737d0ee5c34d23de791f5ed3610" }, "require": { "php": ">=8.0", @@ -195,7 +195,7 @@ "php", "runtimes" ], - "time": "2023-09-12T19:38:43+00:00" + "time": "2023-10-16T15:39:53+00:00" }, { "name": "chillerlan/php-qrcode", @@ -2463,22 +2463,23 @@ }, { "name": "utopia-php/logger", - "version": "0.3.1", + "version": "0.3.2", "source": { "type": "git", "url": "https://github.com/utopia-php/logger.git", - "reference": "de623f1ec1c672c795d113dd25c5bf212f7ef4fc" + "reference": "9151b7d16eab18d4c37c34643041cc0f33ca4a6c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/logger/zipball/de623f1ec1c672c795d113dd25c5bf212f7ef4fc", - "reference": "de623f1ec1c672c795d113dd25c5bf212f7ef4fc", + "url": "https://api.github.com/repos/utopia-php/logger/zipball/9151b7d16eab18d4c37c34643041cc0f33ca4a6c", + "reference": "9151b7d16eab18d4c37c34643041cc0f33ca4a6c", "shasum": "" }, "require": { "php": ">=8.0" }, "require-dev": { + "laravel/pint": "1.2.*", "phpstan/phpstan": "1.9.x-dev", "phpunit/phpunit": "^9.3", "vimeo/psalm": "4.0.1" @@ -2510,9 +2511,9 @@ ], "support": { "issues": "https://github.com/utopia-php/logger/issues", - "source": "https://github.com/utopia-php/logger/tree/0.3.1" + "source": "https://github.com/utopia-php/logger/tree/0.3.2" }, - "time": "2023-02-10T15:52:50+00:00" + "time": "2023-10-16T08:16:19+00:00" }, { "name": "utopia-php/messaging", @@ -3151,16 +3152,16 @@ }, { "name": "utopia-php/vcs", - "version": "0.6.0", + "version": "0.6.1", "source": { "type": "git", "url": "https://github.com/utopia-php/vcs.git", - "reference": "be866170c42912f0d371421346a69f4f575eb116" + "reference": "d161d1156ef336d197a8d45384b531e5ec31243d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/vcs/zipball/be866170c42912f0d371421346a69f4f575eb116", - "reference": "be866170c42912f0d371421346a69f4f575eb116", + "url": "https://api.github.com/repos/utopia-php/vcs/zipball/d161d1156ef336d197a8d45384b531e5ec31243d", + "reference": "d161d1156ef336d197a8d45384b531e5ec31243d", "shasum": "" }, "require": { @@ -3194,9 +3195,9 @@ ], "support": { "issues": "https://github.com/utopia-php/vcs/issues", - "source": "https://github.com/utopia-php/vcs/tree/0.6.0" + "source": "https://github.com/utopia-php/vcs/tree/0.6.1" }, - "time": "2023-10-13T13:07:13+00:00" + "time": "2023-10-19T07:43:31+00:00" }, { "name": "utopia-php/websocket", diff --git a/tests/e2e/Services/VCS/VCSConsoleClientTest.php b/tests/e2e/Services/VCS/VCSConsoleClientTest.php index d610ddeb05..0b76610ade 100644 --- a/tests/e2e/Services/VCS/VCSConsoleClientTest.php +++ b/tests/e2e/Services/VCS/VCSConsoleClientTest.php @@ -18,13 +18,9 @@ class VCSConsoleClientTest extends Scope use ProjectCustom; use SideConsole; - public ?string $providerRepositoryId = null; - - protected function setUp(): void - { - parent::setUp(); - $this->providerRepositoryId = '705764267'; - } + public string $providerInstallationId = '42954928'; + public string $providerRepositoryId = '705764267'; + public string $providerRepositoryId2 = '708688544'; public function testGitHubAuthorize() { @@ -32,10 +28,9 @@ class VCSConsoleClientTest extends Scope * Test for SUCCESS */ $response = $this->client->call(Client::METHOD_GET, '/mock/github/callback', array_merge([ - 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'installation_id' => App::getEnv('_APP_VCS_TEST_GITHUB_INSTALLATION_ID'), + 'providerInstallationId' => $this->providerInstallationId, 'projectId' => $this->getProject()['$id'], ]); @@ -54,13 +49,12 @@ class VCSConsoleClientTest extends Scope */ $installation = $this->client->call(Client::METHOD_GET, '/vcs/installations/' . $installationId, array_merge([ - 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'installationId' => $installationId - ]); + ], $this->getHeaders())); $this->assertEquals(200, $installation['headers']['status-code']); + $this->assertEquals('github', $installation['body']['provider']); + $this->assertEquals('appwrite-test', $installation['body']['organization']); } /** @@ -73,12 +67,8 @@ class VCSConsoleClientTest extends Scope */ $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $this->providerRepositoryId . '/detection', array_merge([ - 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'installationId' => $installationId, - 'providerRepositoryId' => $this->providerRepositoryId - ]); + ], $this->getHeaders())); $this->assertEquals(200, $runtime['headers']['status-code']); $this->assertEquals($runtime['body']['runtime'], 'ruby-3.1'); @@ -88,12 +78,8 @@ class VCSConsoleClientTest extends Scope */ $runtime = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories/randomRepositoryId/detection', array_merge([ - 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'installationId' => $installationId, - 'providerRepositoryId' => 'randomRepositoryId' - ]); + ], $this->getHeaders())); $this->assertEquals(404, $runtime['headers']['status-code']); } @@ -108,36 +94,35 @@ class VCSConsoleClientTest extends Scope */ $repositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories', array_merge([ - 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'installationId' => $installationId - ]); + ], $this->getHeaders())); $this->assertEquals(200, $repositories['headers']['status-code']); $this->assertEquals($repositories['body']['total'], 3); + $this->assertEquals($repositories['body']['providerRepositories'][0]['name'], 'function1.4'); + $this->assertEquals($repositories['body']['providerRepositories'][0]['organization'], 'appwrite-test'); + $this->assertEquals($repositories['body']['providerRepositories'][0]['provider'], 'github'); + $this->assertEquals($repositories['body']['providerRepositories'][1]['name'], 'appwrite'); + $this->assertEquals($repositories['body']['providerRepositories'][2]['name'], 'ruby-starter'); + $searchedRepositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories', array_merge([ - 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'installationId' => $installationId, 'search' => 'func' ]); $this->assertEquals(200, $searchedRepositories['headers']['status-code']); $this->assertEquals($searchedRepositories['body']['total'], 1); + $this->assertEquals($searchedRepositories['body']['providerRepositories'][0]['name'], 'function1.4'); /** * Test for FAILURE */ $repositories = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/randomInstallationId/providerRepositories', array_merge([ - 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'installationId' => 'randomInstallationId' - ]); + ], $this->getHeaders())); $this->assertEquals(404, $repositories['headers']['status-code']); } @@ -145,45 +130,37 @@ class VCSConsoleClientTest extends Scope /** * @depends testGitHubAuthorize */ - public function testGetRepository(string $installationId, string $providerRepositoryId2 = '705764449') + public function testGetRepository(string $installationId) { /** * Test for SUCCESS */ $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $this->providerRepositoryId, array_merge([ - 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'installationId' => $installationId, - 'providerRepositoryId' => $this->providerRepositoryId - ]); + ], $this->getHeaders())); $this->assertEquals(200, $repository['headers']['status-code']); $this->assertEquals($repository['body']['name'], 'ruby-starter'); + $this->assertEquals($repository['body']['organization'], 'appwrite-test'); + $this->assertEquals($repository['body']['private'], false); - $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $providerRepositoryId2, array_merge([ - 'content-type' => 'application/json', + $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $this->providerRepositoryId2, array_merge([ 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'installationId' => $installationId, - 'providerRepositoryId' => $providerRepositoryId2 - ]); + ], $this->getHeaders())); $this->assertEquals(200, $repository['headers']['status-code']); - $this->assertEquals($repository['body']['name'], 'function-1.4'); + $this->assertEquals($repository['body']['name'], 'function1.4'); + $this->assertEquals($repository['body']['organization'], 'appwrite-test'); + $this->assertEquals($repository['body']['private'], true); /** * Test for FAILURE */ $repository = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/randomRepositoryId', array_merge([ - 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'installationId' => $installationId, - 'providerRepositoryId' => 'randomRepositoryId' - ]); + ], $this->getHeaders())); $this->assertEquals(404, $repository['headers']['status-code']); } @@ -198,12 +175,8 @@ class VCSConsoleClientTest extends Scope */ $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/' . $this->providerRepositoryId . '/branches', array_merge([ - 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'installationId' => $installationId, - 'providerRepositoryId' => $this->providerRepositoryId - ]); + ], $this->getHeaders())); $this->assertEquals(200, $repositoryBranches['headers']['status-code']); $this->assertEquals($repositoryBranches['body']['total'], 2); @@ -215,12 +188,8 @@ class VCSConsoleClientTest extends Scope */ $repositoryBranches = $this->client->call(Client::METHOD_GET, '/vcs/github/installations/' . $installationId . '/providerRepositories/randomRepositoryId/branches', array_merge([ - 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], - ], $this->getHeaders()), [ - 'installationId' => $installationId, - 'providerRepositoryId' => 'randomRepositoryId' - ]); + ], $this->getHeaders())); $this->assertEquals(404, $repositoryBranches['headers']['status-code']); } @@ -251,6 +220,11 @@ class VCSConsoleClientTest extends Scope ]); $this->assertEquals(201, $function['headers']['status-code']); + $this->assertEquals('Test', $function['body']['name']); + $this->assertEquals('php-8.0', $function['body']['runtime']); + $this->assertEquals('index.php', $function['body']['entrypoint']); + $this->assertEquals('705764267', $function['body']['providerRepositoryId']); + $this->assertEquals('main', $function['body']['providerBranch']); return [ 'installationId' => $installationId, @@ -261,7 +235,7 @@ class VCSConsoleClientTest extends Scope /** * @depends testCreateFunctionUsingVCS */ - public function testUpdateFunctionUsingVCS(array $data, string $providerRepositoryId2 = '705764449') + public function testUpdateFunctionUsingVCS(array $data) { $function = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'], array_merge([ 'content-type' => 'application/json', @@ -279,11 +253,16 @@ class VCSConsoleClientTest extends Scope 'schedule' => '0 0 1 1 *', 'timeout' => 10, 'installationId' => $data['installationId'], - 'providerRepositoryId' => $providerRepositoryId2, + 'providerRepositoryId' => $this->providerRepositoryId2, 'providerBranch' => 'main', ]); $this->assertEquals(200, $function['headers']['status-code']); + $this->assertEquals('Test', $function['body']['name']); + $this->assertEquals('php-8.0', $function['body']['runtime']); + $this->assertEquals('index.php', $function['body']['entrypoint']); + $this->assertEquals('708688544', $function['body']['providerRepositoryId']); + $this->assertEquals('main', $function['body']['providerBranch']); return $function['body']['$id']; } @@ -293,24 +272,47 @@ class VCSConsoleClientTest extends Scope */ public function testCreateRepository(string $installationId) { + /** + * Test for SUCCESS + */ + $github = new GitHub(new Cache(new None())); - $githubInstallationId = App::getEnv('_APP_VCS_TEST_GITHUB_INSTALLATION_ID'); $privateKey = App::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY'); $githubAppId = App::getEnv('_APP_VCS_GITHUB_APP_ID'); - $github->initializeVariables($githubInstallationId, $privateKey, $githubAppId); + $github->initializeVariables($this->providerInstallationId, $privateKey, $githubAppId); $repository = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories', array_merge([ 'content-type' => 'application/json', 'x-appwrite-project' => $this->getProject()['$id'], ], $this->getHeaders()), [ - 'installationId' => $installationId, 'name' => 'test-repo-1', 'private' => true ]); $this->assertEquals('test-repo-1', $repository['body']['name']); + $this->assertEquals('appwrite-test', $repository['body']['organization']); + $this->assertEquals('github', $repository['body']['provider']); + + /** + * Test for FAILURE + */ + + $repository = $this->client->call(Client::METHOD_POST, '/vcs/github/installations/' . $installationId . '/providerRepositories', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'name' => 'test-repo-1', + 'private' => true + ]); + + $this->assertEquals(400, $repository['headers']['status-code']); + $this->assertEquals('Provider Error: Repository creation failed. name already exists on this account', $repository['body']['message']); + + /** + * Test for SUCCESS + */ $result = $github->deleteRepository('appwrite-test', 'test-repo-1'); - // $this->assertEquals($result, true); + $this->assertEquals($result, true); } } From c7435e7e78d5697080788eb3d63033991fe4113d Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Mon, 23 Oct 2023 15:16:42 +0530 Subject: [PATCH 11/19] Remove unused value from docker-compose --- docker-compose.yml | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 19b991357f..b229609d5b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -185,7 +185,6 @@ services: - _APP_VCS_GITHUB_WEBHOOK_SECRET - _APP_VCS_GITHUB_CLIENT_SECRET - _APP_VCS_GITHUB_CLIENT_ID - - _APP_VCS_TEST_GITHUB_INSTALLATION_ID - _APP_MIGRATIONS_FIREBASE_CLIENT_ID - _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET - _APP_ASSISTANT_OPENAI_API_KEY @@ -212,6 +211,7 @@ services: - traefik.http.routers.appwrite_realtime_wss.rule=PathPrefix(`/v1/realtime`) - traefik.http.routers.appwrite_realtime_wss.service=appwrite_realtime - traefik.http.routers.appwrite_realtime_wss.tls=true + - traefik.http.routers.appwrite_realtime_wss.tls.certresolver=dns networks: - appwrite volumes: @@ -379,8 +379,6 @@ services: - _APP_DB_PASS - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - - _APP_WORKERS_NUM - - _APP_QUEUE_NAME appwrite-worker-builds: entrypoint: worker-builds @@ -723,7 +721,7 @@ services: hostname: appwrite-executor <<: *x-logging stop_signal: SIGINT - image: openruntimes/executor:0.4.5 + image: openruntimes/executor:0.4.3 restart: unless-stopped networks: - appwrite @@ -873,6 +871,7 @@ services: # MailCatcher - An SMTP server. Catches all system emails and displays them in a nice UI. # RequestCatcher - An HTTP server. Catches all system https calls and displays them using a simple HTTP API. Used to debug & tests webhooks and HTTP tasks # RedisCommander - A nice UI for exploring Redis data + # Resque - A nice UI for exploring Redis pub/sub, view the different queues workloads, pending and failed tasks # Chronograf - A nice UI for exploring InfluxDB data # Webgrind - A nice UI for exploring and debugging code-level stuff @@ -914,6 +913,19 @@ services: # ports: # - "8081:8081" + # resque: + # image: appwrite/resque-web:1.1.0 + # restart: unless-stopped + # networks: + # - appwrite + # ports: + # - "5678:5678" + # environment: + # - RESQUE_WEB_HOST=redis + # - RESQUE_WEB_PORT=6379 + # - RESQUE_WEB_HTTP_BASIC_AUTH_USER=user + # - RESQUE_WEB_HTTP_BASIC_AUTH_PASSWORD=password + # chronograf: # image: chronograf:1.6 # container_name: appwrite-chronograf From a09c4281c86275fd03146618b74347bcd45f4621 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Mon, 23 Oct 2023 15:18:48 +0530 Subject: [PATCH 12/19] Revert "Remove unused value from docker-compose" This reverts commit c7435e7e78d5697080788eb3d63033991fe4113d. --- docker-compose.yml | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index b229609d5b..19b991357f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -185,6 +185,7 @@ services: - _APP_VCS_GITHUB_WEBHOOK_SECRET - _APP_VCS_GITHUB_CLIENT_SECRET - _APP_VCS_GITHUB_CLIENT_ID + - _APP_VCS_TEST_GITHUB_INSTALLATION_ID - _APP_MIGRATIONS_FIREBASE_CLIENT_ID - _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET - _APP_ASSISTANT_OPENAI_API_KEY @@ -211,7 +212,6 @@ services: - traefik.http.routers.appwrite_realtime_wss.rule=PathPrefix(`/v1/realtime`) - traefik.http.routers.appwrite_realtime_wss.service=appwrite_realtime - traefik.http.routers.appwrite_realtime_wss.tls=true - - traefik.http.routers.appwrite_realtime_wss.tls.certresolver=dns networks: - appwrite volumes: @@ -379,6 +379,8 @@ services: - _APP_DB_PASS - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG + - _APP_WORKERS_NUM + - _APP_QUEUE_NAME appwrite-worker-builds: entrypoint: worker-builds @@ -721,7 +723,7 @@ services: hostname: appwrite-executor <<: *x-logging stop_signal: SIGINT - image: openruntimes/executor:0.4.3 + image: openruntimes/executor:0.4.5 restart: unless-stopped networks: - appwrite @@ -871,7 +873,6 @@ services: # MailCatcher - An SMTP server. Catches all system emails and displays them in a nice UI. # RequestCatcher - An HTTP server. Catches all system https calls and displays them using a simple HTTP API. Used to debug & tests webhooks and HTTP tasks # RedisCommander - A nice UI for exploring Redis data - # Resque - A nice UI for exploring Redis pub/sub, view the different queues workloads, pending and failed tasks # Chronograf - A nice UI for exploring InfluxDB data # Webgrind - A nice UI for exploring and debugging code-level stuff @@ -913,19 +914,6 @@ services: # ports: # - "8081:8081" - # resque: - # image: appwrite/resque-web:1.1.0 - # restart: unless-stopped - # networks: - # - appwrite - # ports: - # - "5678:5678" - # environment: - # - RESQUE_WEB_HOST=redis - # - RESQUE_WEB_PORT=6379 - # - RESQUE_WEB_HTTP_BASIC_AUTH_USER=user - # - RESQUE_WEB_HTTP_BASIC_AUTH_PASSWORD=password - # chronograf: # image: chronograf:1.6 # container_name: appwrite-chronograf From c0460289b79f0fd36f58001c2faa75169eebd422 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Mon, 23 Oct 2023 15:19:23 +0530 Subject: [PATCH 13/19] Remove unused value from docker-compose --- docker-compose.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 19b991357f..42091e5e46 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -185,7 +185,6 @@ services: - _APP_VCS_GITHUB_WEBHOOK_SECRET - _APP_VCS_GITHUB_CLIENT_SECRET - _APP_VCS_GITHUB_CLIENT_ID - - _APP_VCS_TEST_GITHUB_INSTALLATION_ID - _APP_MIGRATIONS_FIREBASE_CLIENT_ID - _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET - _APP_ASSISTANT_OPENAI_API_KEY From ad4db114bcd6a6b576bd78dbe5d3230e47aa24a0 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Mon, 23 Oct 2023 15:23:52 +0530 Subject: [PATCH 14/19] Updated composer.lock --- composer.lock | 102 +++++++++----------------------------------------- 1 file changed, 17 insertions(+), 85 deletions(-) diff --git a/composer.lock b/composer.lock index 8117b68231..ceb9a4770e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6ff937a260c3e0c09de9eb5e073d830d", + "content-hash": "e1face7cebc5b79288c93a04e1f98521", "packages": [ { "name": "adhocore/jwt", @@ -851,72 +851,6 @@ }, "time": "2021-10-08T21:21:46+00:00" }, - { - "name": "laravel/pint", - "version": "v1.2.1", - "source": { - "type": "git", - "url": "https://github.com/laravel/pint.git", - "reference": "e60e2112ee779ce60f253695b273d1646a17d6f1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/e60e2112ee779ce60f253695b273d1646a17d6f1", - "reference": "e60e2112ee779ce60f253695b273d1646a17d6f1", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-mbstring": "*", - "ext-tokenizer": "*", - "ext-xml": "*", - "php": "^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.11.0", - "illuminate/view": "^9.32.0", - "laravel-zero/framework": "^9.2.0", - "mockery/mockery": "^1.5.1", - "nunomaduro/larastan": "^2.2.0", - "nunomaduro/termwind": "^1.14.0", - "pestphp/pest": "^1.22.1" - }, - "bin": [ - "builds/pint" - ], - "type": "project", - "autoload": { - "psr-4": { - "App\\": "app/", - "Database\\Seeders\\": "database/seeders/", - "Database\\Factories\\": "database/factories/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "An opinionated code formatter for PHP.", - "homepage": "https://laravel.com", - "keywords": [ - "format", - "formatter", - "lint", - "linter", - "php" - ], - "support": { - "issues": "https://github.com/laravel/pint/issues", - "source": "https://github.com/laravel/pint" - }, - "time": "2022-11-29T16:25:20+00:00" - }, { "name": "league/csv", "version": "9.7.1", @@ -2283,23 +2217,22 @@ }, { "name": "utopia-php/logger", - "version": "0.3.2", + "version": "0.3.1", "source": { "type": "git", "url": "https://github.com/utopia-php/logger.git", - "reference": "9151b7d16eab18d4c37c34643041cc0f33ca4a6c" + "reference": "de623f1ec1c672c795d113dd25c5bf212f7ef4fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/logger/zipball/9151b7d16eab18d4c37c34643041cc0f33ca4a6c", - "reference": "9151b7d16eab18d4c37c34643041cc0f33ca4a6c", + "url": "https://api.github.com/repos/utopia-php/logger/zipball/de623f1ec1c672c795d113dd25c5bf212f7ef4fc", + "reference": "de623f1ec1c672c795d113dd25c5bf212f7ef4fc", "shasum": "" }, "require": { "php": ">=8.0" }, "require-dev": { - "laravel/pint": "1.2.*", "phpstan/phpstan": "1.9.x-dev", "phpunit/phpunit": "^9.3", "vimeo/psalm": "4.0.1" @@ -2331,9 +2264,9 @@ ], "support": { "issues": "https://github.com/utopia-php/logger/issues", - "source": "https://github.com/utopia-php/logger/tree/0.3.2" + "source": "https://github.com/utopia-php/logger/tree/0.3.1" }, - "time": "2023-10-16T08:16:19+00:00" + "time": "2023-02-10T15:52:50+00:00" }, { "name": "utopia-php/messaging", @@ -2915,26 +2848,25 @@ }, { "name": "utopia-php/system", - "version": "0.7.1", + "version": "0.7.2", "source": { "type": "git", "url": "https://github.com/utopia-php/system.git", - "reference": "01bf0d283aded0ee0a7a6e5ff540acf64270ab27" + "reference": "4593d4d334b0c15879c4744a826e0362924c5d66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/system/zipball/01bf0d283aded0ee0a7a6e5ff540acf64270ab27", - "reference": "01bf0d283aded0ee0a7a6e5ff540acf64270ab27", + "url": "https://api.github.com/repos/utopia-php/system/zipball/4593d4d334b0c15879c4744a826e0362924c5d66", + "reference": "4593d4d334b0c15879c4744a826e0362924c5d66", "shasum": "" }, "require": { - "laravel/pint": "1.2.*", "php": ">=8.0.0" }, "require-dev": { - "phpunit/phpunit": "^9.3", - "squizlabs/php_codesniffer": "^3.6", - "vimeo/psalm": "4.0.1" + "laravel/pint": "1.13.*", + "phpstan/phpstan": "1.10.*", + "phpunit/phpunit": "9.6.*" }, "type": "library", "autoload": { @@ -2966,9 +2898,9 @@ ], "support": { "issues": "https://github.com/utopia-php/system/issues", - "source": "https://github.com/utopia-php/system/tree/0.7.1" + "source": "https://github.com/utopia-php/system/tree/0.7.2" }, - "time": "2023-08-30T09:14:37+00:00" + "time": "2023-10-20T01:39:17+00:00" }, { "name": "utopia-php/vcs", @@ -5890,5 +5822,5 @@ "platform-overrides": { "php": "8.0" }, - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.3.0" } From 0a1a2af218e45e0e058fa05cfa657cfdf643f027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Fri, 27 Oct 2023 12:57:26 +0200 Subject: [PATCH 15/19] Connect VCS base to VCS test --- tests/e2e/Services/VCS/VCSConsoleClientTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/e2e/Services/VCS/VCSConsoleClientTest.php b/tests/e2e/Services/VCS/VCSConsoleClientTest.php index 0b76610ade..114311d9b8 100644 --- a/tests/e2e/Services/VCS/VCSConsoleClientTest.php +++ b/tests/e2e/Services/VCS/VCSConsoleClientTest.php @@ -15,6 +15,7 @@ use Utopia\Cache\Cache; class VCSConsoleClientTest extends Scope { + use VCSBase; use ProjectCustom; use SideConsole; From cba20d8b96bc7b0b4f9156347231cb4d52d25a0f Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Fri, 27 Oct 2023 19:38:33 +0530 Subject: [PATCH 16/19] Addressed PR comments --- .env | 2 +- .github/workflows/tests.yml | 1 + app/controllers/api/functions.php | 18 ++++--- app/controllers/api/vcs.php | 47 +++++++++++++++++-- tests/e2e/Services/VCS/VCSBase.php | 10 ++++ .../e2e/Services/VCS/VCSConsoleClientTest.php | 18 +++---- .../e2e/Services/VCS/VCSCustomClientTest.php | 24 ++++++++++ .../e2e/Services/VCS/VCSCustomServerTest.php | 25 ++++++++++ 8 files changed, 124 insertions(+), 21 deletions(-) create mode 100644 tests/e2e/Services/VCS/VCSCustomClientTest.php create mode 100644 tests/e2e/Services/VCS/VCSCustomServerTest.php diff --git a/.env b/.env index feeb74d849..ad551e705a 100644 --- a/.env +++ b/.env @@ -91,7 +91,7 @@ _APP_GRAPHQL_MAX_DEPTH=3 _APP_DOCKER_HUB_USERNAME= _APP_DOCKER_HUB_PASSWORD= _APP_VCS_GITHUB_APP_NAME= -_APP_VCS_GITHUB_PRIVATE_KEY="" +_APP_VCS_GITHUB_PRIVATE_KEY=disabled _APP_VCS_GITHUB_APP_ID= _APP_VCS_GITHUB_CLIENT_ID= _APP_VCS_GITHUB_CLIENT_SECRET= diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ed9d7d1f19..842d61ff1c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -98,6 +98,7 @@ jobs: Teams, Users, Webhooks, + VCS, ] steps: diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 4a96308492..d370a7109c 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -46,6 +46,7 @@ use Utopia\Validator\Boolean; use Utopia\Database\Exception\Duplicate as DuplicateException; use MaxMind\Db\Reader; use Utopia\VCS\Adapter\Git\GitHub; +use Utopia\VCS\Exception\RepositoryNotFound; include_once __DIR__ . '/../shared/api.php'; @@ -58,7 +59,14 @@ $redeployVcs = function (Request $request, Document $function, Document $project $github->initializeVariables($providerInstallationId, $privateKey, $githubAppId); $owner = $github->getOwnerName($providerInstallationId); $providerRepositoryId = $function->getAttribute('providerRepositoryId', ''); - $repositoryName = $github->getRepositoryName($providerRepositoryId); + try { + $repositoryName = $github->getRepositoryName($providerRepositoryId) ?? ''; + if (empty($repositoryName)) { + throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); + } + } catch (RepositoryNotFound $e) { + throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); + } $providerBranch = $function->getAttribute('providerBranch', 'main'); $authorUrl = "https://github.com/$owner"; $repositoryUrl = "https://github.com/$owner/$repositoryName"; @@ -287,9 +295,8 @@ App::post('/v1/functions') $ruleModel = new Rule(); $ruleCreate = $queueForEvents - ->setClass(Event::WEBHOOK_CLASS_NAME) - ->setQueue(Event::WEBHOOK_QUEUE_NAME) - ; + ->setClass(Event::WEBHOOK_CLASS_NAME) + ->setQueue(Event::WEBHOOK_QUEUE_NAME); $ruleCreate ->setProject($project) @@ -870,8 +877,7 @@ App::get('/v1/functions/:functionId/deployments/:deploymentId/download') ->setContentType('application/gzip') ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache ->addHeader('X-Peak', \memory_get_peak_usage()) - ->addHeader('Content-Disposition', 'attachment; filename="' . $deploymentId . '.tar.gz"') - ; + ->addHeader('Content-Disposition', 'attachment; filename="' . $deploymentId . '.tar.gz"'); $size = $deviceFunctions->getFileSize($path); $rangeHeader = $request->getHeader('range'); diff --git a/app/controllers/api/vcs.php b/app/controllers/api/vcs.php index 0c18a25b66..8b61580b76 100644 --- a/app/controllers/api/vcs.php +++ b/app/controllers/api/vcs.php @@ -66,7 +66,14 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId } $owner = $github->getOwnerName($providerInstallationId) ?? ''; - $repositoryName = $github->getRepositoryName($providerRepositoryId) ?? ''; + try { + $repositoryName = $github->getRepositoryName($providerRepositoryId) ?? ''; + if (empty($repositoryName)) { + throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); + } + } catch (RepositoryNotFound $e) { + throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); + } if (empty($repositoryName)) { throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); @@ -154,7 +161,14 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId $message = 'Authorization required for external contributor.'; $providerRepositoryId = $resource->getAttribute('providerRepositoryId'); - $repositoryName = $github->getRepositoryName($providerRepositoryId); + try { + $repositoryName = $github->getRepositoryName($providerRepositoryId) ?? ''; + if (empty($repositoryName)) { + throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); + } + } catch (RepositoryNotFound $e) { + throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); + } $owner = $github->getOwnerName($providerInstallationId); $github->updateCommitStatus($repositoryName, $providerCommitHash, $owner, 'failure', $message, $authorizeUrl, $name); continue; @@ -206,7 +220,14 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId $message = 'Starting...'; $providerRepositoryId = $resource->getAttribute('providerRepositoryId'); - $repositoryName = $github->getRepositoryName($providerRepositoryId); + try { + $repositoryName = $github->getRepositoryName($providerRepositoryId) ?? ''; + if (empty($repositoryName)) { + throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); + } + } catch (RepositoryNotFound $e) { + throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); + } $owner = $github->getOwnerName($providerInstallationId); $providerTargetUrl = $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$projectId/functions/function-$functionId"; @@ -459,7 +480,10 @@ App::post('/v1/vcs/github/installations/:installationId/providerRepositories/:pr $owner = $github->getOwnerName($providerInstallationId); try { - $repositoryName = $github->getRepositoryName($providerRepositoryId); + $repositoryName = $github->getRepositoryName($providerRepositoryId) ?? ''; + if (empty($repositoryName)) { + throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); + } } catch (RepositoryNotFound $e) { throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); } @@ -722,6 +746,9 @@ App::get('/v1/vcs/github/installations/:installationId/providerRepositories/:pro $owner = $github->getOwnerName($providerInstallationId) ?? ''; try { $repositoryName = $github->getRepositoryName($providerRepositoryId) ?? ''; + if (empty($repositoryName)) { + throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); + } } catch (RepositoryNotFound $e) { throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); } @@ -768,6 +795,9 @@ App::get('/v1/vcs/github/installations/:installationId/providerRepositories/:pro $owner = $github->getOwnerName($providerInstallationId) ?? ''; try { $repositoryName = $github->getRepositoryName($providerRepositoryId) ?? ''; + if (empty($repositoryName)) { + throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); + } } catch (RepositoryNotFound $e) { throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); } @@ -1090,7 +1120,14 @@ App::patch('/v1/vcs/github/installations/:installationId/repositories/:repositor $providerRepositoryId = $repository->getAttribute('providerRepositoryId'); $owner = $github->getOwnerName($providerInstallationId); - $repositoryName = $github->getRepositoryName($providerRepositoryId); + try { + $repositoryName = $github->getRepositoryName($providerRepositoryId) ?? ''; + if (empty($repositoryName)) { + throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); + } + } catch (RepositoryNotFound $e) { + throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND); + } $pullRequestResponse = $github->getPullRequest($owner, $repositoryName, $providerPullRequestId); $providerBranch = \explode(':', $pullRequestResponse['head']['label'])[1] ?? ''; diff --git a/tests/e2e/Services/VCS/VCSBase.php b/tests/e2e/Services/VCS/VCSBase.php index 66f1158027..65ff84445e 100644 --- a/tests/e2e/Services/VCS/VCSBase.php +++ b/tests/e2e/Services/VCS/VCSBase.php @@ -2,6 +2,16 @@ namespace Tests\E2E\Services\VCS; +use Utopia\App; + trait VCSBase { + protected function setUp(): void + { + parent::setUp(); + + if (App::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY') === 'disabled') { + $this->markTestSkipped('VCS is not enabled.'); + } + } } diff --git a/tests/e2e/Services/VCS/VCSConsoleClientTest.php b/tests/e2e/Services/VCS/VCSConsoleClientTest.php index 114311d9b8..697fbdba91 100644 --- a/tests/e2e/Services/VCS/VCSConsoleClientTest.php +++ b/tests/e2e/Services/VCS/VCSConsoleClientTest.php @@ -23,7 +23,7 @@ class VCSConsoleClientTest extends Scope public string $providerRepositoryId = '705764267'; public string $providerRepositoryId2 = '708688544'; - public function testGitHubAuthorize() + public function testGitHubAuthorize(): string { /** * Test for SUCCESS @@ -43,7 +43,7 @@ class VCSConsoleClientTest extends Scope /** * @depends testGitHubAuthorize */ - public function testGetInstallation(string $installationId) + public function testGetInstallation(string $installationId): void { /** * Test for SUCCESS @@ -61,7 +61,7 @@ class VCSConsoleClientTest extends Scope /** * @depends testGitHubAuthorize */ - public function testDetectRuntime(string $installationId) + public function testDetectRuntime(string $installationId): void { /** * Test for SUCCESS @@ -88,7 +88,7 @@ class VCSConsoleClientTest extends Scope /** * @depends testGitHubAuthorize */ - public function testListRepositories(string $installationId) + public function testListRepositories(string $installationId): void { /** * Test for SUCCESS @@ -131,7 +131,7 @@ class VCSConsoleClientTest extends Scope /** * @depends testGitHubAuthorize */ - public function testGetRepository(string $installationId) + public function testGetRepository(string $installationId): void { /** * Test for SUCCESS @@ -169,7 +169,7 @@ class VCSConsoleClientTest extends Scope /** * @depends testGitHubAuthorize */ - public function testListRepositoryBranches(string $installationId) + public function testListRepositoryBranches(string $installationId): void { /** * Test for SUCCESS @@ -198,7 +198,7 @@ class VCSConsoleClientTest extends Scope /** * @depends testGitHubAuthorize */ - public function testCreateFunctionUsingVCS(string $installationId) + public function testCreateFunctionUsingVCS(string $installationId): array { $function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([ 'content-type' => 'application/json', @@ -236,7 +236,7 @@ class VCSConsoleClientTest extends Scope /** * @depends testCreateFunctionUsingVCS */ - public function testUpdateFunctionUsingVCS(array $data) + public function testUpdateFunctionUsingVCS(array $data): string { $function = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'], array_merge([ 'content-type' => 'application/json', @@ -271,7 +271,7 @@ class VCSConsoleClientTest extends Scope /** * @depends testGitHubAuthorize */ - public function testCreateRepository(string $installationId) + public function testCreateRepository(string $installationId): void { /** * Test for SUCCESS diff --git a/tests/e2e/Services/VCS/VCSCustomClientTest.php b/tests/e2e/Services/VCS/VCSCustomClientTest.php new file mode 100644 index 0000000000..084255cd69 --- /dev/null +++ b/tests/e2e/Services/VCS/VCSCustomClientTest.php @@ -0,0 +1,24 @@ +client->call(Client::METHOD_GET, '/vcs/installations/' . $installationId, array_merge([ + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + + $this->assertEquals(401, $installation['headers']['status-code']); + } +} diff --git a/tests/e2e/Services/VCS/VCSCustomServerTest.php b/tests/e2e/Services/VCS/VCSCustomServerTest.php new file mode 100644 index 0000000000..dee4cd7ced --- /dev/null +++ b/tests/e2e/Services/VCS/VCSCustomServerTest.php @@ -0,0 +1,25 @@ +client->call(Client::METHOD_GET, '/vcs/installations/' . $installationId, array_merge([ + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], $this->getHeaders())); + + $this->assertEquals(401, $installation['headers']['status-code']); + } +} From 30abfb01b72fcd3e5b6655bed3bb9889e4021917 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Fri, 27 Oct 2023 19:40:24 +0530 Subject: [PATCH 17/19] Composer update --- composer.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.lock b/composer.lock index aa16f1b5d0..11729e8957 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "06c2610579f319495ea7d2d28f42d376", + "content-hash": "0422497b0ed14e96f68dda2c6209ddda", "packages": [ { "name": "adhocore/jwt", @@ -5822,5 +5822,5 @@ "platform-overrides": { "php": "8.0" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.3.0" } From 9164ed1045a5e1098d7c83bd5ae4ea77758f6dc0 Mon Sep 17 00:00:00 2001 From: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com> Date: Fri, 27 Oct 2023 19:43:07 +0530 Subject: [PATCH 18/19] Fixed linter errors --- tests/e2e/Services/VCS/VCSBase.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/e2e/Services/VCS/VCSBase.php b/tests/e2e/Services/VCS/VCSBase.php index 65ff84445e..7531ea3bc8 100644 --- a/tests/e2e/Services/VCS/VCSBase.php +++ b/tests/e2e/Services/VCS/VCSBase.php @@ -6,12 +6,12 @@ use Utopia\App; trait VCSBase { - protected function setUp(): void - { - parent::setUp(); - - if (App::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY') === 'disabled') { - $this->markTestSkipped('VCS is not enabled.'); - } + protected function setUp(): void + { + parent::setUp(); + + if (App::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY') === 'disabled') { + $this->markTestSkipped('VCS is not enabled.'); + } } } From 6d237853e65a3a27a88b4a3cad6c5d1cb8850ccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=B7=E5=8D=8E=20=E5=88=98?= Date: Fri, 27 Oct 2023 14:38:04 +0000 Subject: [PATCH 19/19] chore: revert console --- app/console | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/console b/app/console index 9b4bcb8140..fe835e5032 160000 --- a/app/console +++ b/app/console @@ -1 +1 @@ -Subproject commit 9b4bcb8140484669421685b4ba89fa1c4d331360 +Subproject commit fe835e50328ed80f67c66d2d449c0f7b51ade544