Skip to main content

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

  1. Go to https://smee.io/new.
  2. A unique channel URL is automatically generated (e.g. https://smee.io/AbCdEfGhIjKlMn).
  3. Copy this URL. Use the same value for the GitHub Webhook Payload URL and SMEE_URL in your .env.

Note: The git-catcher init command automatically opens Smee.io in your browser.

3. Add a GitHub Repository Webhook

  1. In your GitHub repository, go to SettingsWebhooksAdd webhook.
  2. 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
  1. 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 PermissionsContents: Set to Read-only or 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.

  1. On the created app page, click Install App.
  2. Select your account and choose All repositories.
  3. 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 fetchgit checkoutgit 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 init to auto-generate .env and docker-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/repo from REPO_PATH git remote origin URL when ALLOWED_REPOS is not set
  • Slack deploy notifications: Notifies a Slack channel on deploy success/failure when SLACK_WEBHOOK_URL is set
  • SSE reconnect recovery: Resumes from the last received event using Last-Event-ID on disconnection
  • Rich console logging: Readable colored output with timestamp (HH:MM:SS.ms) format

Verifying It Works

  1. Run Git Catcher:

    python run.py
    
  2. When you see the SSE stream connected log, the connection is established.

  3. If NOTIFY_ON_START=true, a startup notification is sent to Slack.

  4. Push a commit to an allowed branch:

    git add .
    git commit -m "test webhook"
    git push origin main
    
  5. Verify the following logs appear in order in the Git Catcher terminal:

    • Push detected: [main] test webhook
    • git fetchgit checkoutgit pull complete
    • POST_PULL_COMMAND executed (if configured)
    • Slack notification sent (if configured)

If something is wrong, check the Recent Deliveries tab on the GitHub Webhook page to inspect delivery status.

Tests

pytest tests/ -v

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

git_catcher-0.4.0.tar.gz (24.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

git_catcher-0.4.0-py3-none-any.whl (18.0 kB view details)

Uploaded Python 3

File details

Details for the file git_catcher-0.4.0.tar.gz.

File metadata

  • Download URL: git_catcher-0.4.0.tar.gz
  • Upload date:
  • Size: 24.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.8

File hashes

Hashes for git_catcher-0.4.0.tar.gz
Algorithm Hash digest
SHA256 d75846a8cac823e7ae4de6f97f08b1e77db7d2a9deb8f8b5d9403b3e1bbf55e9
MD5 7ae369c281b523d5c7c66f8834581abd
BLAKE2b-256 16cb9d3ac5ec4b7267fa25fd786c387e0e3bb84fe6e3a863ac35016d7f16850d

See more details on using hashes here.

File details

Details for the file git_catcher-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: git_catcher-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 18.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.8

File hashes

Hashes for git_catcher-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 aaa2f611187d4726a7f6de7e135e8adb026d2775ae572ad99ed4cb54607b5ee3
MD5 594dbb2d382883091b23995b8c6071a7
BLAKE2b-256 4ff0470e88fdfd366ca106e2caa62333f167d4de963dda2e9da9f3648f283584

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page