Skip to content

Commit 2f18162

Browse files
authored
Merge pull request #72 from jaysomani/feat/gitea-owner-name-fix
feat: implement getOwnerName for Gitea using repositoryId
2 parents f29fc06 + 73b95f7 commit 2f18162

File tree

4 files changed

+78
-10
lines changed

4 files changed

+78
-10
lines changed

src/VCS/Adapter.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,14 @@ abstract public function getUser(string $username): array;
8080
/**
8181
* Get owner name of the installation
8282
*
83-
* @return string
83+
* For GitHub: Uses installationId to identify the GitHub App installation
84+
* For Gitea: Requires repositoryId since OAuth tokens can access multiple organizations
85+
*
86+
* @param string $installationId Installation ID (GitHub) or empty string (Gitea)
87+
* @param int|null $repositoryId Repository ID (required for Gitea, ignored by GitHub)
88+
* @return string Owner login/username
8489
*/
85-
abstract public function getOwnerName(string $installationId): string;
90+
abstract public function getOwnerName(string $installationId, ?int $repositoryId = null): string;
8691

8792
/**
8893
* Search repositories for GitHub App

src/VCS/Adapter/Git/GitHub.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -618,10 +618,13 @@ public function getUser(string $username): array
618618
/**
619619
* Get owner name of the GitHub installation
620620
*
621-
* @return string
621+
* @param string $installationId GitHub App installation ID
622+
* @param int|null $repositoryId Not used by GitHub (parameter exists for Gitea compatibility)
623+
* @return string Owner login/username
622624
*/
623-
public function getOwnerName(string $installationId): string
625+
public function getOwnerName(string $installationId, ?int $repositoryId = null): string
624626
{
627+
// GitHub doesn't use $repositoryId - only installationId
625628
$url = '/app/installations/' . $installationId;
626629
$response = $this->call(self::METHOD_GET, $url, ['Authorization' => "Bearer $this->jwtToken"]);
627630

src/VCS/Adapter/Git/Gitea.php

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -531,9 +531,35 @@ public function getUser(string $username): array
531531
throw new Exception("Not implemented yet");
532532
}
533533

534-
public function getOwnerName(string $installationId): string
534+
public function getOwnerName(string $installationId, ?int $repositoryId = null): string
535535
{
536-
throw new Exception("getOwnerName() is not applicable for Gitea");
536+
if ($repositoryId === null || $repositoryId <= 0) {
537+
throw new Exception("repositoryId is required for Gitea");
538+
}
539+
540+
$url = "/repositories/{$repositoryId}";
541+
542+
$response = $this->call(self::METHOD_GET, $url, ['Authorization' => "token $this->accessToken"]);
543+
544+
$responseHeaders = $response['headers'] ?? [];
545+
$responseHeadersStatusCode = $responseHeaders['status-code'] ?? 0;
546+
547+
if ($responseHeadersStatusCode === 404) {
548+
throw new RepositoryNotFound("Repository not found");
549+
}
550+
551+
if ($responseHeadersStatusCode >= 400) {
552+
throw new Exception("Failed to get repository: HTTP {$responseHeadersStatusCode}");
553+
}
554+
555+
$responseBody = $response['body'] ?? [];
556+
$owner = $responseBody['owner'] ?? [];
557+
558+
if (empty($owner['login'])) {
559+
throw new Exception("Owner login missing or empty in response");
560+
}
561+
562+
return $owner['login'];
537563
}
538564

539565
public function getPullRequest(string $owner, string $repositoryName, int $pullRequestNumber): array

tests/VCS/Adapter/GiteaTest.php

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -721,19 +721,53 @@ public function testDeleteNonExistingRepositoryFails(): void
721721
}
722722

723723
public function testGetOwnerName(): void
724+
{
725+
$repositoryName = 'test-get-owner-name-' . \uniqid();
726+
$created = $this->vcsAdapter->createRepository(self::$owner, $repositoryName, false);
727+
728+
try {
729+
$this->assertIsArray($created);
730+
$this->assertArrayHasKey('id', $created);
731+
$this->assertIsScalar($created['id']);
732+
$repositoryId = (int) $created['id'];
733+
734+
$ownerName = $this->vcsAdapter->getOwnerName('', $repositoryId);
735+
736+
$this->assertSame(self::$owner, $ownerName);
737+
} finally {
738+
$this->vcsAdapter->deleteRepository(self::$owner, $repositoryName);
739+
}
740+
}
741+
742+
public function testGetOwnerNameWithZeroRepositoryId(): void
743+
{
744+
$this->expectException(\Exception::class);
745+
$this->expectExceptionMessage('repositoryId is required for Gitea');
746+
747+
$this->vcsAdapter->getOwnerName('', 0);
748+
}
749+
750+
public function testGetOwnerNameWithoutRepositoryId(): void
724751
{
725752
$this->expectException(\Exception::class);
726-
$this->expectExceptionMessage('not applicable for Gitea');
753+
$this->expectExceptionMessage('repositoryId is required for Gitea');
727754

728755
$this->vcsAdapter->getOwnerName('');
729756
}
730757

731-
public function testGetOwnerNameWithRandomInput(): void
758+
public function testGetOwnerNameWithInvalidRepositoryId(): void
759+
{
760+
$this->expectException(\Utopia\VCS\Exception\RepositoryNotFound::class);
761+
762+
$this->vcsAdapter->getOwnerName('', 999999999);
763+
}
764+
765+
public function testGetOwnerNameWithNullRepositoryId(): void
732766
{
733767
$this->expectException(\Exception::class);
734-
$this->expectExceptionMessage('not applicable for Gitea');
768+
$this->expectExceptionMessage('repositoryId is required for Gitea');
735769

736-
$this->vcsAdapter->getOwnerName('random-gibberish-' . \uniqid());
770+
$this->vcsAdapter->getOwnerName('', null);
737771
}
738772

739773
public function testGetPullRequestFromBranch(): void

0 commit comments

Comments
 (0)