request($baseUrl, $token) ->get('/user') ->throw() ->json(); return new GitAuthenticatedUser( providerUserId: (string) $payload['id'], login: $payload['login'], name: blank($payload['full_name'] ?? null) ? null : $payload['full_name'], ); } /** * @return array */ public function listRepositories(string $baseUrl, string $token): array { $page = 1; $repositories = []; do { /** @var array $payload */ $payload = $this->request($baseUrl, $token) ->get('/user/repos', [ 'limit' => 100, 'page' => $page, ]) ->throw() ->json(); foreach ($payload as $repository) { $repositories[] = new GitRepository( providerRepositoryId: (string) $repository['id'], owner: $repository['owner']['login'], name: $repository['name'], fullName: $repository['full_name'], htmlUrl: $repository['html_url'], isPrivate: $repository['private'], ); } $page++; } while (count($payload) === 100); return $repositories; } /** * @return array */ public function listBranches( string $baseUrl, string $token, string $owner, string $repository, ): array { $page = 1; $branches = []; do { /** @var array $payload */ $payload = $this->request($baseUrl, $token) ->get( '/repos/'.rawurlencode($owner).'/'.rawurlencode($repository).'/branches', [ 'limit' => 100, 'page' => $page, ], ) ->throw() ->json(); foreach ($payload as $branch) { $branches[] = new GitBranch( name: $branch['name'], ); } $page++; } while (count($payload) === 100); return $branches; } /** * @return array */ public function listPullRequests( string $baseUrl, string $token, string $owner, string $repository, ): array { $page = 1; $pullRequests = []; do { /** @var array $payload */ $payload = $this->request($baseUrl, $token) ->get( '/repos/'.rawurlencode($owner).'/'.rawurlencode($repository).'/pulls', [ 'limit' => 100, 'page' => $page, 'state' => 'all', ], ) ->throw() ->json(); foreach ($payload as $pullRequest) { $status = ($pullRequest['merged'] ?? false) ? 'merged' : $pullRequest['state']; $pullRequests[] = new GitPullRequest( number: (string) $pullRequest['number'], title: $pullRequest['title'], status: $status, sourceBranch: $pullRequest['head']['ref'], htmlUrl: $pullRequest['html_url'], ); } $page++; } while (count($payload) === 100); return $pullRequests; } private function request(string $baseUrl, string $token): PendingRequest { return Http::acceptJson() ->baseUrl($this->apiBaseUrl($baseUrl)) ->connectTimeout(5) ->timeout(10) ->withHeader('Authorization', 'token '.$token); } private function apiBaseUrl(string $baseUrl): string { $normalizedBaseUrl = Str::of(trim($baseUrl)) ->rtrim('/') ->value(); if (Str::endsWith(Str::lower($normalizedBaseUrl), '/api/v1')) { return $normalizedBaseUrl; } return Str::of($normalizedBaseUrl) ->append('/api/v1') ->value(); } }