mirror of
https://github.com/coollabsio/coolify.git
synced 2026-10-28 09:34:36 +08:00
fix(github): show GitHub App errors when loading repositories
Closes #10174 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
086dbb8b1e
commit
c3d110496c
3 files changed
+74
-17
No files matched your search
@@ -115,17 +115,22 @@ class GithubPrivateRepository extends Component
|
||||
->where('is_public', false)
|
||||
->whereNotNull('app_id')
|
||||
->findOrFail($github_app_id);
|
||||
$token = generateGithubInstallationToken($this->github_app);
|
||||
$repositories = loadRepositoryByPage($this->github_app, $token, $this->page);
|
||||
$this->total_repositories_count = $repositories['total_count'];
|
||||
$this->repositories = $this->repositories->concat(collect($repositories['repositories']));
|
||||
if ($this->repositories->count() < $this->total_repositories_count) {
|
||||
try {
|
||||
$token = generateGithubInstallationToken($this->github_app);
|
||||
$repositories = loadRepositoryByPage($this->github_app, $token, $this->page);
|
||||
$this->total_repositories_count = $repositories['total_count'];
|
||||
$this->repositories = $this->repositories->concat(collect($repositories['repositories']));
|
||||
while ($this->repositories->count() < $this->total_repositories_count) {
|
||||
$this->page++;
|
||||
$repositories = loadRepositoryByPage($this->github_app, $token, $this->page);
|
||||
$this->total_repositories_count = $repositories['total_count'];
|
||||
$this->repositories = $this->repositories->concat(collect($repositories['repositories']));
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$this->repositories = collect();
|
||||
handleError($e, $this);
|
||||
|
||||
return;
|
||||
}
|
||||
$this->repositories = $this->repositories->sortBy('name');
|
||||
if ($this->repositories->count() > 0) {
|
||||
@@ -141,12 +146,17 @@ class GithubPrivateRepository extends Component
|
||||
$this->selected_repository_repo = data_get($repository, 'name');
|
||||
$this->branches = collect();
|
||||
$this->page = 1;
|
||||
$this->loadBranchByPage();
|
||||
if ($this->total_branches_count === 100) {
|
||||
while ($this->total_branches_count === 100) {
|
||||
$this->page++;
|
||||
try {
|
||||
do {
|
||||
$this->loadBranchByPage();
|
||||
}
|
||||
$this->page++;
|
||||
} while ($this->total_branches_count === 100);
|
||||
} catch (\Throwable $e) {
|
||||
$this->branches = collect();
|
||||
$this->total_branches_count = 0;
|
||||
handleError($e, $this);
|
||||
|
||||
return;
|
||||
}
|
||||
$this->branches = sortBranchesByPriority($this->branches);
|
||||
$defaultBranch = data_get($repository, 'default_branch', 'main');
|
||||
@@ -157,7 +167,7 @@ class GithubPrivateRepository extends Component
|
||||
$this->detectRepository();
|
||||
}
|
||||
|
||||
protected function loadBranchByPage()
|
||||
protected function loadBranchByPage(): void
|
||||
{
|
||||
$token = generateGithubInstallationToken($this->github_app);
|
||||
|
||||
@@ -170,7 +180,9 @@ class GithubPrivateRepository extends Component
|
||||
]);
|
||||
$json = $response->json();
|
||||
if ($response->status() !== 200) {
|
||||
return $this->dispatch('error', $json['message']);
|
||||
$error = data_get($json, 'message', "HTTP {$response->status()}");
|
||||
|
||||
throw new \RuntimeException("Failed to load branches of {$this->selected_repository_owner}/{$this->selected_repository_repo} with error: ".$error);
|
||||
}
|
||||
|
||||
$this->total_branches_count = count($json);
|
||||
|
||||
@@ -212,7 +212,7 @@ function generateGithubToken(GithubApp $source, string $type)
|
||||
if (! $response->successful()) {
|
||||
$error = data_get($response->json(), 'message', "HTTP {$response->status()}");
|
||||
if ($error === 'Not Found') {
|
||||
$error = 'Repository not found. Is it moved or deleted?';
|
||||
$error = "GitHub App installation {$source->installation_id} was not found. Install the GitHub App again or update its installation ID.";
|
||||
}
|
||||
throw new RuntimeException("Failed to get installation token for {$source->name} with error: ".$error);
|
||||
}
|
||||
@@ -388,10 +388,9 @@ function loadRepositoryByPage(GithubApp $source, string $token, int $page)
|
||||
]);
|
||||
$json = $response->json();
|
||||
if ($response->status() !== 200) {
|
||||
return [
|
||||
'total_count' => 0,
|
||||
'repositories' => [],
|
||||
];
|
||||
$error = data_get($json, 'message', "HTTP {$response->status()}");
|
||||
|
||||
throw new RuntimeException("Failed to load repositories for {$source->name} with error: ".$error);
|
||||
}
|
||||
|
||||
if ($json['total_count'] === 0) {
|
||||
|
||||
@@ -344,6 +344,52 @@ describe('GitHub Private Repository Component', function () {
|
||||
->assertSee('Refresh');
|
||||
});
|
||||
|
||||
test('loadRepositories shows an error when the installation is not found', function () {
|
||||
Http::fake([
|
||||
'https://api.github.com/zen' => Http::response('Keep it logically awesome.', 200, [
|
||||
'Date' => now()->toRfc7231String(),
|
||||
]),
|
||||
'https://api.github.com/app/installations/67890/access_tokens' => Http::response(['message' => 'Not Found'], 404),
|
||||
]);
|
||||
|
||||
Livewire::test(GithubPrivateRepository::class, ['type' => 'private-gh-app'])
|
||||
->call('loadRepositories', $this->githubApp->id)
|
||||
->assertDispatched('error', fn (string $event, array $params) => str_contains($params[0], 'installation 67890 was not found'))
|
||||
->assertSet('current_step', 'github_apps');
|
||||
});
|
||||
|
||||
test('loadRepositories shows the GitHub error when listing repositories fails', function () {
|
||||
Http::fake([
|
||||
'https://api.github.com/zen' => Http::response('Keep it logically awesome.', 200, [
|
||||
'Date' => now()->toRfc7231String(),
|
||||
]),
|
||||
'https://api.github.com/app/installations/67890/access_tokens' => Http::response([
|
||||
'token' => 'fake-installation-token',
|
||||
], 201),
|
||||
'https://api.github.com/installation/repositories*' => Http::response(['message' => 'Resource not accessible by integration'], 403),
|
||||
]);
|
||||
|
||||
Livewire::test(GithubPrivateRepository::class, ['type' => 'private-gh-app'])
|
||||
->call('loadRepositories', $this->githubApp->id)
|
||||
->assertDispatched('error', fn (string $event, array $params) => str_contains($params[0], 'Resource not accessible by integration'))
|
||||
->assertSet('current_step', 'github_apps');
|
||||
});
|
||||
|
||||
test('loadBranches stops and shows the GitHub error when a later branch page fails', function () {
|
||||
$repository = ['id' => 1, 'name' => 'alpha-repo', 'owner' => ['login' => 'testuser']];
|
||||
fakeGithubHttp([$repository]);
|
||||
Http::fake([
|
||||
'https://api.github.com/repos/testuser/alpha-repo/branches*' => Http::sequence()
|
||||
->push(collect(range(1, 100))->map(fn (int $i) => ['name' => "branch-{$i}"])->all(), 200)
|
||||
->whenEmpty(Http::response(['message' => 'API rate limit exceeded'], 403)),
|
||||
]);
|
||||
|
||||
Livewire::test(GithubPrivateRepository::class, ['type' => 'private-gh-app'])
|
||||
->call('loadRepositories', $this->githubApp->id)
|
||||
->call('loadBranches')
|
||||
->assertDispatched('error', fn (string $event, array $params) => str_contains($params[0], 'API rate limit exceeded'));
|
||||
});
|
||||
|
||||
test('refresh button is not visible before repositories are loaded', function () {
|
||||
Livewire::test(GithubPrivateRepository::class, ['type' => 'private-gh-app'])
|
||||
->assertDontSee('Refresh');
|
||||
|
||||
Reference in new issue
Block a user