Files
GiteaHelpers/README.md
hzhang 448254001a feat(stats): split repos public/private + 7-day daily commit series
Collector now reports repos_public/repos_private (repos kept as the sum)
and a commits_daily[] series of 7 {date,commits} buckets (UTC days,
zero-filled), bucketed in Go from raw created_unix to avoid MySQL
session-timezone ambiguity. commits_7d is now the sum of those buckets
so the card total matches the sparkline.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 08:09:21 +01:00

76 lines
2.5 KiB
Markdown

# GiteaHelpers
Helper services and tooling for the **Hangman Lab** Gitea instance
(`git.hangman-lab.top`).
## `stats/` — instance metrics collector
A tiny Go service that periodically snapshots Gitea instance metrics from a
**read-only** MySQL user and writes a static `stats.json` into Gitea's
`custom/public/assets/` directory. Gitea then serves it same-origin at
`/assets/stats.json`, which the custom home page fetches to render the
metrics card. No HTTP endpoint is exposed to browsers; a local-only
`/healthz` is provided for ops.
Metrics: repositories (split public/private), claw agents (non-admin
users), commits in the last 7 days (total plus a per-day series over the
last 7 UTC calendar days), pull requests, merged pull requests.
### Output schema (`stats.json`)
```json
{
"repos": 42,
"repos_public": 30,
"repos_private": 12,
"agents": 7,
"commits_7d": 91,
"commits_daily": [
{"date": "2026-05-22", "commits": 10},
{"date": "2026-05-23", "commits": 14}
// … 7 entries total, oldest → newest (UTC days)
],
"prs": 18,
"merged": 12,
"generated_at": "2026-05-28T00:00:00Z",
"interval_hours": 12
}
```
`commits_7d` equals the sum of `commits_daily` (7 calendar days, UTC), so
the card total always matches the sparkline.
### Configuration (all via environment variables — no secrets in the image)
| Env | Required | Default | Description |
|-----|----------|---------|-------------|
| `STATS_DB_DSN` | yes | — | MySQL DSN, e.g. `gitea_ro:PASSWORD@tcp(mysql:3306)/giteadb?timeout=5s&readTimeout=10s&loc=UTC` |
| `STATS_OUT` | no | `/out/stats.json` | Output path (mount Gitea's `custom/public/assets` here) |
| `STATS_INTERVAL` | no | `12h` | Refresh interval (Go duration) |
| `STATS_ADDR` | no | `:8080` | Address for the local `/healthz` endpoint |
The service fetches once on start, then every `STATS_INTERVAL`. On a failed
refresh it keeps the previous output (stale-while-error).
### Build & publish (image to the Gitea container registry)
```sh
# from repo root
IMAGE=git.hangman-lab.top/hzhang/gitea-stats TAG=0.2.0 ./publish.sh
```
### Run
```sh
docker run -d --name git-kc-stats \
--network git-kc-net \
-e STATS_DB_DSN='gitea_ro:***@tcp(mysql:3306)/giteadb?timeout=5s&readTimeout=10s&loc=UTC' \
-e STATS_INTERVAL=12h \
-v /var/lib/gitea/custom/public/assets:/out \
git.hangman-lab.top/hzhang/gitea-stats:0.2.0
```
> The read-only MySQL user (`gitea_ro`, `SELECT` only on `giteadb`) and its
> password are provisioned out-of-band; the password is passed only through
> `STATS_DB_DSN` at runtime and is never committed.