Stop wrestling with GitHub's API. Start shipping.
composer require jordanpartridge/github-client// That's it. You're done.
$repos = Github::repos()->all();
$issues = Github::issues()->forRepo('owner', 'repo');
$pr = Github::pullRequests()->create('owner', 'repo', 'My PR', 'feature', 'main');- Laravel Native - Built for Laravel, not wrapped around it
- Typed Responses - DTOs everywhere, not arrays
- Auto-Pagination -
allWithPagination()just works - Type-Safe Params - Enums, not magic strings
- Easy Testing - Saloon MockClient built in
One line: Modern GitHub API for modern Laravel.
composer require jordanpartridge/github-clientAdd your token to .env:
GITHUB_TOKEN=ghp_your_token_hereGet one at github.com/settings/tokens
use JordanPartridge\GithubClient\Facades\Github;
// Get your repos
$repos = Github::repos()->all();
// Get ALL your repos (auto-pagination, no limits)
$allRepos = Github::repos()->allWithPagination();
// Get a specific repo
$repo = Github::repos()->get('jordanpartridge/github-client');
echo $repo->name; // "github-client"
echo $repo->stargazers_count; // 🤞
echo $repo->owner->login; // "jordanpartridge"$issue = Github::issues()->create(
owner: 'jordanpartridge',
repo: 'github-client',
title: 'Bug: Something broke',
body: 'Here are the details...',
labels: ['bug', 'high-priority'],
assignees: ['jordanpartridge']
);
echo $issue->number; // 42
echo $issue->html_url; // Direct link to GitHubuse JordanPartridge\GithubClient\Enums\MergeMethod;
// Create PR
$pr = Github::pullRequests()->create(
owner: 'jordanpartridge',
repo: 'github-client',
title: 'Add new feature',
head: 'feature-branch',
base: 'main',
body: 'This PR adds the thing.',
draft: false
);
// Merge it
Github::pullRequests()->merge(
owner: 'jordanpartridge',
repo: 'github-client',
number: $pr->number,
mergeMethod: MergeMethod::Squash
);// Get all comments on an issue
$comments = Github::issues()->comments('owner', 'repo', 42);
// Add a comment
Github::issues()->addComment('owner', 'repo', 42, 'Fixed in latest release.');
// Close the issue
Github::issues()->close('owner', 'repo', 42);use JordanPartridge\GithubClient\Enums\Visibility;
use JordanPartridge\GithubClient\Enums\Sort;
use JordanPartridge\GithubClient\Enums\Direction;
use JordanPartridge\GithubClient\Enums\Issues\State;
// Only public repos, sorted by creation date
$repos = Github::repos()->allWithPagination(
visibility: Visibility::PUBLIC,
sort: Sort::CREATED,
direction: Direction::DESC
);
// Open bugs only
$bugs = Github::issues()->forRepo(
owner: 'jordanpartridge',
repo: 'github-client',
state: State::OPEN,
labels: 'bug'
);Saloon's MockClient makes testing trivial:
use Saloon\Http\Faking\MockClient;
use Saloon\Http\Faking\MockResponse;
use JordanPartridge\GithubClient\Facades\Github;
it('creates issues', function () {
$mock = new MockClient([
'*' => MockResponse::make([
'id' => 1,
'number' => 42,
'title' => 'Test Issue',
'state' => 'open',
], 201),
]);
Github::connector()->withMockClient($mock);
$issue = Github::issues()->create('owner', 'repo', 'Test Issue');
expect($issue->number)->toBe(42);
expect($issue->title)->toBe('Test Issue');
});No HTTP calls. No flaky tests. No rate limits in CI.
| Resource | Methods |
|---|---|
repos() |
all, allWithPagination, get, delete, search |
issues() |
all, forRepo, allForRepo, get, create, update, close, reopen, comments, addComment |
pullRequests() |
all, get, create, merge, files, commits |
commits() |
all, get |
files() |
get, contents |
releases() |
all, get, latest, create |
actions() |
workflows, runs, trigger |
Don't like facades? Use DI:
use JordanPartridge\GithubClient\Contracts\GithubConnectorInterface;
class MyService
{
public function __construct(
private readonly GithubConnectorInterface $github
) {}
public function getMyRepos()
{
return $this->github->repos()->all();
}
}Building a GitHub app? OAuth is built in:
use JordanPartridge\GithubClient\Facades\GithubOAuth;
// 1. Redirect user to GitHub
return redirect(GithubOAuth::getAuthorizationUrl(['repo', 'user']));
// 2. Handle callback
$token = GithubOAuth::getAccessToken($request->code);
// 3. Use their token
$github = new GithubConnector($token);
$theirRepos = $github->repos()->all();- PHP 8.2+
- Laravel 11 or 12
PRs welcome. Run tests first:
composer testMIT. Go build something.
Built with Saloon by Jordan Partridge