Simple Git Webhooks Server
Table of Contents
Introduction
A lightweight Git webhook server for automated deployment.
- Implemented with Python 3.6+ (standard library only)
- Supports Github, Gitee, Gitlab, and custom repositories
- Custom working directory and command for different repositories
- Installable as a Systemd service
- Modular architecture for easy extension and testing
Architecture
Version 2.0 features a modular package structure:
gitwebhooks/
├── models/ # Data models (Provider, Request, Result)
├── config/ # Configuration management
├── auth/ # Signature verification
├── handlers/ # Webhook handlers
├── utils/ # Utilities
└── logging/ # Logging setup
Key Features:
- Dependency Injection: ConfigurationRegistry, VerifierFactory, HandlerFactory
- Abstract Base Classes: SignatureVerifier, WebhookHandler
- No External Dependencies: 100% Python standard library
- In-Place Execution: CLI runs from source directory
Installation
Prerequisites
- Python 3.6 or higher
- pip (Python package manager)
- sudo/root access (for systemd service installation)
Recommended: pipx (System-wide installation)
pipx is the recommended way to install gitwebhooks system-wide.
# Install pipx (if not already installed)
sudo apt install pipx # Ubuntu/Debian
# or: python3 -m pip install --user pipx
# Install gitwebhooks
pipx install gitwebhooks
Why pipx?
- Isolated from system Python packages
- No dependency conflicts
- Easy to upgrade and uninstall
- Automatic service file configuration
Alternative: venv (Virtual environment)
If you prefer using Python's built-in venv module:
# Create virtual environment
python3 -m venv ~/venv/gitwebhooks
# Activate and install
source ~/venv/gitwebhooks/bin/activate
pip install gitwebhooks
# Add to PATH (optional)
echo 'export PATH="$HOME/venv/gitwebhooks/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
⚠️ NOT Recommended: System pip
Warning: Installing directly with sudo pip install is NOT recommended:
# DO NOT DO THIS
sudo pip install gitwebhooks
Risks:
- Can conflict with system Python packages
- May break system tools that depend on Python
- Difficult to uninstall cleanly
Initialize Configuration
# Interactive configuration setup (prompts for configuration level)
gitwebhooks-cli config init
# Or specify configuration level directly
gitwebhooks-cli config init user # User level (~/.gitwebhooks.ini)
gitwebhooks-cli config init local # Local level (/usr/local/etc/gitwebhooks.ini)
sudo gitwebhooks-cli config init system # System level (/etc/gitwebhooks.ini, requires root)
The wizard will prompt for:
- Configuration level (system/local/user)
- Server configuration (address, port, log file)
- Git platform (github/gitee/gitlab/custom)
- Platform-specific settings (webhook events, verification, secret)
- Repository configuration (name, working directory, deploy command)
This will create a configuration file with secure permissions (0600).
Install as systemd Service
The service installation command automatically detects your installation type (pipx, venv, or system) and generates the appropriate service file.
# Install and start as a systemd service (interactive config level selection)
sudo gitwebhooks-cli serve install
# Install with specific config level (skip interactive selection)
sudo gitwebhooks-cli serve install --config-level user # User level (~/.gitwebhooks.ini)
sudo gitwebhooks-cli serve install --config-level local # Local level (/usr/local/etc/gitwebhooks.ini)
sudo gitwebhooks-cli serve install --config-level system # System level (/etc/gitwebhooks.ini)
# Use custom config file (backward compatibility)
sudo gitwebhooks-cli serve install -c /path/to/config.ini
# Preview service file without installing (dry-run mode)
sudo gitwebhooks-cli serve install --dry-run
sudo gitwebhooks-cli serve install --config-level local --dry-run # Preview specific level
# Install with verbose output
sudo gitwebhooks-cli serve install --verbose
# Force overwrite existing service
sudo gitwebhooks-cli serve install --force
# Uninstall the service
sudo gitwebhooks-cli serve uninstall
Configuration levels:
- user:
~/.gitwebhooks.ini- Single user configuration, highest priority - local:
/usr/local/etc/gitwebhooks.ini- Local system configuration, medium priority - system:
/etc/gitwebhooks.ini- Global system configuration, lowest priority
Service file auto-detection:
- pipx installation: Uses
gitwebhooks-clicommand directly - venv/virtualenv: Uses
python -m gitwebhooks.mainwith environment's Python - System pip: Uses system Python with
python -m gitwebhooks.main - conda: Not supported - installation will be refused with clear error message
Manual Installation
To install manually without pip:
# Make CLI executable
chmod +x gitwebhooks-cli
# Create hard link to system path
sudo ln "$(pwd)/gitwebhooks-cli" /usr/local/bin/gitwebhooks-cli
Verify Installation
# Show version
gitwebhooks-cli -v
# Show help (also: gitwebhooks-cli --help)
gitwebhooks-cli help
# View configuration
gitwebhooks-cli config view
Migrating from System pip Installation
If you previously installed gitwebhooks using sudo pip install,
follow these steps to migrate to a recommended installation method.
Step 1: Uninstall the old installation
sudo pip uninstall gitwebhooks
Step 2: Backup your configuration (if exists)
cp ~/.gitwebhook.ini ~/.gitwebhook.ini.backup
Step 3: Stop and uninstall the service (if installed)
sudo systemctl stop gitwebhooks
sudo systemctl disable gitwebhooks
sudo gitwebhooks-cli serve uninstall
Step 4: Install using the recommended method
Choose pipx (recommended):
# Install pipx if needed
sudo apt install pipx # Ubuntu/Debian
# or: python3 -m pip install --user pipx
# Install gitwebhooks
pipx install gitwebhooks
Or venv:
# Create virtual environment
python3 -m venv ~/venv/gitwebhooks
source ~/venv/gitwebhooks/bin/activate
# Install gitwebhooks
pip install gitwebhooks
Step 5: Restore configuration (if backed up)
# If you backed up your configuration
cp ~/.gitwebhook.ini.backup ~/.gitwebhook.ini
# Or create a new one
gitwebhooks-cli config init
Step 6: Reinstall the service
sudo gitwebhooks-cli serve install
Step 7: Verify
sudo systemctl status gitwebhooks
Uninstallation
# Uninstall systemd service (if installed)
sudo gitwebhooks-cli serve uninstall --purge
# Remove the package
pip uninstall gitwebhooks
Usage
Configuration File Auto-Discovery
The gitwebhooks-cli automatically searches for configuration files in the following order (priority):
- User level:
~/.gitwebhooks.ini(highest priority) - Local level:
/usr/local/etc/gitwebhooks.ini - System level:
/etc/gitwebhooks.ini(lowest priority)
You can run gitwebhooks-cli serve without specifying -c parameter, and it will automatically use the first existing configuration file.
# Auto-discover and use configuration file
gitwebhooks-cli serve
# The server will display which config file is being used
# Using configuration file: /home/user/.gitwebhooks.ini
If you want to use a specific configuration file, use the -c parameter:
# Use a specific configuration file
gitwebhooks-cli serve -c /path/to/custom.ini
If no configuration file is found, a friendly error message will display all searched paths:
Error: Configuration file not found.
Searched paths:
1. /home/user/.gitwebhooks.ini
2. /usr/local/etc/gitwebhooks.ini
3. /etc/gitwebhooks.ini
You can create a configuration file using:
gitwebhooks-cli config init
1. Configure Repository
Edit your configuration file (e.g., ~/.gitwebhooks.ini):
[your_name/repository]
cwd=/path/to/your/repository
cmd=git fetch --all && git reset --hard origin/master && git pull
2. Restart Service
# If running as a service
systemctl restart gitwebhooks
# Or run directly (auto-discovers config file):
gitwebhooks-cli serve
3. Add Webhook
Github
Gitee
Gitlab
Custom
For custom webhook sources, configure like this:
[custom]
# Header to identify the source
header_name=X-Custom-Header
header_value=Custom-Git-Hookshot
# Header for token verification
header_token=X-Custom-Token
# Path to repository name in JSON payload
identifier_path=project.path_with_namespace
verify=True
secret=123456
The handler accepts POST data with application/json or application/x-www-form-urlencoded content type. See Github / Gitee / Gitlab for payload examples.
Example payload:
{
"project": {
"path_with_namespace": "your_name/repository"
}
}
Configuration
Default configuration file: ~/.gitwebhook.ini
Initialize Configuration
# Interactive configuration setup
gitwebhooks-cli config init
# Or specify configuration level directly
gitwebhooks-cli config init user
sudo gitwebhooks-cli config init system
View Configuration
# View current configuration file (auto-detects location)
gitwebhooks-cli config view
# View specific configuration file
gitwebhooks-cli config view -c /path/to/config.ini
The config view command displays:
- Configuration file path and source (user-specified or auto-detected)
- Configuration content organized by sections
- Sensitive fields (containing: secret, password, token, key, passphrase) highlighted in yellow
To disable color highlighting:
NO_COLOR=1 gitwebhooks-cli config view
Server Configuration
[server]
address=0.0.0.0 # Listen address
port=6789 # Listen port
log_file=~/.gitwebhook.log # Log file (empty = stdout only)
SSL Configuration (Optional)
[ssl]
enable=False
key_file=/path/to/key.pem
cert_file=/path/to/cert.pem
Provider Configuration
[github]
verify=True # Enable signature verification
secret=your_webhook_secret
handle_events=push,pull_request # Events to handle (empty = all)
[gitee]
verify=True
secret=your_webhook_secret
[gitlab]
verify=True
secret=your_webhook_token
[custom]
header_name=X-Custom-Header
header_value=Your-Identifier
header_token=X-Custom-Token
identifier_path=project.path_with_namespace
verify=True
secret=your_secret
Repository Configuration
[owner/repository]
cwd=/path/to/repo # Working directory
cmd=your_command # Command to execute
Project Structure
gitwebhooks/
├── gitwebhooks/ # Python package (modular)
│ ├── main/ # CLI entry point (python3 -m gitwebhooks.main)
│ ├── cli/ # Subcommands (serve / config / help)
│ ├── server.py # HTTP server
│ ├── models/ # Data models
│ ├── config/ # Configuration management
│ ├── auth/ # Signature verification
│ ├── handlers/ # Webhook handlers
│ ├── utils/ # Utilities
│ └── logging/ # Logging setup
├── gitwebhooks-cli # CLI wrapper script
├── gitwebhooks.ini.sample # Configuration template
├── scripts/ # pre-release-check.sh
├── tests/ # Test suite
├── CONSTITUTION.md # Coding charter (highest authority)
└── AGENTS.md # Agent guide (full file tree)
The authoritative, complete file tree lives in
AGENTS.md; this is a summary.
Development
Running from Source
# Method 1: Use CLI tool (recommended)
./gitwebhooks-cli serve -c gitwebhooks.ini.sample
# Method 2: Use module entry
python3 -m gitwebhooks.main serve -c gitwebhooks.ini.sample
Running Tests
# Using pytest
python3 -m pytest tests/
# Or using unittest
python3 -m unittest discover tests/
Releasing to PyPI
IMPORTANT: Before releasing to PyPI, you MUST run the pre-release validation script:
./scripts/pre-release-check.sh
This script validates:
- Package builds successfully
- CLI entry point works (
gitwebhooks-cli) - All subcommands work (
service,config) - Module imports work correctly
Only after all checks pass, proceed with publishing:
# Build the package
python3 -m build
# Upload to PyPI
python3 -m twine upload dist/*
License
MIT License
Metadata
Release files for gitwebhooks 2.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| gitwebhooks-2.4.1.tar.gz | 811.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gitwebhooks-2.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 871.6 kB
Release files / gitwebhooks-2.4.1.tar.gz
| Download URL | gitwebhooks-2.4.1.tar.gz |
|---|---|
| Size | 811.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9356dfaee5144142dcd6adef1da78ccbcf03502e9637292b23eed75123035d79
|
|
BLAKE2b-256 checksum How to use checksums |
ca47127c1d9d84e20fcc99a945da1db9b64be3ed60d2f39d9444faf1b9326633
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.8
|
Release files / gitwebhooks-2.4.1-py3-none-any.whl
| Download URL | gitwebhooks-2.4.1-py3-none-any.whl |
|---|---|
| Size | 60.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
132a72aeb9a976e7f50166ce4f8d575d447fb0c6af055398b39b8542c5c1f7f7
|
|
BLAKE2b-256 checksum How to use checksums |
af92d4743fb8308f931ef6db3b9c7bef516107ed6454e1e68a9c3533e4216f6f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.8
|