docs: expand README with setup, configuration and operations
This commit is contained in:
committed by
latypov
parent
4e7b8e3e48
commit
8522a2d0a8
@@ -1,22 +1,26 @@
|
||||
# GitHub Release Monitor
|
||||
|
||||
Bash monitor for GitHub releases, with Telegram notifications and SOCKS5 proxy support.
|
||||
Lightweight Bash monitor that checks GitHub Releases and sends notifications to Telegram through a SOCKS5 proxy. Designed for unattended daily execution with cron. No Python or Docker required.
|
||||
|
||||
The default repository list tracks **Lychee**, **Firefly III**, and **Memos**.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Bash 4+
|
||||
- curl with SOCKS5 support
|
||||
- jq
|
||||
- flock (util-linux)
|
||||
- mktemp (coreutils)
|
||||
- Bash 4+ (Linux)
|
||||
- `curl` with SOCKS5 support
|
||||
- `jq`
|
||||
- `flock` (util-linux)
|
||||
- `mktemp` (coreutils)
|
||||
- `hostname`, `date`, `awk`, `sed`, `sort`, `tail`
|
||||
|
||||
Debian:
|
||||
On Debian 12/13:
|
||||
|
||||
```bash
|
||||
sudo apt-get install curl jq ca-certificates util-linux
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y bash curl jq ca-certificates util-linux coreutils
|
||||
```
|
||||
|
||||
## Setup
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
@@ -24,53 +28,110 @@ chmod 600 .env
|
||||
chmod +x monitor.sh
|
||||
```
|
||||
|
||||
Set `TELEGRAM_BOT_TOKEN` and `TELEGRAM_CHAT_ID` in `.env`. `GITHUB_TOKEN` is optional for public repositories. `SOCKS5_PROXY` can be set to `socks5h://127.0.0.1:1080`; `socks5h` resolves DNS through the proxy. The `.env` file is sourced as Bash: use only trusted local configuration.
|
||||
Edit `.env` and supply `TELEGRAM_BOT_TOKEN` and `TELEGRAM_CHAT_ID`. Create a bot with BotFather and send it a message first; the chat ID can then be obtained through Telegram Bot API `getUpdates`. A bot must have access to the destination chat.
|
||||
|
||||
Edit `repos.json` to select GitHub repositories. Initial test set: Lychee, Firefly III and Memos.
|
||||
The script **sources `.env` as Bash code**. Only use a trusted, locally maintained file. Do not commit it.
|
||||
|
||||
## Configuration
|
||||
|
||||
All settings from `.env.example`:
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
| --- | --- | --- |
|
||||
| `TELEGRAM_BOT_TOKEN` | empty | Telegram bot token; required for sending |
|
||||
| `TELEGRAM_CHAT_ID` | empty | Target user/group/channel ID |
|
||||
| `GITHUB_TOKEN` | empty | Optional GitHub API token; recommended to avoid low anonymous rate limits |
|
||||
| `SOCKS5_PROXY` | `socks5h://127.0.0.1:1080` | Proxy for both GitHub and Telegram; use `socks5h` for proxy-side DNS |
|
||||
| `REQUEST_TIMEOUT` | `30` | Maximum time in seconds per HTTP request |
|
||||
| `GITHUB_PER_PAGE` | `100` | Releases per API page, range 1–100 |
|
||||
| `GITHUB_MAX_PAGES` | `3` | Maximum pages fetched per repository |
|
||||
| `REPOS_FILE` | `repos.json` | Repository configuration path |
|
||||
| `STATE_FILE` | `state.json` | Persisted release IDs |
|
||||
| `INCLUDE_PRERELEASES` | `false` | Include GitHub prereleases |
|
||||
| `TELEGRAM_INCLUDE_CHANGELOG` | `true` | Include shortened release notes |
|
||||
| `TELEGRAM_CHANGELOG_MAX_LENGTH` | `1800` | Maximum release-note characters in each message |
|
||||
| `STATE_MAX_IDS` | `500` | Maximum stored release IDs per repository |
|
||||
|
||||
`REPOS_FILE` and `STATE_FILE` are resolved relative to the script directory unless absolute paths are specified. The default `.env` is loaded from that directory; set `ENV_FILE` to select another configuration file.
|
||||
|
||||
For authenticated GitHub requests, use a token with access to the repositories you want to monitor. For public repositories, authentication is optional. GitHub's unauthenticated REST API rate limit is normally 60 requests/hour per originating IP; authenticated requests generally have a larger allowance.
|
||||
|
||||
## Repositories
|
||||
|
||||
`repos.json` contains GitHub `owner/repo` names:
|
||||
|
||||
```json
|
||||
{
|
||||
"repositories": [
|
||||
"LycheeOrg/Lychee",
|
||||
"firefly-iii/firefly-iii",
|
||||
"usememos/memos"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Legacy URLs such as `https://github.com/usememos/memos` or `https://www.github.com/usememos/memos.git` are accepted, but `owner/repo` is preferred. The script monitors **GitHub Releases**, not Git tags that have no release object.
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | Behavior |
|
||||
| --- | --- |
|
||||
| `./monitor.sh --test-telegram` | Send one test message, without GitHub requests or reading/writing `repos.json`/`state.json` |
|
||||
| `./monitor.sh --dry-run --verbose` | Fetch releases, show pending messages and diagnostics, without Telegram delivery or state changes |
|
||||
| `./monitor.sh --init` | Replace baseline for all configured repositories; do not notify |
|
||||
| `./monitor.sh` | Normal monitoring: notify for new releases and save successful deliveries |
|
||||
| `./monitor.sh --include-prereleases` | Include prereleases for this run |
|
||||
| `./monitor.sh --help` | Show command-line help |
|
||||
|
||||
Recommended first run:
|
||||
|
||||
```bash
|
||||
./monitor.sh --test-telegram
|
||||
./monitor.sh --dry-run --verbose
|
||||
./monitor.sh --init
|
||||
./monitor.sh
|
||||
./monitor.sh --include-prereleases
|
||||
```
|
||||
|
||||
`--test-telegram` sends one Telegram test message without querying GitHub or accessing `state.json`/`repos.json`.
|
||||
**First-run behavior:** if a repository has no entry in `state.json`, its current releases are recorded as a baseline without notifications. `--init` **replaces** existing baselines, so avoid using it as a routine daily command. A dry run with no baseline prints the currently fetched tags; it does not send them.
|
||||
|
||||
`--init` records current releases without notifications; it **replaces** existing baselines. Use only for first initialization or an intentional reset. Normal first run also initializes missing repositories silently.
|
||||
`--test-telegram` uses the configured proxy and sends a sample changelog if changelogs are enabled. It does not verify GitHub connectivity. `--dry-run` does not send any Telegram message.
|
||||
|
||||
`--dry-run` queries GitHub and displays pending notifications without sending or changing state. On a repository without baseline it prints its current release tags.
|
||||
|
||||
`--include-prereleases` overrides `INCLUDE_PRERELEASES=false`. To track prereleases continuously, set `INCLUDE_PRERELEASES=true` in `.env`.
|
||||
|
||||
State is written atomically after each successful Telegram notification. If Telegram accepted a message but its response was lost, a duplicate may be sent next time. The state contains release IDs and grows over time. A bounded GitHub pagination window (`GITHUB_PER_PAGE * GITHUB_MAX_PAGES`) may miss releases if more are published between checks. For small projects and daily checks this is generally sufficient.
|
||||
To track prereleases every day, set `INCLUDE_PRERELEASES=true` in `.env` instead of enabling them for occasional runs.
|
||||
|
||||
## Daily cron
|
||||
|
||||
At 09:00 server-local time:
|
||||
Run once daily at 09:00 in the server's local timezone:
|
||||
|
||||
```cron
|
||||
0 9 * * * cd /opt/github-release-monitor && ./monitor.sh >> monitor.log 2>&1
|
||||
```
|
||||
|
||||
Run the monitor under a dedicated user where possible. Keep `.env` private and do not commit it. Use `./monitor.sh --test-telegram` to verify Telegram and proxy connectivity.
|
||||
Use `crontab -e` for the account running the monitor. Change `/opt/github-release-monitor` to your actual installation directory. Keep `monitor.log` under log rotation if it grows; cron output redirection does not rotate logs.
|
||||
|
||||
### Large release histories
|
||||
For troubleshooting:
|
||||
|
||||
GitHub response pages are processed through temporary files, rather than passed
|
||||
through command-line arguments. The state file is read directly by `jq`.
|
||||
This prevents `Argument list too long` for repositories with large release notes.
|
||||
```bash
|
||||
bash -n monitor.sh
|
||||
./monitor.sh --dry-run --verbose
|
||||
```
|
||||
|
||||
Run `bash -n monitor.sh` and `./monitor.sh --dry-run --verbose` to verify.
|
||||
## State, ordering, and reliability
|
||||
|
||||
### Release notes and retention
|
||||
- `state.json` records notified release IDs separately for each repository; it is created automatically.
|
||||
- After successful Telegram delivery, the corresponding release ID is written atomically to state.
|
||||
- Release notifications are processed oldest-first within the fetched API window.
|
||||
- `flock -n` prevents overlapping runs; a second invocation exits immediately while another holds the lock.
|
||||
- If any page of a repository's GitHub response fails, that repository is not processed from a partial response. Other repositories continue; the run exits nonzero if any repository failed.
|
||||
- GitHub HTTP failures log status and available `X-RateLimit-Remaining`, `X-RateLimit-Reset`, and `Retry-After` headers. The script does not sleep until rate-limit reset.
|
||||
- The Telegram message contains repository, version, name, publication date, release URL, and optionally a truncated changelog. The message is limited to 4096 Unicode characters.
|
||||
- GitHub API response pages are processed using temporary files rather than passing large JSON values through process arguments, avoiding `Argument list too long` on long release histories.
|
||||
|
||||
`repos.json` uses `owner/repo` names (legacy full GitHub URLs remain accepted).
|
||||
`TELEGRAM_INCLUDE_CHANGELOG=true` includes a shortened release body in Telegram messages.
|
||||
`TELEGRAM_CHANGELOG_MAX_LENGTH=1800` limits the changelog; Telegram messages are capped at 4096 characters.
|
||||
`STATE_MAX_IDS=500` bounds stored release IDs per repository. Keep this larger than the number of releases that may appear in the fetched pages; old releases returning after pruning may otherwise be notified again.
|
||||
**Retention caveat:** `STATE_MAX_IDS` keeps a bounded set of IDs. Pruned IDs may be treated as new if their releases reappear within the fetched API pages. The fetched window is limited to `GITHUB_PER_PAGE * GITHUB_MAX_PAGES` releases per repository; releases outside it can be missed. Set retention and pagination limits with these trade-offs in mind. The script does not track edited releases or tag-only versions.
|
||||
|
||||
GitHub HTTP 403/429 responses log rate-limit headers and fail without changing the repository state. Mid-pagination errors also fail the repository without partially processing it. Tags without GitHub releases are not tracked.
|
||||
**Delivery caveat:** Telegram does not provide idempotency for `sendMessage`. If it accepted a message but the HTTP response was lost, the next run may resend it. Telegram POST requests are not automatically retried by this script.
|
||||
|
||||
## Security and files
|
||||
|
||||
Keep `.env` private (`chmod 600 .env`). Do not commit `.env`, `state.json`, lock files, or logs; these are excluded by `.gitignore`. The monitor is intended to run as an unprivileged account.
|
||||
|
||||
For a clean installation, copy the tracked project files and configure `.env` locally. Back up `state.json` if migrating an existing installation to avoid reinitializing baselines.
|
||||
|
||||
Reference in New Issue
Block a user