Skip to content

Commit a7ba6f3

Browse files
committed
Merge branch 'main' of https://github.com/jaysomani/vcs into feat/gitea-content-endpoints
2 parents 9219a0c + 0580493 commit a7ba6f3

File tree

4 files changed

+81
-15
lines changed

4 files changed

+81
-15
lines changed

src/VCS/Adapter.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ abstract public function getOwnerName(string $installationId): string;
8686

8787
/**
8888
* Search repositories for GitHub App
89+
* @param string $installationId ID of the installation
8990
* @param string $owner Name of user or org
9091
* @param int $page page number
9192
* @param int $per_page number of results per page
@@ -94,7 +95,7 @@ abstract public function getOwnerName(string $installationId): string;
9495
*
9596
* @throws Exception
9697
*/
97-
abstract public function searchRepositories(string $owner, int $page, int $per_page, string $search = ''): array;
98+
abstract public function searchRepositories(string $installationId, string $owner, int $page, int $per_page, string $search = ''): array;
9899

99100
/**
100101
* Get repository

src/VCS/Adapter/Git/GitHub.php

Lines changed: 76 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ public function createRepository(string $owner, string $repositoryName, bool $pr
9696

9797
/**
9898
* Search repositories for GitHub App
99+
* @param string $installationId ID of the installation
99100
* @param string $owner Name of user or org
100101
* @param int $page page number
101102
* @param int $per_page number of results per page
@@ -104,24 +105,87 @@ public function createRepository(string $owner, string $repositoryName, bool $pr
104105
*
105106
* @throws Exception
106107
*/
107-
public function searchRepositories(string $owner, int $page, int $per_page, string $search = ''): array
108+
public function searchRepositories(string $installationId, string $owner, int $page, int $per_page, string $search = ''): array
108109
{
109-
$url = '/search/repositories';
110+
// Find whether installation has access to all (or) specific repositories
111+
$url = '/app/installations/' . $installationId;
112+
$response = $this->call(self::METHOD_GET, $url, ['Authorization' => "Bearer $this->jwtToken"]);
113+
$hasAccessToAllRepositories = ($response['body']['repository_selection'] ?? '') === 'all';
114+
115+
// Installation has access to all repositories, use the search API which supports filtering.
116+
if ($hasAccessToAllRepositories) {
117+
$url = '/search/repositories';
118+
119+
$response = $this->call(self::METHOD_GET, $url, ['Authorization' => "Bearer $this->accessToken"], [
120+
'q' => "{$search} user:{$owner} fork:true",
121+
'page' => $page,
122+
'per_page' => $per_page,
123+
'sort' => 'updated'
124+
]);
125+
126+
if (!isset($response['body']['items'])) {
127+
throw new Exception("Repositories list missing in the response.");
128+
}
129+
130+
return [
131+
'items' => $response['body']['items'],
132+
'total' => $response['body']['total_count'],
133+
];
134+
}
110135

111-
$response = $this->call(self::METHOD_GET, $url, ['Authorization' => "Bearer $this->accessToken"], [
112-
'q' => "{$search} user:{$owner} fork:true",
113-
'page' => $page,
114-
'per_page' => $per_page,
115-
'sort' => 'updated'
116-
]);
136+
// Installation has access to specific repositories, we need to perform client-side filtering.
137+
$url = '/installation/repositories';
138+
$repositories = [];
117139

118-
if (!isset($response['body']['items'])) {
119-
throw new Exception("Repositories list missing in the response.");
140+
// When no search query is provided, delegate pagination to the GitHub API.
141+
if (empty($search)) {
142+
$repositories = $this->call(self::METHOD_GET, $url, ['Authorization' => "Bearer $this->accessToken"], [
143+
'page' => $page,
144+
'per_page' => $per_page,
145+
]);
146+
147+
if (!isset($repositories['body']['repositories'])) {
148+
throw new Exception("Repositories list missing in the response.");
149+
}
150+
151+
return [
152+
'items' => $repositories['body']['repositories'],
153+
'total' => $repositories['body']['total_count'],
154+
];
120155
}
121156

157+
// When search query is provided, fetch all repositories accessible by the installation and filter them locally.
158+
$currentPage = 1;
159+
while (true) {
160+
$response = $this->call(self::METHOD_GET, $url, ['Authorization' => "Bearer $this->accessToken"], [
161+
'page' => $currentPage,
162+
'per_page' => 100, // Maximum allowed by GitHub API
163+
]);
164+
165+
if (!isset($response['body']['repositories'])) {
166+
throw new Exception("Repositories list missing in the response.");
167+
}
168+
169+
// Filter repositories to only include those that match the search query.
170+
$filteredRepositories = array_filter($response['body']['repositories'], fn ($repo) => stripos($repo['name'], $search) !== false);
171+
172+
// Merge with result so far.
173+
$repositories = array_merge($repositories, $filteredRepositories);
174+
175+
// If less than 100 repositories are returned, we have fetched all repositories.
176+
if (\count($response['body']['repositories']) < 100) {
177+
break;
178+
}
179+
180+
// Increment page number to fetch next page.
181+
$currentPage++;
182+
}
183+
184+
$repositoriesInRequestedPage = \array_slice($repositories, ($page - 1) * $per_page, $per_page);
185+
122186
return [
123-
'items' => $response['body']['items'],
124-
'total' => $response['body']['total_count'],
187+
'items' => $repositoriesInRequestedPage,
188+
'total' => \count($repositories),
125189
];
126190
}
127191

src/VCS/Adapter/Git/Gitea.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public function createOrganization(string $orgName): string
118118
// Stub methods to satisfy abstract class requirements
119119
// These will be implemented in follow-up PRs
120120

121-
public function searchRepositories(string $owner, int $page, int $per_page, string $search = ''): array
121+
public function searchRepositories(string $installationId, string $owner, int $page, int $per_page, string $search = ''): array
122122
{
123123
throw new Exception("Not implemented yet");
124124
}

tests/VCS/Base.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ public function testGetOwnerName(): void
5151

5252
public function testSearchRepositories(): void
5353
{
54-
['items' => $repos, 'total' => $total] = $this->vcsAdapter->searchRepositories('test-kh', 1, 2);
54+
$installationId = System::getEnv('TESTS_GITHUB_INSTALLATION_ID') ?? '';
55+
['items' => $repos, 'total' => $total] = $this->vcsAdapter->searchRepositories($installationId, 'test-kh', 1, 2);
5556
$this->assertCount(2, $repos);
5657
$this->assertSame(6, $total);
5758
}

0 commit comments

Comments
 (0)