A small persistent service (bot/app.py) that reuses the ci-ai modules (llm.py->Jetson, gitea_api.py, ai_review prompt). Handles issue_comment @ci-ai mentions as threaded chat and pull_request events as idempotent reviews — answering in seconds via webhook, with NO runner/clone/hairpin. Runs on the Pi next to Gitea (internal http://gitea:3000 API). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ci-ai — KI-Schicht für die Gitea-CI
Self-hosted Äquivalent zu GitLab Duo für Gitea + act_runner: automatische
PR-Reviews, PR-Summaries, KI-erklärte Security-Funde und CI-Failure-Analyse.
Läuft über den vorhandenen gitea-runner auf dem Pi.
Bausteine
| Feature | Skript | Trigger |
|---|---|---|
| A — PR-Review + Summary | scripts/ai_review.py |
pull_request |
| B — Security-Scan + KI-Erklärung (hart blockierend) | security.yml + scripts/ai_explain.py |
pull_request, push |
| C — CI-Failure-Analyse | if:failure()-Job + scripts/ai_explain.py |
Job-Fehler |
| D — Test-Generierung (Vorschlag) | scripts/ai_tests.py |
Kommentar /gen-tests (PR) |
| E — Issue-/PR-Zusammenfassung | scripts/ai_summary.py |
Kommentar /summarize |
Slash-Commands (D + E): in einem Issue/PR /gen-tests bzw. /summarize kommentieren
→ der commands-Job (siehe caller.example.yml) postet das Ergebnis als Kommentar.
scripts/llm.py ist die provider-agnostische LLM-Schicht — heute Claude
(Anthropic), später der lokale Jetson (Ollama), umschaltbar per Env-Var.
Aufbau
scripts/
llm.py Provider-Abstraktion (anthropic | ollama), stdlib-only
gitea_api.py PR-Diff holen + idempotente Marker-Kommentare
context.py Gitea-Actions-Event-Kontext (GITHUB_*-Vars)
ai_review.py Feature A
ai_explain.py Features B & C
ai_tests.py Feature D (/gen-tests)
ai_summary.py Feature E (/summarize)
.gitea/workflows/
reusable-security.yml on: workflow_call — zentraler Security-Scan
reusable-ai-review.yml on: workflow_call — zentraler PR-Review
reusable-commands.yml on: workflow_call — Slash-Commands (/gen-tests, /summarize)
workflows/
caller.example.yml der EINE 12-Zeiler fürs Ziel-Repo (empfohlen)
*.example.yml standalone-Workflows (Alternative: kopieren)
Keine Abhängigkeiten — reine Python-Standardbibliothek, kein pip install.
In ein Repo einbauen
Empfohlen: globaler Aufruf (reusable workflow)
Nur eine Datei ins Ziel-Repo: workflows/caller.example.yml →
.gitea/workflows/ci-ai.yml. Sie ruft die zentrale Logik aus diesem Repo auf
(uses: user2595/ci-ai/.gitea/workflows/reusable-*.yml@main + secrets: inherit).
Logik-Updates passieren einmal hier, alle Repos ziehen automatisch nach.
Einmalig zentral einzurichten:
- Runner instanzweit registrieren (Admin → Actions → Runners), Label
eulernest— sonst haben Repos außerhalb der org keinen Runner. - Anonymen Clone für public Repos erlauben (
REQUIRE_SIGNIN_VIEW=false) — der Job klontci-aifür die Skripte. ANTHROPIC_API_KEYals Org-/Instanz-Actions-Secret (KI-Schritte; ohne ihn laufen die Scans normal, die KI-Teile überspringen sich sauber).- Für „hart blockieren":
security-Check in der Branch-Protection als required.
Alternative: standalone (kopieren)
workflows/ai-review.example.yml + workflows/security.example.yml direkt nach
.gitea/workflows/ kopieren. Enthält die volle Logik (klont die Skripte selbst) —
mehr Copy-Paste, aber unabhängig von reusable-workflow-Support.
Umstieg auf den Jetson (später)
Sobald das lokale Ollama auf dem Jetson läuft — nur die Workflow-Env ändern, kein Code-Change:
AI_PROVIDER: ollama
AI_MODEL: qwen-light
AI_BASE_URL: http://192.168.178.20:11434/v1
JETSON_API_KEY: ${{ secrets.JETSON_API_KEY }}
Konfiguration (Env-Vars)
| Var | Default | Zweck |
|---|---|---|
AI_PROVIDER |
anthropic |
anthropic oder ollama |
AI_MODEL |
claude-3-5-haiku-latest / qwen-light |
Modell |
ANTHROPIC_API_KEY |
— | Pflicht bei provider=anthropic |
AI_BASE_URL |
http://192.168.178.20:11434/v1 |
Ollama-Endpoint |
JETSON_API_KEY |
— | Bearer für Ollama (optional) |
GITEA_API |
https://git.eulernest.eu/api/v1 |
Gitea-API-Basis |
GITEA_TOKEN / GITEA_BOT_TOKEN |
— | Token fürs Kommentieren |
Constraints
- Runner hat capacity 1 → Jobs laufen seriell.
- Docker-Executor abgesichert (kein privileged, keine Host-Mounts) → Trivy
fs/config+ Gitleaks laufen; Scans laufender Container nicht (unnötig). - Kosten (Anthropic, Haiku-Klasse, gedeckelter Diff): Bruchteile eines Cent/PR.