Skip to content

Project: Package setup, testing infrastructure, and documentation #31

@jordanpartridge

Description

@jordanpartridge

Summary

Set up complete package infrastructure including Composer configuration, service provider, testing framework, CI/CD, and comprehensive documentation.

Acceptance Criteria

Composer Configuration

{
    "name": "conduit-ui/pr",
    "description": "Expressive Laravel package for GitHub pull request automation and management",
    "type": "library",
    "license": "MIT",
    "keywords": [
        "github",
        "pull-request",
        "pr",
        "automation",
        "laravel",
        "conduit"
    ],
    "authors": [
        {
            "name": "Jordan Partridge",
            "email": "jordan@partridge.rocks"
        }
    ],
    "require": {
        "php": "^8.2",
        "illuminate/support": "^11.0|^12.0",
        "illuminate/collections": "^11.0|^12.0",
        "conduit-ui/connector": "^1.0",
        "nesbot/carbon": "^2.0|^3.0"
    },
    "require-dev": {
        "orchestra/testbench": "^9.0",
        "pestphp/pest": "^3.0",
        "laravel/pint": "^1.0",
        "phpstan/phpstan": "^1.10",
        "nunomaduro/larastan": "^2.0"
    },
    "autoload": {
        "psr-4": {
            "ConduitUI\\Pr\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "ConduitUI\\Pr\\Tests\\": "tests/"
        }
    },
    "scripts": {
        "test": "pest",
        "format": "pint",
        "analyse": "phpstan analyse"
    },
    "extra": {
        "laravel": {
            "providers": [
                "ConduitUI\\Pr\\PrServiceProvider"
            ],
            "aliases": {
                "PullRequests": "ConduitUI\\Pr\\Facades\\PullRequests"
            }
        }
    },
    "minimum-stability": "dev",
    "prefer-stable": true
}

Service Provider

namespace ConduitUI\Pr;

use Illuminate\Support\ServiceProvider;
use ConduitUI\Connector\GitHub;
use ConduitUI\Pr\Services\PullRequests;
use ConduitUI\Pr\Contracts;

class PrServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        // Register main service
        $this->app->singleton(PullRequests::class, function ($app) {
            return new PullRequests($app->make(GitHub::class));
        });
        
        // Bind interfaces to implementations
        $this->app->bind(
            Contracts\PullRequestQueryInterface::class,
            Services\PullRequestQuery::class
        );
        
        $this->app->bind(
            Contracts\PullRequestBuilderInterface::class,
            Services\PullRequestBuilder::class
        );
        
        $this->app->bind(
            Contracts\ReviewBuilderInterface::class,
            Services\ReviewBuilder::class
        );
        
        $this->app->bind(
            Contracts\CheckRunQueryInterface::class,
            Services\CheckRunQuery::class
        );
        
        $this->app->bind(
            Contracts\MergeManagerInterface::class,
            Services\MergeManager::class
        );
        
        $this->app->bind(
            Contracts\FileQueryInterface::class,
            Services\FileQuery::class
        );
        
        $this->app->bind(
            Contracts\LabelManagerInterface::class,
            Services\LabelManager::class
        );
        
        $this->app->bind(
            Contracts\CommentManagerInterface::class,
            Services\CommentManager::class
        );
    }
    
    public function boot(): void
    {
        // Configuration publishing would go here if needed
    }
}

Pest Configuration

// tests/Pest.php
<?php

use ConduitUI\Pr\Tests\TestCase;

uses(TestCase::class)->in(__DIR__);

Base Test Case

// tests/TestCase.php
<?php

namespace ConduitUI\Pr\Tests;

use Orchestra\Testbench\TestCase as Orchestra;
use ConduitUI\Pr\PrServiceProvider;

abstract class TestCase extends Orchestra
{
    protected function getPackageProviders($app): array
    {
        return [
            PrServiceProvider::class,
        ];
    }
    
    protected function getPackageAliases($app): array
    {
        return [
            'PullRequests' => \ConduitUI\Pr\Facades\PullRequests::class,
        ];
    }
}

PHPStan Configuration

# phpstan.neon
includes:
    - ./vendor/nunomaduro/larastan/extension.neon

parameters:
    paths:
        - src
    level: 8
    ignoreErrors:
        - '#Property .* is never read, only written#'
    checkMissingIterableValueType: false

Pint Configuration

{
    "preset": "laravel",
    "rules": {
        "declare_strict_types": true,
        "no_unused_imports": true,
        "ordered_imports": {
            "sort_algorithm": "alpha"
        }
    }
}

GitHub Actions Workflow

# .github/workflows/tests.yml
name: Tests

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        php: [8.2, 8.3]
        laravel: [11.*, 12.*]
    
    name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }}
    
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php }}
          extensions: dom, curl, libxml, mbstring, zip
          coverage: none
      
      - name: Install dependencies
        run: composer install --prefer-dist --no-interaction
      
      - name: Run tests
        run: composer test
      
      - name: Run static analysis
        run: composer analyse
      
      - name: Check code style
        run: composer format -- --test

Sentinel Gate Workflow

# .github/workflows/gate.yml
name: Sentinel Gate

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]

jobs:
  gate:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: 8.3
          extensions: dom, curl, libxml, mbstring, zip
          coverage: xdebug
      
      - name: Install dependencies
        run: composer install --prefer-dist --no-interaction
      
      - name: Run Pest tests
        run: composer test -- --coverage --min=80
      
      - name: Run PHPStan
        run: composer analyse
      
      - name: Run Pint
        run: composer format -- --test

Directory Structure

conduit-ui/pr/
├── .github/
│   └── workflows/
│       ├── tests.yml
│       └── gate.yml
├── src/
│   ├── Contracts/
│   │   ├── PullRequestQueryInterface.php
│   │   ├── PullRequestBuilderInterface.php
│   │   ├── ReviewBuilderInterface.php
│   │   ├── CheckRunQueryInterface.php
│   │   ├── MergeManagerInterface.php
│   │   ├── FileQueryInterface.php
│   │   ├── LabelManagerInterface.php
│   │   └── CommentManagerInterface.php
│   ├── Data/
│   │   ├── PullRequest.php
│   │   ├── Review.php
│   │   ├── CheckRun.php
│   │   ├── CheckSummary.php
│   │   ├── FileChange.php
│   │   ├── FileStats.php
│   │   ├── Comment.php
│   │   ├── ReviewComment.php
│   │   ├── User.php
│   │   └── Label.php
│   ├── Exceptions/
│   │   ├── MergeConflictException.php
│   │   └── UnmergeableException.php
│   ├── Facades/
│   │   └── PullRequests.php
│   ├── Services/
│   │   ├── PullRequests.php
│   │   ├── PullRequestInstance.php
│   │   ├── PullRequestQuery.php
│   │   ├── PullRequestBuilder.php
│   │   ├── PullRequestActions.php
│   │   ├── ReviewBuilder.php
│   │   ├── ReviewQuery.php
│   │   ├── CheckRunQuery.php
│   │   ├── MergeManager.php
│   │   ├── FileQuery.php
│   │   ├── LabelManager.php
│   │   ├── CommentManager.php
│   │   └── InlineCommentManager.php
│   └── PrServiceProvider.php
├── tests/
│   ├── Feature/
│   ├── Unit/
│   ├── Pest.php
│   └── TestCase.php
├── .gitignore
├── composer.json
├── phpstan.neon
├── pint.json
├── LICENSE.md
└── README.md

README Content Structure

# conduit-ui/pr

Expressive Laravel package for GitHub pull request automation and management.

## Features
- Fluent PR query builder
- Chainable PR actions
- Review workflow automation
- CI/CD check integration
- Merge strategy support
- File and diff analysis
- Label management
- Comment operations

## Installation
composer require conduit-ui/pr

## Quick Start
[Examples from main README]

## Documentation
- Core Concepts
- Query Builder
- PR Actions
- Review Workflow
- Merge Strategies
- File Analysis
- Label Management
- Comment System
- Examples & Recipes

## Testing
composer test

## License
MIT

Testing Requirements

Unit Tests

  • All Data DTOs have fromArray tests
  • All Service classes implement their interfaces
  • All query builders return correct types
  • All builders chain correctly
  • All managers handle errors gracefully

Feature Tests

  • End-to-end PR creation flow
  • Review submission workflow
  • Merge operations with different strategies
  • File query and filtering
  • Label management operations
  • Comment CRUD operations

Integration Tests

  • GitHub API mocking
  • Service provider bindings
  • Facade resolution
  • Collection operations

Example Tests

// tests/Feature/PullRequestTest.php
it('creates and merges PR', function() {
    $pr = PullRequests::create('owner/repo')
        ->title('Test PR')
        ->head('test-branch')
        ->create();
    
    expect($pr)->toBeInstanceOf(PullRequest::class);
    expect($pr->title)->toBe('Test PR');
});

// tests/Unit/PullRequestQueryTest.php
it('builds query with filters', function() {
    $query = new PullRequestQuery($github, 'owner/repo');
    
    $result = $query
        ->whereOpen()
        ->whereBase('main')
        ->orderByUpdated();
    
    expect($result)->toBeInstanceOf(PullRequestQuery::class);
});

Documentation Requirements

API Documentation

  • All public methods documented with PHPDoc
  • Parameter types and return types specified
  • Usage examples in docblocks
  • Exception documentation

User Documentation

  • Installation guide
  • Quick start guide
  • Comprehensive API reference
  • Common use cases and recipes
  • Troubleshooting guide

Examples

  • Basic PR operations
  • Automated workflows
  • Review automation
  • CI/CD integration
  • Label-based workflows
  • Bulk operations

Related Issues

All package issues (#20-30)

References

Labels

  • infrastructure
  • testing
  • documentation
  • high-priority

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions