Nav apraksta

Claude (AgentBox) bea11a8266 Add command execution feature to webhook server 9 mēneši atpakaļ
examples c6c4f8a633 Add modular Node.js webhook server for Gogs 9 mēneši atpakaļ
src bea11a8266 Add command execution feature to webhook server 9 mēneši atpakaļ
.env.example bea11a8266 Add command execution feature to webhook server 9 mēneši atpakaļ
.gitignore c6c4f8a633 Add modular Node.js webhook server for Gogs 9 mēneši atpakaļ
README.md bea11a8266 Add command execution feature to webhook server 9 mēneši atpakaļ
package.json c6c4f8a633 Add modular Node.js webhook server for Gogs 9 mēneši atpakaļ

README.md

Gogs Webhook Server

A modular Node.js server for receiving and processing Gogs webhooks. The server logs all incoming webhooks to the console, executes configured commands based on webhook events, and provides an extensible callback system for custom event handling.

Features

  • Modular Architecture: Clean separation of concerns (server, handler, logger)
  • Command Execution: Execute shell commands on webhook events with variable substitution
  • Environment Configuration: Configure commands via .env file
  • Variable Substitution: Access repo name, branch, pusher, and more in commands
  • Branch Filtering: Execute commands only for specific branches
  • Extensible Callback System: Register callbacks for specific events or all events
  • Console Logging: Colored, formatted logging of all webhook events
  • Health Check Endpoint: Built-in health monitoring
  • Graceful Shutdown: Proper cleanup on process termination
  • Zero Dependencies: Pure Node.js implementation

Requirements

  • Node.js >= 18.0.0

Installation

npm install

Usage

Quick Start

  1. Copy the example environment file:

    cp .env.example .env
    
  2. Edit .env to configure commands for webhook events (see Configuration section below)

  3. Start the server:

    npm start
    

The server will start on port 3000 and execute configured commands when webhooks are received.

Development Mode (Auto-reload)

npm run dev

Configuration

The server is configured using a .env file. Copy .env.example to .env and edit it:

cp .env.example .env

Basic Server Configuration

PORT=3000
WEBHOOK_PATH=/webhook
WEBHOOK_SECRET=your-secret-here

Command Execution Configuration

Configure commands to execute when webhooks are received. Commands support variable substitution:

Available Variables:

  • {{repo}} - Repository name (e.g., "my-repo")
  • {{full_repo}} - Full repository name (e.g., "user/my-repo")
  • {{branch}} - Branch name (e.g., "main", "feature/new-feature")
  • {{pusher}} - Username of person who triggered the event
  • {{event}} - Event type (e.g., "push", "pull_request")
  • {{commit}} - Latest commit hash (short, for push events)
  • {{commit_msg}} - Latest commit message (for push events)
  • {{pr_number}} - Pull request number (for PR events)
  • {{pr_action}} - Pull request action (opened, closed, etc.)
  • {{tag}} - Tag name (for create/delete tag events)

Example .env configuration:

# Execute command on push events
WEBHOOK_PUSH_ENABLED=true
WEBHOOK_PUSH_COMMAND=echo "Push to {{branch}} by {{pusher}} in {{repo}}"

# Deploy only when pushing to main branch
WEBHOOK_PUSH_FILTER_BRANCH=main
WEBHOOK_PUSH_COMMAND=/path/to/deploy.sh {{branch}} {{repo}} {{pusher}}

# Execute command on pull request events
WEBHOOK_PULL_REQUEST_ENABLED=true
WEBHOOK_PULL_REQUEST_COMMAND=echo "PR #{{pr_number}} {{pr_action}} by {{pusher}}"

# Global command (runs for all events)
WEBHOOK_GLOBAL_ENABLED=true
WEBHOOK_GLOBAL_COMMAND=/path/to/notify.sh {{event}} {{repo}} {{pusher}}

Supported Event Types:

  • WEBHOOK_PUSH_* - Push events
  • WEBHOOK_PULL_REQUEST_* - Pull request events
  • WEBHOOK_CREATE_* - Branch/tag creation
  • WEBHOOK_DELETE_* - Branch/tag deletion
  • WEBHOOK_RELEASE_* - Release events
  • WEBHOOK_GLOBAL_* - All events

Command Settings:

COMMAND_TIMEOUT=300000          # Command timeout in ms (default: 5 minutes)
COMMAND_WORKING_DIR=/workspace  # Working directory for commands

Endpoints

  • POST /webhook - Webhook endpoint
  • GET /health - Health check endpoint

Real-World Examples

Example 1: Auto-deploy on push to main

.env:

WEBHOOK_PUSH_ENABLED=true
WEBHOOK_PUSH_FILTER_BRANCH=main
WEBHOOK_PUSH_COMMAND=/home/deploy/deploy.sh {{repo}} {{branch}} {{commit}}

deploy.sh:

#!/bin/bash
REPO=$1
BRANCH=$2
COMMIT=$3

echo "Deploying $REPO from $BRANCH (commit: $COMMIT)"
cd /var/www/$REPO
git pull origin $BRANCH
npm install
npm run build
systemctl restart $REPO

Example 2: Send notification on any webhook

.env:

WEBHOOK_GLOBAL_ENABLED=true
WEBHOOK_GLOBAL_COMMAND=curl -X POST https://api.slack.com/webhook -d '{"text":"{{event}} in {{repo}} by {{pusher}}"}'

Example 3: Run tests on pull request

.env:

WEBHOOK_PULL_REQUEST_ENABLED=true
WEBHOOK_PULL_REQUEST_COMMAND=/home/scripts/run-tests.sh {{repo}} {{pr_number}} {{pusher}}

Extending with Callbacks

The server is designed to be easily extended with custom callbacks. See examples/with-callbacks.js for a complete example.

Register Event-Specific Callbacks

import { WebhookServer } from './src/server.js';

const server = new WebhookServer({ port: 3000 });
const handler = server.getHandler();

// Handle push events
handler.on('push', async (payload, headers) => {
  console.log('Push to:', payload.repository.name);
  console.log('Commits:', payload.commits.length);
  // Your custom logic here
});

// Handle pull request events
handler.on('pull_request', async (payload, headers) => {
  console.log('PR:', payload.action);
  // Your custom logic here
});

server.start();

Register Global Callbacks

// Handle all events
handler.onAny(async (eventType, payload, headers) => {
  console.log('Received event:', eventType);
  // Send to analytics, external logging, etc.
});

Run the Example

node examples/with-callbacks.js

Gogs Webhook Configuration

  1. Go to your Gogs repository settings
  2. Navigate to Webhooks → Add Webhook → Gogs
  3. Configure:
    • Payload URL: http://your-server:3000/webhook
    • Content Type: application/json
    • Secret: (optional) your webhook secret
    • Events: Select which events to receive
  4. Click "Add Webhook"

Supported Events

  • push - Repository push
  • create - Branch or tag creation
  • delete - Branch or tag deletion
  • pull_request - Pull request actions
  • issues - Issue actions
  • issue_comment - Issue comment actions
  • release - Release actions

Project Structure

.
├── src/
│   ├── index.js           # Main entry point
│   ├── server.js          # HTTP server implementation
│   ├── webhookHandler.js  # Webhook processing and callbacks
│   ├── commandExecutor.js # Command execution with variable substitution
│   ├── config.js          # Configuration loader (.env parser)
│   └── logger.js          # Logging utility
├── examples/
│   └── with-callbacks.js  # Example with custom callbacks
├── .env.example           # Example configuration file
├── package.json
└── README.md

Architecture

WebhookServer (src/server.js)

  • Creates HTTP server
  • Handles routing and request parsing
  • Manages webhook verification
  • Delegates webhook processing to handler

WebhookHandler (src/webhookHandler.js)

  • Manages callback registration
  • Executes callbacks for events
  • Supports event-specific and global callbacks
  • Provides error handling for callbacks

Logger (src/logger.js)

  • Formats and colorizes console output
  • Provides structured logging methods
  • Handles timestamp formatting

Config (src/config.js)

  • Loads and parses .env file
  • Provides configuration access methods
  • Merges environment variables with file config

CommandExecutor (src/commandExecutor.js)

  • Executes shell commands on webhook events
  • Performs variable substitution
  • Handles command timeouts and errors
  • Extracts webhook payload data

Testing

You can test the webhook server using curl:

# Test health check
curl http://localhost:3000/health

# Test webhook with push event
curl -X POST http://localhost:3000/webhook \
  -H "Content-Type: application/json" \
  -H "X-Gogs-Event: push" \
  -H "X-Gogs-Delivery: 12345" \
  -d '{
    "ref": "refs/heads/main",
    "repository": {
      "name": "test-repo",
      "full_name": "user/test-repo"
    },
    "pusher": {
      "username": "testuser"
    },
    "commits": [
      {
        "id": "abc123",
        "message": "Test commit"
      }
    ]
  }'

License

ISC