定制 balescoses/github-webhooks 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

balescoses/github-webhooks

Composer 安装命令:

composer require balescoses/github-webhooks

包简介

Laravel package for handling GitHub webhooks

README 文档

README

A comprehensive Laravel package for handling GitHub webhooks with database storage, signature validation, event management, and automated deployment capabilities.

Requirements

  • PHP ^8.2
  • Laravel ^11.0 or ^12.0

Installation

  1. Add the package to your local composer.json:
{
    "repositories": [
        {
            "type": "path",
            "url": "./packages/github-webhooks"
        }
    ],
    "require": {
        "laravel/github-webhooks": "*"
    }
}
  1. Install the package:
composer require laravel/github-webhooks
  1. Publish configuration and migrations:
php artisan vendor:publish --tag=github-webhooks-config
php artisan vendor:publish --tag=github-webhooks-migrations
  1. Run migrations:
php artisan migrate

Configuration

Environment Variables

Add these variables to your .env file:

# Secret for validating GitHub webhooks (optional but recommended)
GITHUB_WEBHOOK_SECRET=your-webhook-secret

# Route prefix (default: webhooks)
GITHUB_WEBHOOK_ROUTE_PREFIX=webhooks

# Store webhooks in database (default: true)
GITHUB_WEBHOOK_STORE=true

# Deployment Configuration
GITHUB_WEBHOOK_BRANCH=main
GITHUB_WEBHOOK_REPOSITORY_PATH=/path/to/your/project
GITHUB_WEBHOOK_RUN_COMPOSER=true
GITHUB_WEBHOOK_RUN_MIGRATIONS=true
GITHUB_WEBHOOK_RUN_NPM=false
GITHUB_WEBHOOK_RUN_CACHE_CLEAR=true
GITHUB_WEBHOOK_OPTIMIZE=true
GITHUB_WEBHOOK_CREATE_STORAGE_LINK=true
GITHUB_WEBHOOK_RESTART_QUEUE=false

Configuration File

The package configuration file (config/github-webhooks.php) provides extensive options:

return [
    // GitHub webhook secret for signature validation
    'secret' => env('GITHUB_WEBHOOK_SECRET'),

    // Route configuration
    'route_prefix' => env('GITHUB_WEBHOOK_ROUTE_PREFIX', 'webhooks'),
    'middleware' => [
        // Add middleware like 'throttle:60,1'
    ],

    // Storage configuration
    'store_webhooks' => env('GITHUB_WEBHOOK_STORE', true),

    // Handler configuration
    'handlers' => [
        'push' => [
            App\Webhooks\Handlers\PushHandler::class,
        ],
        'pull_request' => [
            App\Webhooks\Handlers\PullRequestHandler::class,
        ],
        '*' => [
            App\Webhooks\Handlers\LogAllEventsHandler::class,
        ],
    ],

    // Error handling
    'continue_on_handler_failure' => true,

    // Auto-deployment configuration
    'auto_update_branches' => ['main', 'master', 'develop'],
    'branch' => env('GITHUB_WEBHOOK_BRANCH', 'main'),
    'repository_path' => env('GITHUB_WEBHOOK_REPOSITORY_PATH', base_path()),

    'deployment' => [
        'run_composer' => env('GITHUB_WEBHOOK_RUN_COMPOSER', true),
        'run_migrations' => env('GITHUB_WEBHOOK_RUN_MIGRATIONS', true),
        'run_npm' => env('GITHUB_WEBHOOK_RUN_NPM', false),
        'cache_clear' => env('GITHUB_WEBHOOK_RUN_CACHE_CLEAR', true),
        'optimize' => env('GITHUB_WEBHOOK_OPTIMIZE', true),
        'create_storage_link' => env('GITHUB_WEBHOOK_CREATE_STORAGE_LINK', true),
        'restart_queue' => env('GITHUB_WEBHOOK_RESTART_QUEUE', false),
    ]
];

GitHub Configuration

  1. Go to your GitHub repository settings
  2. Click "Webhooks" in the left menu
  3. Click "Add webhook"
  4. Configure:
    • Payload URL: https://your-domain.com/webhooks/github
    • Content type: application/json
    • Secret: Your secret (same as GITHUB_WEBHOOK_SECRET)
    • Events: Select the events you want to receive

Features

✅ Core Features

  • Webhook Reception: Secure endpoint for GitHub webhooks
  • Signature Validation: HMAC-SHA256 signature verification
  • Database Storage: Store webhook data for audit and replay
  • Event Handling: Flexible handler system for different events
  • Error Handling: Robust error handling with optional failure tolerance

✅ Deployment Automation

  • Automated Git Pull: Automatic repository updates on push events
  • Composer Management: Automatic dependency installation
  • NPM Support: Node.js dependency and build management
  • Database Migrations: Automatic migration execution
  • Cache Management: Cache clearing and optimization
  • Queue Management: Worker restart capability
  • Storage Links: Automatic symbolic link creation

✅ Management Commands

  • Webhook Management: List, filter, and reprocess webhooks
  • Repository Operations: Clone and update repositories
  • Secret Generation: Secure webhook secret generation
  • Configuration Validation: Validate webhook setup

Usage

Custom Handlers

Create handlers to process GitHub events:

<?php

namespace App\Webhooks\Handlers;

use Illuminate\Http\Request;
use Laravel\GitHubWebhooks\Contracts\WebhookHandler;

class DeploymentHandler implements WebhookHandler
{
    public function handle(string $event, array $payload, Request $request): mixed
    {
        if ($event === 'push') {
            $branch = str_replace('refs/heads/', '', $payload['ref'] ?? '');
            
            if ($branch === 'main') {
                // Trigger deployment
                $this->triggerDeployment($payload);
            }
        }

        return ['deployed' => true];
    }

    private function triggerDeployment(array $payload): void
    {
        // Your deployment logic
    }
}

Registering Handlers

In config/github-webhooks.php:

'handlers' => [
    'push' => [
        App\Webhooks\Handlers\DeploymentHandler::class,
    ],
    'pull_request' => [
        App\Webhooks\Handlers\PullRequestHandler::class,
    ],
    // Handler for all events
    '*' => [
        App\Webhooks\Handlers\LogAllEventsHandler::class,
    ],
],

Programmatic Usage

use Laravel\GitHubWebhooks\GitHubWebhooks;

// Register a handler on the fly
GitHubWebhooks::on('push', function ($event, $payload, $request) {
    // Process push event
    return ['status' => 'processed'];
});

// Register handler for multiple events
GitHubWebhooks::on(['push', 'pull_request'], new MyCustomHandler());

Deployment Service

The package includes a comprehensive deployment service for automated deployments:

use Laravel\GitHubWebhooks\Service\DeploymentService;

// In your webhook handler
public function handle(string $event, array $payload, Request $request): mixed
{
    if ($event === 'push') {
        $branch = str_replace('refs/heads/', '', $payload['ref'] ?? '');
        
        if (in_array($branch, config('github-webhooks.auto_update_branches', ['main']))) {
            $deploymentService = new DeploymentService();
            $result = $deploymentService->deploy($payload);
            
            return $result;
        }
    }
    
    return ['status' => 'skipped'];
}

The deployment service automatically handles:

  • Git Pull: Updates repository from the specified branch
  • Composer Install: Installs PHP dependencies with optimization
  • NPM Operations: Installs and builds frontend assets
  • Database Migrations: Runs pending migrations safely
  • Cache Management: Clears and rebuilds application cache
  • Optimization: Caches routes, config, and views for production
  • Storage Links: Creates symbolic links for public storage
  • Queue Restart: Restarts queue workers to load new code

Each step is configurable via the deployment configuration and logs detailed information for monitoring.

Event Listeners

use Laravel\GitHubWebhooks\Events\GitHubWebhookReceived;

// In your EventServiceProvider
protected $listen = [
    GitHubWebhookReceived::class => [
        App\Listeners\HandleGitHubWebhook::class,
    ],
];
<?php

namespace App\Listeners;

use Laravel\GitHubWebhooks\Events\GitHubWebhookReceived;

class HandleGitHubWebhook
{
    public function handle(GitHubWebhookReceived $event): void
    {
        $eventType = $event->eventType;
        $payload = $event->payload;
        $deliveryId = $event->deliveryId;

        // Your custom logic
    }
}

Artisan Commands

The package provides several Artisan commands for managing GitHub webhooks:

Secret Management

# Generate a new secure webhook secret
php artisan github-webhooks:generate-secret

# Show the secret without writing to .env
php artisan github-webhooks:generate-secret --show

# Force overwrite existing secret
php artisan github-webhooks:generate-secret --force

# Generate secret with custom length
php artisan github-webhooks:generate-secret --length=64

Configuration Validation

# Validate complete configuration
php artisan github-webhooks:validate

# Test with specific URL
php artisan github-webhooks:validate --url=https://your-domain.com/webhooks/github

Webhook Management

# List all webhooks
php artisan github-webhooks:list

# Filter by event type
php artisan github-webhooks:list --event=push

# Show only unprocessed webhooks
php artisan github-webhooks:list --unprocessed

# Show only processed webhooks
php artisan github-webhooks:list --processed

# Limit number of results
php artisan github-webhooks:list --limit=5

# Reprocess specific webhook
php artisan github-webhooks:reprocess {webhook_id}

Repository Management

# List all local repositories
php artisan github-webhooks:list-repos

# Update repository from GitHub
php artisan github-webhooks:update-repo owner/repo --branch=main --clone-url=https://github.com/owner/repo.git

# Force update (ignore local changes)
php artisan github-webhooks:update-repo owner/repo --force

# Use custom path
php artisan github-webhooks:list-repos --path=/custom/path

Data Model

The package stores webhooks in the git_hub_webhooks table with these fields:

  • id: Auto-incremented ID
  • event_type: GitHub event type (push, pull_request, etc.)
  • delivery_id: GitHub delivery ID for deduplication
  • payload: JSON webhook data from GitHub
  • headers: HTTP headers from the webhook request
  • processed_at: Processing timestamp (nullable)
  • created_at / updated_at: Laravel timestamps

Model Usage

use Laravel\GitHubWebhooks\Models\GitHubWebhook;

// Get all unprocessed push webhooks
$webhooks = GitHubWebhook::eventType('push')
    ->unprocessed()
    ->get();

// Get all processed webhooks
$processedWebhooks = GitHubWebhook::processed()->get();

// Mark a webhook as processed
$webhook->update(['processed_at' => now()]);

// Get webhooks by delivery ID
$webhook = GitHubWebhook::where('delivery_id', $deliveryId)->first();

Available Scopes

The GitHubWebhook model includes these query scopes:

  • unprocessed(): Webhooks that haven't been processed yet
  • processed(): Webhooks that have been processed
  • eventType($type): Filter by specific GitHub event type

Security

Signature Validation

The package automatically validates GitHub signatures if you configure a secret. This validation:

  • Uses HMAC-SHA256 algorithm as required by GitHub
  • Compares securely with hash_equals() to prevent timing attacks
  • Returns 401 error if signature is invalid
  • Logs security violations for monitoring

Exception Handling

The package provides specific exceptions for different error scenarios:

  • InvalidSignatureException: Thrown when webhook signature validation fails
  • DeploymentFailedException: Thrown when automated deployment encounters errors
  • WebhookHandlerException: Thrown when custom handlers fail
  • RepositoryException: Thrown when repository operations fail
  • SlackNotificationException: Thrown when notification services fail
use Laravel\GitHubWebhooks\Exceptions\InvalidSignatureException;
use Laravel\GitHubWebhooks\Exceptions\DeploymentFailedException;

try {
    // Your webhook handling code
} catch (InvalidSignatureException $e) {
    // Handle signature validation failure
    Log::warning('Invalid webhook signature', ['error' => $e->getMessage()]);
} catch (DeploymentFailedException $e) {
    // Handle deployment failure
    Log::error('Deployment failed', ['error' => $e->getMessage()]);
}

Recommended Middleware

Add middleware in configuration:

'middleware' => [
    'throttle:60,1', // Rate limiting
    'api',           // API middleware
],

Supported GitHub Events

The package can handle all GitHub events, including:

  • push: Commits pushed
  • pull_request: Pull requests (opened, closed, synchronized, etc.)
  • issues: Issues (opened, closed, labeled, etc.)
  • release: Releases
  • deployment: Deployments
  • workflow_run: GitHub Actions runs
  • And many more...

Troubleshooting

Debug Mode

Enable debug logging by setting the log level to debug in your webhook handlers:

use Illuminate\Support\Facades\Log;

public function handle(string $event, array $payload, Request $request): mixed
{
    Log::debug('Webhook received', [
        'event' => $event,
        'delivery_id' => $request->header('X-GitHub-Delivery'),
        'payload_size' => strlen(json_encode($payload))
    ]);
    
    // Your handling logic
}

Common Issues

Webhook Not Received

  1. Check URL accessibility: Ensure your webhook URL is publicly accessible
  2. Verify routing: Check that the route is properly registered
  3. Review middleware: Ensure middleware doesn't block the requests
  4. Check GitHub delivery: Review the "Recent Deliveries" tab in GitHub webhook settings

Signature Validation Fails

  1. Secret mismatch: Verify GITHUB_WEBHOOK_SECRET matches GitHub configuration
  2. Encoding issues: Ensure the secret doesn't contain special characters that might be encoded differently
  3. Environment loading: Verify the .env file is properly loaded

Deployment Failures

  1. Permission issues: Ensure the web server has proper file permissions
  2. Git access: Verify the server can access the Git repository
  3. Dependencies: Check that required tools (git, composer, npm) are installed
  4. Path configuration: Verify GITHUB_WEBHOOK_REPOSITORY_PATH is correct

Check Logs

Monitor webhook processing through Laravel logs:

# Follow real-time logs
tail -f storage/logs/laravel.log

# Search for webhook-related entries
grep -i "webhook" storage/logs/laravel.log

# Search for deployment logs
grep -i "deployment" storage/logs/laravel.log

Test Webhooks Locally

Use ngrok for local development and testing:

# Install ngrok
brew install ngrok  # macOS
# or download from https://ngrok.com

# Expose local server
ngrok http 8000

# Use the generated URL in GitHub webhook configuration
# Example: https://abc123.ngrok.io/webhooks/github

Validate Configuration

Use the built-in validation command to check your setup:

php artisan github-webhooks:validate

This command checks:

  • Configuration file validity
  • Environment variables
  • Route registration
  • Handler class existence
  • Database connectivity

Testing Webhook Processing

You can manually test webhook processing using the reprocess command:

# List recent webhooks
php artisan github-webhooks:list --limit=5

# Reprocess a specific webhook
php artisan github-webhooks:reprocess {webhook_id}

Contributing

This package is designed to be extensible and welcomes contributions. You can:

Extend Functionality

  • Create custom handlers: Implement the WebhookHandler interface for specialized processing
  • Extend the GitHubWebhook model: Add custom attributes and relationships
  • Add custom middleware: Implement additional security or processing layers
  • Custom deployment steps: Extend the DeploymentService for specific needs

Development Setup

  1. Clone the repository
  2. Install dependencies: composer install
  3. Run tests: vendor/bin/phpunit
  4. Follow PSR-12 coding standards

Testing

The package includes comprehensive tests. Run them with:

vendor/bin/phpunit

Package Information

  • Name: laravel/github-webhooks
  • Version: 1.0.0
  • Author: Balesco (balehormo25@gmail.com)
  • License: MIT
  • Requirements: PHP ^8.2, Laravel ^11.0|^12.0

License

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

Support

For issues, feature requests, or questions:

  1. Check the troubleshooting section above
  2. Review existing GitHub issues
  3. Create a new issue with detailed information
  4. Include log outputs and configuration when reporting bugs

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-08-12