diff --git a/README.md b/README.md index 33803d5..f3a5f9d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,116 @@ # gitea-notification-hub -Gitea webhook to Slack DM middleware (modified for Coolify deployment) \ No newline at end of file +Μικρή υπηρεσία σε Go που δέχεται webhooks από το Gitea (`git.dev1.jkapps.gr`) και στέλνει **προσωπικό μήνυμα στο Slack** σε όποιον αφορά ένα PR ή issue: τον συντάκτη, τους reviewers, τους assignees και όσους γίνονται `@mention`. + +Είναι τροποποιημένη έκδοση του `github.com/vincentc-afk/gitea-notification-hub` (άδεια AGPL-3.0, βλ. `LICENSE`), προσαρμοσμένη για deploy σε Coolify. + +## Περιεχόμενα + +- [Πώς δουλεύει](#πώς-δουλεύει) +- [Ποιος ειδοποιείται](#ποιος-ειδοποιείται) +- [Εγκατάσταση](#εγκατάσταση) +- [Ρύθμιση Gitea](#ρύθμιση-gitea) +- [Ρύθμιση Slack](#ρύθμιση-slack) +- [Αλλαγές σε σχέση με το upstream](#αλλαγές-σε-σχέση-με-το-upstream) +- [Δομή](#δομή) + +## Πώς δουλεύει + +1. Το Gitea στέλνει `POST /webhook` με υπογραφή HMAC στην κεφαλίδα `X-Gitea-Signature`. Αιτήματα χωρίς σωστή υπογραφή απορρίπτονται. +2. Το event (`X-Gitea-Event`) μετατρέπεται σε κοινή μορφή και αποφασίζεται ποιοι χρήστες πρέπει να ειδοποιηθούν. Αυτός που έκανε την ενέργεια αφαιρείται από τη λίστα. +3. Κάθε χρήστης Gitea αντιστοιχίζεται σε χρήστη Slack, με αυτή τη σειρά: + 1. χειροκίνητη αντιστοίχιση από το `MANUAL_USER_MAPPINGS` + 2. cache στη SQLite (`data/notifications.db`) + 3. το πραγματικό email από το Gitea API (`/api/v1/users/{username}`). Το email του webhook δεν χρησιμοποιείται, γιατί μπορεί να είναι noreply. + 4. αναζήτηση στο Slack με αυτό το email. Το αποτέλεσμα αποθηκεύεται στην cache. +4. Το μήνυμα στέλνεται ως DM (Slack blocks). Τα `@mention` του Gitea μέσα στο κείμενο γίνονται mentions του Slack. + +Health check: `GET /health`. + +## Ποιος ειδοποιείται + +| Event | Ενέργεια | Ειδοποιούνται | +|---|---|---| +| `pull_request` | opened | assignees, reviewers | +| | closed / merged | συντάκτης | +| | assigned | ο νέος assignee | +| | review_requested | οι reviewers που ζητήθηκαν. Ο αποστολέας δεν αφαιρείται εδώ, ώστε να δουλεύει και όταν το CI ζητά review εκ μέρους του χρήστη. | +| | synchronize (νέα commits) | συντάκτης, reviewers, assignees | +| `pull_request_review` | | συντάκτης του PR | +| `pull_request_comment` | | συντάκτης, reviewers, mentions | +| `issues` | opened | assignees | +| | closed | συντάκτης | +| `issue_comment` | | συντάκτης, mentions | + +Οι κανόνες ενεργοποιούνται ή απενεργοποιούνται στο `rules` του config. Το `docker-entrypoint.sh` τους έχει όλους ενεργούς. + +## Εγκατάσταση + +Με Docker Compose ή Coolify. Το `docker-entrypoint.sh` γράφει το `config/config.yaml` από τις μεταβλητές περιβάλλοντος σε κάθε εκκίνηση. Το `config/config.example.yaml` είναι μόνο για αναφορά. + +| Μεταβλητή | Υποχρεωτική | Περιγραφή | +|---|---|---| +| `GITEA_WEBHOOK_SECRET` | ναι | Ίδιο με το Secret του webhook στο Gitea | +| `GITEA_URL` | ναι | π.χ. `https://git.dev1.jkapps.gr`, χωρίς `/` στο τέλος | +| `GITEA_API_TOKEN` | ναι | Token Gitea με δικαίωμα ανάγνωσης χρηστών | +| `SLACK_BOT_TOKEN` | ναι | `xoxb-...` | +| `MANUAL_USER_MAPPINGS` | όχι | `giteaUser:SLACKID,άλλος:SLACKID2`. Για χρήστες με διαφορετικό email στο Gitea και στο Slack. | + +Δημιουργήστε `.env` με τις παραπάνω μεταβλητές και τρέξτε: + +```bash +docker compose up -d --build +``` + +Το `docker-compose.yml` περνάει στο container μόνο τις τέσσερις υποχρεωτικές μεταβλητές. Για να φτάσει και το `MANUAL_USER_MAPPINGS`, προσθέστε `- MANUAL_USER_MAPPINGS=${MANUAL_USER_MAPPINGS}` στο `environment` του compose. + +Η υπηρεσία ακούει στο port `8080`. Η βάση SQLite μένει στο `./data`, που είναι volume. + +Τοπικά, χωρίς Docker (απαιτεί Go 1.24 και CGO για τη SQLite): + +```bash +go build -o gitea-notification-hub ./cmd/server +./gitea-notification-hub -config config/config.yaml -debug +``` + +## Ρύθμιση Gitea + +Στο repo, στον οργανισμό ή σε όλο το Gitea: **Settings > Webhooks > Add Webhook > Gitea**. + +- Target URL: `https:///webhook` +- Content type: `application/json` +- Secret: η τιμή του `GITEA_WEBHOOK_SECRET` +- Events: Pull request, Pull request review, Pull request comment, Issues, Issue comment + +## Ρύθμιση Slack + +Slack app με Bot Token και scopes: + +- `chat:write`: αποστολή μηνυμάτων +- `im:write`: άνοιγμα DM +- `users:read` και `users:read.email`: αναζήτηση χρήστη με email + +## Αλλαγές σε σχέση με το upstream + +- Το config γράφεται από μεταβλητές περιβάλλοντος στο `docker-entrypoint.sh`, για το Coolify. +- Υποστήριξη `MANUAL_USER_MAPPINGS`, στον κώδικα Go και στο entrypoint, που γράφει τις αντιστοιχίσεις στη SQLite με το `sqlite3`. +- Διορθώσεις στο `review_requested`: χρησιμοποιούνται όλοι οι reviewers του event και δεν αφαιρείται ο αποστολέας. +- Το entrypoint ξεκινά πάντα με `-debug`. + +Ζητήματα που υπάρχουν σήμερα: + +- Το `default_channel` υπάρχει στο παράδειγμα config, αλλά το entrypoint δεν το ορίζει. +- Το παράδειγμα config αναφέρει PostgreSQL, αλλά υλοποιείται μόνο SQLite. +- Η ρύθμιση `LOG_LEVEL` αναφέρεται στο ιστορικό των commits, αλλά δεν υπάρχει στον κώδικα. + +## Δομή + +| Φάκελος | Περιεχόμενο | +|---|---| +| `cmd/server` | `main.go`, σύνδεση όλων των κομματιών | +| `internal/webhook` | Έλεγχος υπογραφής, τύποι events, handler | +| `internal/event` | Κανόνες ειδοποίησης, mentions, μορφή μηνύματος | +| `internal/identity` | Αντιστοίχιση Gitea → Slack με cache | +| `internal/notifier/slack` | Αποστολή DM | +| `internal/storage/sqlite` | Πίνακας `users` | +| `migrations/` | Σχήμα SQLite |