ARIA 7aeecc1e15 Fix: Add setuptools package discovery config
The src package was not being installed, causing ModuleNotFoundError
when running ghrel command from outside the project directory.
2026-07-28 12:07:38 +02:00

GitHub Release Monitor

A CLI tool that tracks GitHub releases or tags from user-defined repositories and exposes them as a subscribable RSS feed.

Some repositories (e.g., Zammad) only use git tags without creating GitHub releases — both modes are supported.

Features

  • Track releases or tags per repository
  • SQLite storage with automatic deduplication
  • RSS 2.0 feed with markdown-stripped release notes
  • Built-in HTTP server for local feed access
  • Rate-limit-aware GitHub API client
  • Configurable via environment variables and CLI flags
  • Daemon mode for automatic background checks

Installation

pip install .

Or install in development mode:

pip install -e .

Quick Start

# Set your GitHub token (optional, increases rate limit from 60/h to 5000/h)
export GH_TOKEN=your_token

# Add repositories to track
ghrel add golang/go              # Track releases (default)
ghrel add zammad/zammad --tags   # Track tags

# Fetch latest releases/tags
ghrel check

# List tracked repositories
ghrel list

# Start the RSS feed server
ghrel serve

The RSS feed is available at http://127.0.0.1:8080/feed.xml.

CLI Commands

ghrel                          # Main command
├── --version                  # Show version
├── --verbose / -v             # Enable verbose/debug output
├── --quiet / -q               # Suppress non-essential output
├── --db-path <path>           # Override database path
├── add <owner/repo> [--tags]  # Add a repository to track
├── remove <owner/repo>        # Remove a repository
├── update <owner/repo> [--tags] [--release]  # Update tracking mode
├── list                       # List all tracked repositories
├── check [--since N]          # Fetch latest releases/tags
├── daemon [--interval 30m]    # Run as background daemon
└── serve [--port 8080] [--host 127.0.0.1]  # Start HTTP server

add <owner/repo> [--tags]

Add a repository to track. Validates the format and pings the GitHub API to verify the repository exists.

ghrel add golang/go              # Track releases
ghrel add zammad/zammad --tags   # Track tags

remove <owner/repo>

Remove a repository and its associated entries.

ghrel remove golang/go

update <owner/repo> [--tags] [--release]

Update the tracking mode for an existing repository.

ghrel update zammad/zammad --tags
ghrel update zammad/zammad --release

list

Display tracked repositories with entry counts and last check time.

REPO            MODE      ENTRIES  LAST CHECKED
golang/go       release   12       2025-01-15 10:30
zammad/zammad   tag       8        2025-01-15 10:30

check [--since N]

Fetch latest releases or tags for all tracked repositories. With --since, only fetch entries published in the last N hours (e.g., --since 24h).

ghrel check           # Fetch all new entries
ghrel check --since 24h  # Only entries from the last 24 hours

serve [--port PORT] [--host HOST]

Start the HTTP server.

ghrel serve                        # Default: 127.0.0.1:8080
ghrel serve --port 9090 --host 0.0.0.0  # Custom port and host

daemon [--interval INTERVAL] [--pid-file PATH] [--since N]

Run as a background daemon that periodically checks all tracked repositories for new releases or tags.

ghrel daemon                      # Default: 30m interval
ghrel daemon --interval 1h        # Check every hour
ghrel daemon --interval 15m       # Check every 15 minutes
ghrel daemon --pid-file /run/ghrel.pid  # Custom PID file
ghrel daemon --since 24h          # Only entries from last 24h

Interval format: N followed by s (seconds), m (minutes), h (hours), or d (days).

The daemon writes a PID file for status checking and sends structured logs to stderr (suitable for systemd journal). It handles SIGTERM and SIGINT for graceful shutdown.

Systemd Service

Create /etc/systemd/system/ghrel-daemon.service:

[Unit]
Description=GitHub Release Monitor Daemon
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/ghrel daemon --interval 30m --pid-file /run/ghrel.pid
Restart=on-failure
RestartSec=10
Environment=GH_TOKEN=your_token_here

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl daemon-reload
sudo systemctl enable --now ghrel-daemon
sudo systemctl status ghrel-daemon

View logs:

journalctl -u ghrel-daemon -f

## Configuration

| Setting       | Default                    | Override          |
|---------------|----------------------------|-------------------|
| `db_path`     | `~/.config/ghrel/repos.db` | `--db-path` flag  |
| `gh_token`    | `GH_TOKEN` env var         | —                 |
| `server_host` | `127.0.0.1`                | `--host` flag     |
| `server_port` | `8080`                     | `--port` flag     |

## RSS Feed

The feed follows RSS 2.0 specification:

- **Title**: `GitHub Release Monitor`
- **Items**: Sorted by `published_at` (newest first), capped at 50 items
- **Release entries**: Title from release name, description from markdown-stripped body (truncated at 300 characters)
- **Tag entries**: Title from tag name, description as `Tag {tag_name}`

## Architecture

┌──────────────────────────────────────────────────┐ │ CLI Interface │ │ (add, remove, update, list, check, serve) │ ├──────────────────────────────────────────────────┤ │ Core Logic │ │ ┌──────────────┐ ┌──────────────┐ ┌────────┐ │ │ │ config.py │ │ db.py │ │github.py│ │ │ │ (defaults, │ │ (sqlite3) │ │(httpx) │ │ │ │ env vars) │ │ │ │ │ │ │ └──────────────┘ └──────┬───────┘ └───┬────┘ │ │ │ │ │ │ ┌────────▼──────────────▼────┐ │ │ │ rss.py │ │ │ │ (xml.etree + markdown) │ │ │ └──────────────┬─────────────┘ │ │ │ │ │ ┌──────────────▼─────────────┐ │ │ │ server.py │ │ │ │ (http.server, stdlib) │ │ │ │ (/feed.xml endpoint) │ │ │ └─────────────────────────────┘ │ └──────────────────────────────────────────────────┘


## Testing

```bash
pytest

Dependencies

Package Purpose
httpx HTTP client for GitHub API
markdown Convert markdown to HTML
bleach Strip HTML tags for plain text
pytest Testing framework
respx Mocking HTTP requests for tests

No heavy frameworks. http.server and xml.etree.ElementTree are stdlib.

S
Description
CLI tool that tracks GitHub releases or tags from user-defined repositories and exposes them as a subscribable RSS feed
Readme
116 KiB
Languages
Python 100%