설명 없음

Claude 5ecd4f06aa feat: add npm scripts to install and build client automatically #38 8 달 전
client 5a6e6866c1 docs: actualize client README with current features #22 9 달 전
docs dea6ef0215 feat: force Claude to communicate only via issue comments 9 달 전
examples 5f81f5b334 feat: add per-repository MCP configuration support #13 9 달 전
scripts 43568b5ad9 chore: remove obsolete shell script and update documentation #26 9 달 전
src b2155b3f1a feat: add file logging with automatic rotation #35 9 달 전
.env.example b2155b3f1a feat: add file logging with automatic rotation #35 9 달 전
.gitignore b2155b3f1a feat: add file logging with automatic rotation #35 9 달 전
.mcp-gogs.json.example 482c07b709 feat: enable MCP tools in Claude Code headless mode with environment-specific configuration 9 달 전
.smtp-config.json.example b2155b3f1a feat: add file logging with automatic rotation #35 9 달 전
CLAUDE.md 7eb85de66e docs: update CLAUDE.md with file logging documentation #35 9 달 전
README.md 9c5fbf18ba feat: add multi-queue system with per-repository parallel processing #30 9 달 전
SYSTEMD.md 1f39ddaa15 feat: add systemd install and uninstall scripts 9 달 전
agent-manager.service b2155b3f1a feat: add file logging with automatic rotation #35 9 달 전
commands.json 19ba0c2680 feat: add label-aware behavior for Claude agent #25 9 달 전
commands.json.example 19ba0c2680 feat: add label-aware behavior for Claude agent #25 9 달 전
email-rules.json.example b2155b3f1a feat: add file logging with automatic rotation #35 9 달 전
install.sh 1f39ddaa15 feat: add systemd install and uninstall scripts 9 달 전
package-lock.json 3aec5c4975 Add persistent job queue and issue event support 9 달 전
package.json 5ecd4f06aa feat: add npm scripts to install and build client automatically #38 8 달 전
show-example-prompts.sh a1696845f0 feat: force Claude to read all issue comments via MCP tools 9 달 전
test-signature-verification.js 05ec4a0045 fix: improve signature verification error handling #14 9 달 전
uninstall.sh 1f39ddaa15 feat: add systemd install and uninstall scripts 9 달 전

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

  • Persistent Job Queue: FIFO queue ensures sequential execution and crash recovery
  • Modular Architecture: Clean separation of concerns (server, handler, queue, logger)
  • Command Execution: Execute shell or Node.js commands on webhook events
  • Email Notifications: Event-based email notifications with condition matching
  • JSON Configuration: Flexible command configuration via commands.json
  • Multiple Commands per Event: Run multiple commands for each webhook event type
  • Variable Substitution: Access repo name, branch, pusher, issue details, and more in commands
  • Branch Filtering: Execute commands only for specific branches
  • Node.js & Shell Support: Run both shell scripts and Node.js scripts
  • Per-Command Settings: Configure working directory and timeout per command
  • 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: Saves queue state and ensures 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 files:

    cp .env.example .env
    cp commands.json.example commands.json
    cp .smtp-config.json.example .smtp-config.json  # Optional, for email notifications
    cp email-rules.json.example email-rules.json    # Optional, for email notifications
    
  2. Edit .env to enable/disable webhook events

  3. Edit commands.json to configure commands for webhook events (see Configuration section below)

  4. (Optional) Configure email notifications:

    • Edit .smtp-config.json with your SMTP server settings
    • Edit email-rules.json to define email notification rules
  5. 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

Running as a Systemd Service

For production deployments, you can run the server as a systemd service. This provides:

  • Automatic start on system boot
  • Automatic restart on failure
  • Centralized logging via journalctl
  • Running as an unprivileged user

See SYSTEMD.md for detailed installation and configuration instructions.

Quick example:

# Install the service
sudo cp agent-manager.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable agent-manager
sudo systemctl start agent-manager

# View logs
journalctl -u agent-manager -f -n100

Configuration

The server uses two configuration files:

  1. .env - Enable/disable webhook events and server settings
  2. commands.json - Define commands to execute for each event type

Basic Server Configuration (.env)

HOST=0.0.0.0
PORT=3000
WEBHOOK_PATH=/webhook
WEBHOOK_SECRET=your-secret-here
  • HOST - The network interface to bind to (default: 0.0.0.0 for all interfaces, use 127.0.0.1 for localhost only)
  • PORT - The port number to listen on (default: 3000)
  • WEBHOOK_PATH - The URL path for webhooks (default: /webhook)
  • WEBHOOK_SECRET - Optional secret for webhook signature verification (see Security section below)

Enable/Disable Events (.env)

WEBHOOK_PUSH_ENABLED=true
WEBHOOK_PULL_REQUEST_ENABLED=false
WEBHOOK_CREATE_ENABLED=false
WEBHOOK_DELETE_ENABLED=false
WEBHOOK_RELEASE_ENABLED=false
WEBHOOK_ISSUES_ENABLED=false
WEBHOOK_ISSUE_COMMENT_ENABLED=false
WEBHOOK_GLOBAL_ENABLED=false

Command Configuration (commands.json)

Commands are configured in a JSON file with the following structure:

{
  "commands": {
    "push": [
      {
        "name": "deploy-production",
        "description": "Deploy to production on main branch",
        "type": "shell",
        "command": "/path/to/deploy.sh",
        "args": ["{{branch}}", "{{repo}}", "{{pusher}}"],
        "cwd": "/workspace",
        "timeout": 600000,
        "filterBranch": "main"
      }
    ],
    "issues": [
      {
        "name": "process-issue",
        "description": "Process issue with Node.js script",
        "type": "node",
        "command": "./scripts/process-issue.js",
        "args": ["--repo", "{{repo}}", "--issue", "{{issue_number}}"],
        "cwd": null,
        "timeout": 300000,
        "filterBranch": null
      }
    ]
  }
}

Command Fields:

  • name - Unique identifier for the command
  • description - Human-readable description
  • type - Either "shell" (bash script) or "node" (Node.js script)
  • command - The command or script to execute
  • args - Array of arguments (supports variable substitution)
  • cwd - Working directory (null uses project root)
  • timeout - Timeout in milliseconds
  • filterBranch - Only run for specific branch (null = all branches)

Available Variables:

  • {{repo}} - Repository name (e.g., "my-repo")
  • {{full_repo}} - Full repository name (e.g., "user/my-repo")
  • {{repo_owner}} - Repository owner username (e.g., "user")
  • {{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)
  • {{ref_type}} - "branch" or "tag"
  • {{issue_number}} - Issue number (for issue events)
  • {{issue_title}} - Issue title (for issue events)
  • {{issue_action}} - Issue action (opened, closed, reopened, etc.)
  • {{issue_body}} - Issue description/body (for issue events)
  • {{issue_assignee}} - Username of the person assigned to the issue (for issue events)
  • {{comment_body}} - Comment text (for issue_comment events)

Supported Event Types:

  • push - Push events
  • pull_request - Pull request events
  • create - Branch/tag creation
  • delete - Branch/tag deletion
  • release - Release events
  • issues - Issue events (opened, closed, reopened, etc.)
  • issue_comment - Issue comment events
  • global - All events

Endpoints

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

Security

Webhook Signature Verification

The server supports HMAC-SHA256 signature verification to ensure webhooks are authentic and haven't been tampered with.

How It Works

When you configure a secret in Gogs webhook settings and in your .env file, Gogs will sign each webhook request with an HMAC-SHA256 signature and send it in the X-Gogs-Signature header. The server verifies this signature before processing the webhook.

Setup

  1. Configure Secret in .env:

    WEBHOOK_SECRET=your-secure-random-string
    
  2. Configure Secret in Gogs:

  3. Go to your repository settings → Webhooks

  4. Edit or create a webhook

  5. Set the same secret value in the "Secret" field

  6. Set Content Type to application/json

Behavior

  • Secret Configured: The server requires a valid X-Gogs-Signature header and rejects webhooks with missing or invalid signatures (HTTP 401)
  • No Secret Configured: Signature verification is skipped, and all webhooks are accepted (useful for development)

Security Best Practices

  • Use a strong, random secret (at least 32 characters)
  • Keep your secret secure and never commit it to version control
  • Use different secrets for different environments (development, staging, production)
  • Rotate secrets periodically for enhanced security

Verification Process

The server:

  1. Computes an HMAC-SHA256 hash of the raw request body using the configured secret
  2. Compares it with the signature from the X-Gogs-Signature header using a timing-safe comparison
  3. Accepts the webhook if signatures match, rejects otherwise

This ensures:

  • Authenticity: The webhook came from Gogs with the correct secret
  • Integrity: The payload hasn't been modified in transit
  • Replay Protection: Combined with Gogs' delivery ID tracking

Job Queue System

The webhook server uses a persistent job queue to ensure reliable command execution. The queue supports two operating modes:

Operating Modes

Single-Queue Mode (Default)

  • One global FIFO queue for all repositories
  • Jobs execute sequentially, one at a time
  • Recommended for single-repository setups or when strict sequential execution is required

Multi-Queue Mode (Parallel Per Repository)

  • Separate FIFO queue for each Gogs repository
  • Jobs from different repositories execute in parallel
  • Each repository maintains FIFO order internally
  • Recommended for multi-repository setups where independent execution is desired
  • Enable with: QUEUE_PARALLEL_PER_REPOSITORY=true in .env

How It Works

  1. Webhook Received: When a webhook arrives, it's immediately accepted and added to the queue
  2. Quick Response: The server responds to Gogs instantly (no timeout issues)
  3. Queue Selection:
    • Single-queue mode: Job added to global queue
    • Multi-queue mode: Job added to repository-specific queue
  4. Processing: Jobs execute in FIFO order (per repository in multi-queue mode)
  5. Persistence: Queue state is saved to queue.json after every change
  6. Crash Recovery: If the server crashes or restarts, pending jobs are automatically resumed

Benefits

Single-Queue Mode:

  • No Lost Webhooks: Even if the server crashes, queued jobs are preserved and executed after restart
  • No Concurrent Execution: Prevents conflicts when multiple webhooks trigger deployment scripts
  • Handle Bursts: Can accept many webhooks quickly while processing them sequentially
  • Predictable Order: Strict sequential execution across all repositories

Multi-Queue Mode:

  • All benefits of single-queue mode, plus:
  • Parallel Execution: Jobs from different repositories run independently
  • Better Resource Usage: Multiple repositories can be processed simultaneously
  • Reduced Wait Time: One slow repository won't block others
  • Repository Isolation: Issues in one repository don't affect others

Queue File

The queue state is stored in queue.json in the project root.

Single-Queue Mode:

{
  "queue": [
    {
      "id": 1,
      "eventType": "push",
      "status": "pending",
      "createdAt": "2025-10-28T12:00:00.000Z"
    }
  ],
  "jobIdCounter": 5,
  "lastSaved": "2025-10-28T12:05:00.000Z"
}

Multi-Queue Mode:

{
  "queues": {
    "owner/repo1": {
      "queue": [{ "id": 1, "eventType": "push", "status": "pending" }]
    },
    "owner/repo2": {
      "queue": [{ "id": 2, "eventType": "issues", "status": "running" }]
    }
  },
  "jobIdCounter": 5,
  "lastSaved": "2025-10-28T12:05:00.000Z"
}

This file is automatically managed and should not be manually edited. It's excluded from git via .gitignore.

Email Notifications

The server includes an email notification system that can send emails based on webhook events and configurable conditions.

Configuration

Email notifications require two configuration files:

  1. .smtp-config.json - SMTP server configuration (excluded from git)
  2. email-rules.json - Email notification rules (excluded from git)

Copy the example files to get started:

cp .smtp-config.json.example .smtp-config.json
cp email-rules.json.example email-rules.json

SMTP Configuration (.smtp-config.json)

{
  "host": "mail.example.com",
  "port": 1025,
  "secure": false,
  "user": "your-email@example.com",
  "pass": "your-password",
  "from": "noreply@example.com"
}

Fields:

  • host - SMTP server hostname
  • port - SMTP server port (25, 587, 465, etc.)
  • secure - Use TLS from start (true for port 465, false for STARTTLS)
  • user - SMTP username
  • pass - SMTP password
  • from - Email address to send from

Email Rules Configuration (email-rules.json)

{
  "rules": [
    {
      "name": "mention-notification",
      "event": "issue_comment",
      "condition": {
        "type": "mention",
        "value": "username"
      },
      "recipients": ["{{mentioned_user}}"],
      "subject": "You were mentioned in {{full_repo}}#{{issue_number}}",
      "body": "Comment by {{sender}}:\n{{comment_body}}"
    }
  ]
}

Rule Fields:

  • name - Unique identifier for the rule
  • event - Webhook event type to trigger on
  • condition - Condition that must be met (optional)
  • recipients - Array of email addresses or variables
  • subject - Email subject (supports variables)
  • body - Email body (supports variables)

Condition Types

mention - Check if a user is mentioned in the payload:

{
  "type": "mention",
  "value": "username"
}

branch - Check if event is for a specific branch:

{
  "type": "branch",
  "value": "main"
}

action - Check if webhook action matches:

{
  "type": "action",
  "value": "opened"
}

user - Check if sender/pusher matches:

{
  "type": "user",
  "value": "username"
}

repository - Check if repository matches:

{
  "type": "repository",
  "value": "owner/repo"
}

Recipient Variables

  • {{mentioned_user}} - User mentioned in comment/issue
  • {{sender}} - Event sender email
  • {{assignee}} - Issue/PR assignee email
  • Direct email addresses: "admin@example.com"

Email Body Variables

All the standard webhook variables are available in email subjects and bodies:

  • {{repo}}, {{full_repo}}, {{repo_owner}}
  • {{branch}}, {{sender}}, {{commit}}, {{commit_msg}}
  • {{issue_number}}, {{issue_title}}, {{issue_action}}
  • {{comment_body}}, {{mentioned_user}}
  • {{pr_number}}, {{pr_action}}

Example Rules

Notify mentioned users in issue comments:

{
  "name": "mention-notification",
  "event": "issue_comment",
  "condition": {
    "type": "mention",
    "value": ".*"
  },
  "recipients": ["{{mentioned_user}}"],
  "subject": "You were mentioned in {{full_repo}}#{{issue_number}}",
  "body": "Hi @{{mentioned_user}},\n\nYou were mentioned by {{sender}}:\n{{comment_body}}"
}

Notify team on push to main:

{
  "name": "push-to-main",
  "event": "push",
  "condition": {
    "type": "branch",
    "value": "main"
  },
  "recipients": ["dev-team@example.com"],
  "subject": "Push to {{full_repo}}/{{branch}}",
  "body": "Pusher: {{sender}}\nCommit: {{commit}}\nMessage: {{commit_msg}}"
}

Notify assignee when issue is assigned:

{
  "name": "issue-assigned",
  "event": "issues",
  "condition": {
    "type": "action",
    "value": "assigned"
  },
  "recipients": ["{{assignee}}"],
  "subject": "Issue assigned: {{full_repo}}#{{issue_number}}",
  "body": "You have been assigned to issue #{{issue_number}}: {{issue_title}}"
}

How It Works

  1. Registration: Email notifier registers callbacks for events defined in rules
  2. Event Processing: When a matching webhook arrives, conditions are evaluated
  3. Condition Check: If condition is met (or no condition exists), email is sent
  4. Variable Substitution: Variables in subject/body are replaced with actual values
  5. Recipient Resolution: User variables are converted to email addresses from payload
  6. Email Delivery: Email is sent via configured SMTP server

Security Notes

  • Configuration files (.smtp-config.json, email-rules.json) are excluded from git
  • Credentials are stored locally and never committed to version control
  • File permissions should be restricted (600) to protect SMTP credentials
  • Use strong passwords and consider using app-specific passwords where available

Real-World Examples

Example 1: Auto-deploy on push to main

.env:

WEBHOOK_PUSH_ENABLED=true

commands.json:

{
  "commands": {
    "push": [
      {
        "name": "deploy-production",
        "description": "Deploy to production on main branch",
        "type": "shell",
        "command": "/home/deploy/deploy.sh",
        "args": ["{{repo}}", "{{branch}}", "{{commit}}"],
        "cwd": null,
        "timeout": 600000,
        "filterBranch": "main"
      }
    ]
  }
}

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

commands.json:

{
  "commands": {
    "global": [
      {
        "name": "slack-notification",
        "description": "Send Slack notification for all events",
        "type": "shell",
        "command": "curl",
        "args": ["-X", "POST", "https://api.slack.com/webhook", "-d", "{\"text\":\"{{event}} in {{repo}} by {{pusher}}\"}"],
        "cwd": null,
        "timeout": 30000,
        "filterBranch": null
      }
    ]
  }
}

Example 3: Run tests on pull request with Node.js

.env:

WEBHOOK_PULL_REQUEST_ENABLED=true

commands.json:

{
  "commands": {
    "pull_request": [
      {
        "name": "run-tests",
        "description": "Run automated tests on pull request",
        "type": "node",
        "command": "./scripts/run-tests.js",
        "args": ["--repo", "{{repo}}", "--pr", "{{pr_number}}", "--author", "{{pusher}}"],
        "cwd": "/home/ci",
        "timeout": 900000,
        "filterBranch": null
      }
    ]
  }
}

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
│   ├── jobQueue.js        # Persistent job queue with FIFO processing
│   ├── commandExecutor.js # Command execution with variable substitution
│   ├── emailNotifier.js   # Email notification callback module
│   ├── emailSender.js     # SMTP email sender (zero dependencies)
│   ├── config.js          # Configuration loader (.env and commands.json)
│   └── logger.js          # Logging utility
├── client/                # TypeScript-based Claude Agent SDK client
│   ├── src/
│   │   ├── index.ts              # CLI entry point
│   │   ├── claude-client.ts      # Main Claude Agent SDK client
│   │   ├── config.ts             # Configuration management
│   │   ├── mcpConfigManager.ts   # MCP configuration manager
│   │   └── types.ts              # TypeScript type definitions
│   └── dist/              # Compiled JavaScript (auto-generated)
├── scripts/               # Utility scripts
├── examples/
│   ├── with-callbacks.js         # Example with custom callbacks
│   ├── mcp-config-default.json   # Example default MCP config
│   ├── mcp-config-multi-server.json  # Example multi-server MCP config
│   └── MCP-CONFIG.md             # MCP configuration guide
├── .env.example                  # Example environment configuration
├── commands.json.example         # Example command configuration
├── .smtp-config.json.example     # Example SMTP configuration
├── email-rules.json.example      # Example email notification rules
├── .env                          # Your environment configuration (not in git)
├── commands.json                 # Your command configuration (not in git)
├── .smtp-config.json             # Your SMTP configuration (not in git)
├── email-rules.json              # Your email notification rules (not in git)
├── queue.json                    # Queue state (auto-generated, gitignored)
├── 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

JobQueue (src/jobQueue.js)

  • Manages persistent job queue with FIFO processing
  • Ensures only one job executes at a time
  • Persists queue state to queue.json
  • Handles crash recovery and job resumption
  • Provides queue statistics and status

CommandExecutor (src/commandExecutor.js)

  • Executes shell and Node.js commands on webhook events
  • Performs variable substitution in commands and arguments
  • Supports both shell scripts and Node.js scripts
  • Handles command timeouts and errors
  • Extracts webhook payload data

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 and commands.json
  • Provides configuration access methods
  • Merges environment variables with file config
  • Supports backward compatibility with legacy .env commands

TypeScript Client for Issue Automation

The client/ directory contains a TypeScript-based Claude Agent SDK client for AI-powered issue automation.

Features

  • AI-Powered Issue Processing: Automatically processes Gogs issues assigned to Claude
  • MCP Server Integration: Connects to MCP servers for external API access
  • Per-Repository Configuration: Different repositories can use different MCP servers
  • Environment Variable Substitution: Support for secrets using ${VAR_NAME} syntax
  • Secure Configuration Storage: MCP configs stored outside repositories with restricted permissions

Quick Start

cd client
npm install
npm run build

MCP Configuration

The client supports three levels of MCP server configuration:

  1. Repository-specific: ~/.config/agent-manager/mcp/{owner}/{repo}.json
  2. Global default: ~/.config/agent-manager/mcp/default.json
  3. Hardcoded fallback: Built-in gogs-mcp (automatic)

Example MCP Configuration:

{
  "mcpServers": {
    "gogs": {
      "type": "stdio",
      "command": "node",
      "args": ["/data/gogs-mcp/dist/index.js"],
      "env": {}
    },
    "database": {
      "type": "stdio",
      "command": "node",
      "args": ["/path/to/db-mcp/dist/index.js"],
      "env": {
        "DB_HOST": "${DB_HOST}",
        "DB_PASSWORD": "${DB_PASSWORD}"
      }
    }
  }
}

Key Features:

  • Multiple MCP servers per repository
  • Environment variable substitution for secrets
  • Secure storage with 600 file permissions
  • Backward compatible with existing setup

For detailed MCP configuration guide, see examples/MCP-CONFIG.md.

Usage

The TypeScript client is automatically invoked by the webhook server when issues are assigned to Claude. It can also be run manually:

node client/dist/index.js <owner> <repo> <pusher> <issue_number> <issue_title> <issue_body> <issue_action> [comment_body] [assignee]

See client/README.md for more details.

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