jordanpartridge/github-client

This is my package github-client


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads PHP Version Laravel Version

A powerful, Laravel-first GitHub API client built on Saloon that makes integrating with GitHub's API simple and intuitive. This package provides strongly-typed responses, resource-based architecture, and an elegant developer experience.

๐ŸŒŸ Features

  • Elegant Resource Pattern: A Laravel-style resource pattern for all GitHub API entities
  • Strongly Typed: Full type-hinting support with typed responses via DTOs
  • Built on Saloon: Reliable API handling with MockClient for testing
  • Comprehensive Coverage: Support for repositories, commits, pull requests, and files
  • Laravel Integration: Seamless integration with Laravel's configuration and authentication
  • Multiple Access Methods: Support for facades and dependency injection
  • Modern Codebase: PHP 8.2+ with modern features like enums and readonly properties
  • Extensive Test Coverage: Complete test suite using Pest PHP
  • Laravel Compatibility: Support for Laravel 10, 11, and 12

๐Ÿ“ฆ Installation

Install the package via Composer:

composer require jordanpartridge/github-client

โš™๏ธ Configuration

  1. Generate a GitHub token in your GitHub Settings with appropriate scopes
  2. Add the token to your .env file:
GITHUB_TOKEN=your-token-here
  1. (Optional) Publish the configuration file if you need custom settings:
php artisan vendor:publish --tag="github-client-config"

๐Ÿ“„ Available Resources

This package provides the following GitHub resource classes:

Resource Description
repos() Access and manage GitHub repositories
commits() Work with repository commits
pullRequests() Manage pull requests, reviews, and comments
files() Access repository file contents

๐Ÿš€ Basic Usage

Working with Repositories

use JordanPartridge\GithubClient\Facades\Github;

// List all repositories
$allRepos = Github::repos()->all();

// Get a specific repository
$repo = Github::repos()->get('jordanpartridge/github-client');

// Filter repositories by visibility
use JordanPartridge\GithubClient\Enums\Visibility;
$publicRepos = Github::repos()->all(
    visibility: Visibility::PUBLIC,
);

Working with Commits

// Get all commits for a repository
$commits = Github::commits()->all('jordanpartridge/github-client');

// Get a specific commit by SHA
$specificCommit = Github::commits()->get('jordanpartridge/github-client', 'abc123deadbeef');

Working with Pull Requests

use JordanPartridge\GithubClient\Enums\MergeMethod;

// List all pull requests for a repository
$pullRequests = Github::pullRequests()->all('jordanpartridge/github-client');

// Get a specific pull request
$pullRequest = Github::pullRequests()->get('jordanpartridge/github-client', 123);

// Create a new pull request
$newPr = Github::pullRequests()->create(
    owner: 'jordanpartridge',
    repo: 'github-client',
    title: 'New feature implementation',
    head: 'feature-branch',
    base: 'main',
    body: 'This PR implements the new feature with tests',
    draft: false
);

// Merge a pull request
$mergeResult = Github::pullRequests()->merge(
    owner: 'jordanpartridge',
    repo: 'github-client',
    number: 123,
    commitMessage: 'Implement new feature',
    mergeMethod: MergeMethod::Squash
);

Working with Repository Files

// Get file contents from a repository
$fileContent = Github::files()->get(
    owner: 'jordanpartridge',
    repo: 'github-client',
    path: 'README.md'
);

// List directory contents
$files = Github::files()->contents(
    owner: 'jordanpartridge',
    repo: 'github-client',
    path: 'src'
);

Using Dependency Injection

You can use dependency injection instead of the Facade:

use JordanPartridge\GithubClient\Contracts\GithubConnectorInterface;

class GitHubService
{
    public function __construct(
        private readonly GithubConnectorInterface $github
    ) {}
    
    public function getRepositories()
    {
        return $this->github->repos()->all();
    }
}

๐Ÿ”„ Type-Safe API Responses

All responses are properly typed using data transfer objects (DTOs) powered by spatie/laravel-data:

// $repo is a strongly-typed RepoData object
$repo = Github::repos()->get('jordanpartridge/github-client');

// Access typed properties
echo $repo->name;
echo $repo->full_name;
echo $repo->created_at->format('Y-m-d');
echo $repo->owner->login;

๐Ÿงช Testing

When testing your application, you can use Saloon's MockClient to mock GitHub API responses:

use Saloon\Http\Faking\MockClient;
use Saloon\Http\Faking\MockResponse;
use JordanPartridge\GithubClient\Facades\Github;

// Set up mock response
$mockClient = new MockClient([
    '*' => MockResponse::make([
        'id' => 1,
        'name' => 'test-repo',
        'full_name' => 'test/test-repo',
    ], 200),
]);

// Apply mock client to GitHub connector
Github::connector()->withMockClient($mockClient);

// Now any API calls will return the mock response
$repo = Github::repos()->get('any/repo');

๐Ÿ“– Advanced Documentation

Parameter Type Validation

This package uses PHP 8.2+ enums for parameter validation, ensuring you always pass valid values:

use JordanPartridge\GithubClient\Enums\Visibility;
use JordanPartridge\GithubClient\Enums\Sort;
use JordanPartridge\GithubClient\Enums\Direction;
use JordanPartridge\GithubClient\Enums\MergeMethod;
use JordanPartridge\GithubClient\Enums\Pulls\State;

// Using enums for parameter validation
$repos = Github::repos()->all(
    visibility: Visibility::PUBLIC,    // 'public', 'private', 'all'
    sort: Sort::CREATED,               // 'created', 'updated', 'pushed', 'full_name'
    direction: Direction::DESC         // 'asc', 'desc'
);

// Pull request states
$openPrs = Github::pullRequests()->all(
    'jordanpartridge/github-client',
    state: State::OPEN                 // 'open', 'closed', 'all'
);

// Merge methods
$mergeResult = Github::pullRequests()->merge(
    'jordanpartridge',
    'github-client',
    123,
    mergeMethod: MergeMethod::Squash   // 'merge', 'squash', 'rebase'
);

OAuth Authentication

For web applications that need user authentication:

use JordanPartridge\GithubClient\Facades\GithubOAuth;

// Get authorization URL
$authUrl = GithubOAuth::getAuthorizationUrl([
    'repo',           // Access repositories
    'user',           // Access user profile
    'read:org',       // Read organization access
]);

// Redirect user to authorization URL
return redirect()->away($authUrl);

// In your callback route
$token = GithubOAuth::getAccessToken($code);

// Store the token for the authenticated user
auth()->user()->update(['github_token' => $token]);

// Use the user's token for GitHub API requests
$github = new \JordanPartridge\GithubClient\GithubConnector($token);
$userRepos = $github->repos()->all();

๐Ÿ”ง Local Development

# Install dependencies
composer install

# Run tests
composer test

# Run a specific test
vendor/bin/pest tests/ReposTest.php

# Run static analysis
composer analyse

# Format code
composer format

๐Ÿ“œ License

This package is open-source software licensed under the MIT license.

โœจ Credits

Built with Saloon and Laravel