Smee.io-based GitHub push webhook auto-deploy CLI tool
Project description
Git Catcher
A Python CLI tool that receives GitHub push webhooks in real time via the Smee.io SSE proxy and automatically runs git pull and a custom deploy command for allowed branches.
Works behind firewalls/NAT, and supports automatic reconnection with exponential backoff on disconnection.
Installation
pip install -r git_catcher/requirements.txt
Dependencies
| Package | Purpose |
|---|---|
httpx |
SSE stream HTTP client |
rich |
Colored console logging |
python-dotenv |
Load environment variables from .env |
InquirerPy |
Interactive CLI prompts (init command) |
hypothesis |
Property-based testing (dev) |
pytest |
Test framework (dev) |
Quick Start
1. Interactive Setup (recommended)
python -m git_catcher.main init
Or using the shortcut:
python run.py init
Answer the interactive prompts to automatically generate a .env file and docker-compose.yml.
- Auto-generate Smee.io URL (opens browser)
- Randomly generate Webhook Secret
- Select repository path and allowed branches
- Configure Slack notifications
2. Manual Setup
Copy .env.example to create a .env file and fill in the values.
cp git_catcher/.env.example git_catcher/.env
| Variable | Default | Description |
|---|---|---|
SMEE_URL |
https://smee.io/YOUR_CHANNEL_ID |
Smee.io channel URL (create at smee.io/new) |
WEBHOOK_SECRET |
"" |
GitHub Webhook Secret (signature verification skipped if not set) |
REPO_PATH |
/path/to/your/repo |
Local path to the target Git repository |
ALLOWED_BRANCHES |
main,master |
Branches to deploy (comma-separated) |
POST_PULL_COMMAND |
"" |
Shell command to run after git pull |
RECONNECT_DELAY |
1 |
Initial reconnect wait time (seconds) |
MAX_RECONNECT_DELAY |
300 |
Maximum reconnect wait time (seconds) |
ALLOWED_REPOS |
"" |
Allowed repositories (owner/repo format, comma-separated). Auto-detected from REPO_PATH git remote origin if empty |
SLACK_WEBHOOK_URL |
"" |
Slack Incoming Webhook URL. Notifications skipped if empty |
NOTIFY_ON_START |
true |
Send Slack notification on startup (true/false) |
POLL_INTERVAL |
0 |
Git status polling interval (seconds; 0 disables) |
LOG_LEVEL |
INFO |
Log level (DEBUG, INFO, WARNING, ERROR) |
LOG_FILE |
"" |
Log file path (file logging disabled if empty) |
SHOW_ALL_EVENTS |
false |
Log all push events (true/false) |
2. Create a Smee.io Channel
- Go to https://smee.io/new.
- A unique channel URL is automatically generated (e.g.
https://smee.io/AbCdEfGhIjKlMn). - Copy this URL. Use the same value for the GitHub Webhook Payload URL and
SMEE_URLin your.env.
Note: The
git-catcher initcommand automatically opens Smee.io in your browser.
3. Add a GitHub Repository Webhook
- In your GitHub repository, go to Settings → Webhooks → Add webhook.
- Configure as follows:
| Field | Value |
|---|---|
| Payload URL | Smee.io channel URL (e.g. https://smee.io/AbCdEfGhIjKlMn) |
| Content type | application/json |
| Secret | Same value as WEBHOOK_SECRET in .env |
| Which events? | Select "Just the push event" |
| Active | Checked |
- Click Add webhook to save.
Note: Leaving the Secret blank also skips signature verification in Git Catcher. Setting a Secret is recommended for security.
3-1. Receive Webhooks for All Repositories via GitHub App (optional)
If you only need a single repository, use 3. Add a GitHub Repository Webhook above. To receive push webhooks from all repositories in your personal account (including future ones), create a GitHub App.
1) Create a GitHub App
Create an app at GitHub Settings → Developer settings → GitHub Apps → New GitHub App.
| Field | Value | Notes |
|---|---|---|
| App name | Any name | e.g. my-git-catcher |
| Homepage URL | https://github.com/your-account |
Required for app identification |
| Webhook URL | Smee.io channel URL | Destination to receive webhook data |
| Webhook Secret | Same value as WEBHOOK_SECRET in .env |
Shared key to prevent payload tampering between server and GitHub |
2) Permissions and Event Subscriptions
At the bottom of the creation form, configure:
- Repository Permissions → Contents: Set to
Read-onlyor higher (required to detect code changes) - Subscribe to events → Check Push (webhook fires only on code pushes)
3) Install the App on Your Account
This is the most important step. Creating the app alone is not enough — you must install it on your account.
- On the created app page, click Install App.
- Select your account and choose All repositories.
- Click Install.
Selecting All repositories automatically applies the webhook to all existing repositories and any created in the future.
4) Security and Verification
| Item | Description |
|---|---|
Private Key (.pem) |
Generate from the app settings page. Used for authentication when calling the GitHub API from your server |
| Recent Deliveries | View sent webhook payloads and test redelivery via Redeliver in the app settings → Advanced tab |
4. .env Example
SMEE_URL must match the channel URL from Smee.io, and WEBHOOK_SECRET must match the Secret entered in GitHub Webhook settings.
SMEE_URL=https://smee.io/AbCdEfGhIjKlMn
WEBHOOK_SECRET=your-webhook-secret-here
REPO_PATH=/path/to/your/repo
ALLOWED_BRANCHES=main,master
POST_PULL_COMMAND=
ALLOWED_REPOS=
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T.../B.../xxx
NOTIFY_ON_START=true
POLL_INTERVAL=0
LOG_LEVEL=INFO
LOG_FILE=
SHOW_ALL_EVENTS=false
See the environment variables table for details on each variable.
Running
Basic Usage
# Option 1: run as module
python -m git_catcher.main
# Option 2: shortcut (recommended)
python run.py
On startup, git-catcher connects to the Smee.io SSE stream and waits for GitHub push events. When a push is detected on an allowed branch, it automatically runs git fetch → git checkout → git pull → post-pull command in sequence.
Startup Notification
When NOTIFY_ON_START=true, git-catcher sends a Slack notification on startup containing:
- Repository name
- Allowed branch list
- Hostname
- External IP address
- Start time (UTC)
CLI Commands
| Command | Description |
|---|---|
git-catcher init |
Interactive setup (generates .env and docker-compose.yml) |
git-catcher run |
Run git-catcher (default behavior) |
CLI Options (run command)
| Option | Description |
|---|---|
-v |
DEBUG logging for git_catcher module only |
-vv |
DEBUG logging for all modules |
-vvvv |
Also print raw webhook payloads |
--show-all-events |
Log all push events (deployment filtering still applies) |
--log-file PATH |
Log file path (also writes DEBUG logs to file when set) |
--log-level LEVEL |
Log level (DEBUG, INFO, WARNING, ERROR) |
# Basic run
python run.py
# git_catcher module DEBUG + write to log file
python run.py -v --log-file deploy.log
# Show all push events + full DEBUG
python run.py -vv --show-all-events
# Interactive setup
python run.py init
Key Features
- Interactive setup: Answer prompts with
git-catcher initto auto-generate.envanddocker-compose.yml - Quick start: Run with
python run.py - Startup notification: Sends a Slack notification on start when
NOTIFY_ON_START=true(includes repo, branches, host, IP) - Auto repo detection: Extracts
owner/repofromREPO_PATHgit remote origin URL whenALLOWED_REPOSis not set - Slack deploy notifications: Notifies a Slack channel on deploy success/failure when
SLACK_WEBHOOK_URLis set - SSE reconnect recovery: Resumes from the last received event using
Last-Event-IDon disconnection - Rich console logging: Readable colored output with timestamp (HH:MM:SS.ms) format
Verifying It Works
-
Run Git Catcher:
python run.py -
When you see the
SSE stream connectedlog, the connection is established. -
If
NOTIFY_ON_START=true, a startup notification is sent to Slack. -
Push a commit to an allowed branch:
git add . git commit -m "test webhook" git push origin main
-
Verify the following logs appear in order in the Git Catcher terminal:
- Push detected:
[main] test webhook git fetch→git checkout→git pullcompletePOST_PULL_COMMANDexecuted (if configured)- Slack notification sent (if configured)
- Push detected:
If something is wrong, check the Recent Deliveries tab on the GitHub Webhook page to inspect delivery status.
Tests
pytest tests/ -v
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file git_catcher-0.14.0.tar.gz.
File metadata
- Download URL: git_catcher-0.14.0.tar.gz
- Upload date:
- Size: 25.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8b8d29789ad6dd41799087865016454fdd188c6f696d3acdd8427ff7d92d7ff1
|
|
| MD5 |
fe43a8e4ae788134479c86c6617f2bac
|
|
| BLAKE2b-256 |
f13e6868858f58b3ab31ca80af2f25fe0a868fbea38161b2b8cb18b1bd43093b
|
File details
Details for the file git_catcher-0.14.0-py3-none-any.whl.
File metadata
- Download URL: git_catcher-0.14.0-py3-none-any.whl
- Upload date:
- Size: 19.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8dc12df3405f722f17f7b83962eb3de946602f776a3b608af1beaf5ca91de4a9
|
|
| MD5 |
ff12a672edba196742240d98ec82cf95
|
|
| BLAKE2b-256 |
6c5c4fe8eec4e75ca29677b55e5f8efb00b24bd9b138b1220bff781c4165f9b3
|