ci: Gitea Actions PR-Gate und Tooling-Hygiene
CI / lint + typecheck + test (push) Has been cancelled

Lokales make check als CI-Gate (lint/mypy/unittest), mise-Lint per Glob,
Cache-Dirs in .gitignore und Doku für self-hosted Gitea Actions.
This commit is contained in:
grok-bot committed 2026-08-03 23:03:18 +02:00
1 parent 5f15d42b26
commit c0534541f8
8 files changed
+135 -79

No files matched your search

+42
View File
@@ -0,0 +1,42 @@
# Gitea/Forgejo Actions – PR-Gate (Parity zu lokalem `make check` / `mise run check`)
# Scope: lint (py_compile) + mypy + unittest. Kein Coverage-Gate, kein mutmut, keine Live-Tests.
# Runner-Label muss zum act_runner passen (oft ubuntu-latest; ggf. anpassen).
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
check:
name: lint + typecheck + test
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
- name: Dev-Dependencies installieren
run: pip install -e ".[dev]"
- name: check (lint + typecheck + test)
run: make check
env:
# Unit-Tests setzen Dummy-Keys in tests/common.py; keine echten Secrets.
# Live-Suite bleibt ohne RUN_LIVE_TESTS=1 inaktiv.
PYTHONDONTWRITEBYTECODE: "1"
+2
View File
@@ -24,3 +24,5 @@ mutants/
.mutmut-cache
mutmut-stats.json
mutmut_stats.json
.mypy_cache/
.pytest_cache/
+9 -7
View File
@@ -16,10 +16,11 @@ Session-Status: [HANDOFF.md](HANDOFF.md) (nicht auto-geladen – bei Fortsetzung
| Chat | `mise run chat` / `python -m chatpy` |
| Tests | `mise run test` |
| Typecheck | `mise run typecheck` |
| Lint + Typecheck + Tests | `mise run check` |
| Lint + Typecheck + Tests | `mise run check` (CI-Parity) |
| Live-Tests | `RUN_LIVE_TESTS=1` + echte Keys (Free-Tier) |
Kein Ruff/Black – Standard-Python, PEP-8. Fallback ohne mise: `python3 -m venv .venv && .venv/bin/pip install -e .` (Details: [development.md](docs/development.md)).
Kein Ruff/Black – Standard-Python, PEP-8. Fallback ohne mise: `python3 -m venv .venv && .venv/bin/pip install -e .` (Details: [development.md](docs/development.md)).
**CI:** Gitea Actions [`.gitea/workflows/ci.yml`](.gitea/workflows/ci.yml) → `make check` (kein Coverage/mutmut/Live).
## Nicht verhandelbar
@@ -37,11 +38,12 @@ Hard-Deny (Read/Edit `.env`, destruktive Shell): [`.grok/config.toml`](.grok/con
## Layout (kompakt)
```text
chat.py → dünner Launcher → chatpy.chat.main
chatpy/ → Package (chat, commands, providers, client, models, types, …)
tests/ + tests/live/ → Unit-Tests / opt-in Live
.runtime/ → Settings, History, Caches (gitignored)
docs/ → kanonische Doku
chat.py → dünner Launcher → chatpy.chat.main
chatpy/ → Package (chat, commands, providers, client, models, types, …)
tests/ + tests/live/ → Unit-Tests / opt-in Live
.gitea/workflows/ci.yml → Gitea Actions PR-Gate (make check)
.runtime/ → Settings, History, Caches (gitignored)
docs/ → kanonische Doku
```
Module/Flows: [architecture.md](docs/architecture.md). Startup lädt `.env` (Root), bricht ohne Cloud-Key **und** ohne `OPENAI_COMPAT_BASE_URL` ab (`sys.exit(1)`).
+6
View File
@@ -7,6 +7,12 @@ Versionierung nach [Semantic Versioning](https://semver.org/lang/de/).
## [Unreleased]
### Hinzugefügt – CI / Tooling
- Gitea/Forgejo Actions: `.gitea/workflows/ci.yml` (PR-Gate = `make check`)
- `mise run lint` nutzt Glob `chatpy/*.py` (Parity zu Makefile; keine fehlenden Module)
- `.gitignore`: `.mypy_cache/`, `.pytest_cache/`
- Doku: CI-Abschnitt in `docs/development.md`
### Hinzugefügt – Typing / mypy
- Dev-Dependency `mypy`; Tasks `mise run typecheck` / `make typecheck`
- `check` = lint + typecheck + test
+35 -64
View File
@@ -3,81 +3,59 @@
**Stand:** 2026-08-03
**Branch:** `main`
**Release (Tag):** **v2.1.0** (remote vorhanden)
**HEAD (committed):** `c5f6be5` · Package-Typing mit mypy
**Remote:** `main` **1 Commit vor** `origin/main` (noch nicht gepusht)
**Working Tree:** **clean**
**Verifikation:** `mise run typecheck` → **0 errors**; `mise run test` → **619 OK**, 5 skipped
### Neu: Typing nach Best Practices (`c5f6be5`)
- mypy als Dev-Dep; `[tool.mypy]` in `pyproject.toml`; `mise run typecheck`
- `types.py` erweitert; Hints in settings/history/client/commands/chat/…
- `check` = lint + typecheck + test; keine Runtime-Verhaltensänderung
**Thema dieser Session:** Tooling & CI/CD (Gitea Actions PR-Gate)
**Working Tree:** dirty bis Commit (CI/Tooling)
Agent-Regeln: [AGENTS.md](AGENTS.md) · Changelog: [CHANGELOG.md](CHANGELOG.md) · Architektur: [docs/architecture.md](docs/architecture.md)
---
## Kurz: Was ist erledigt?
| Phase | Inhalt | Commit / Stand |
|-------|--------|----------------|
| 1+2 | Workflow-Commands, Tokens, Scripting-CLI, Modell-Filter | `2c58e60` |
| 3 | Local OpenAI-kompatibler Provider | `83100ab` |
| Release | CHANGELOG, Version 2.1.0, Tag `v2.1.0` | `1c9698c` / Docs |
| **P1–P5** | Qualitäts-Refactor + Session-Snapshots | `5780a14` |
| **Mutation Testing** | mutmut-Setup + Score **81,1 %** | `1fc458d` |
| **QoL-Kern** | Anhänge, Web, CLI `-f`, Export JSON, Session-QoL | `7215a02` |
| Docs | Getting-Started-Tutorial | `28f1009` |
| **Modularisierung** | `stats`, `session_snapshot`, chat ohne `_cmd_*`-Fassade | **`302450d`** (gepusht) |
---
## Modularisierung (`302450d`) – Detail
### Kontext / Urteil
- Package war bereits gut geschnitten (~4,4k LOC, flache Module).
- **Kein** Nested-Package-Tree – zu teuer, wenig Nutzen.
- Umgesetzt: gezielte Domain-Schnitte + Test-Kompat-Schicht abtragen (Plan B1 + B3 + B4).
### Umgesetzt
## Neu: Tooling & CI/CD (Best Practices, Ansatz B)
| Änderung | Detail |
|----------|--------|
| `chatpy/stats.py` | `Statistics` aus `history.py`; Re-Export `history.Statistics` bleibt |
| `chatpy/session_snapshot.py` | Snapshot-Logik aus `commands.py`; Re-Export unter `commands.*` für Tests |
| `chat.py` | ~100 Zeilen `_cmd_*` / `_COMMANDS` / Alias-Re-Exports **entfernt** |
| Tests | `test_commands` → `chatpy.commands`; Patch `chat.switch_provider`; `find_model_by_name` über providers |
| Doku | architecture, development (Mock-Tabelle), AGENTS, CHANGELOG Unreleased |
| `.gitea/workflows/ci.yml` | Gitea/Forgejo Actions: push/PR `main` → `pip install -e ".[dev]"` + **`make check`** |
| `mise.toml` lint | Glob `chat.py chatpy/*.py` (vorher explizite Liste, fehlten u. a. stats/session_snapshot) |
| `.gitignore` | `.mypy_cache/`, `.pytest_cache/` |
| Docs | CI-Abschnitt in `docs/development.md`; AGENTS/CHANGELOG |
### LOC (ca.)
- `chat.py` ~602, `commands.py` ~551, `history.py` ~379
- neu: `stats.py` ~64, `session_snapshot.py` ~142
- `client.py` **nicht** gesplittet (Stream nur bei nächstem Stream-Feature)
**Scope bewusst:** kein Coverage-Gate, kein mutmut-CI, keine Live-Tests, kein Ruff/Black.
**Runner:** Label `ubuntu-latest` muss zum `act_runner` passen – ggf. im Workflow anpassen.
### Bewusst nicht gemacht
- Nested Packages
- Stream aus `client.py` (optional später)
- Verhaltensänderungen Free-Tier / Reasoning
### Verifikation
### Verifikation (lokal)
```bash
mise run check
# → 619 Unit-Tests OK (skipped=5)
mise run check # oder make check
```
### Nach Push auf Gitea
1. Actions fürs Repo aktiv
2. Runner online + Label match
3. Workflow „CI“ grün
---
## Kurz: Was ist erledigt? (Vorgänger)
| Phase | Inhalt | Commit / Stand |
|-------|--------|----------------|
| Typing | mypy + Domain-Typen | `c5f6be5` |
| Modularisierung | stats, session_snapshot, chat-Fassade | `302450d` |
| QoL / Mutation / Release 2.1.0 | … | siehe Historie |
---
## Offen / nächste Schritte (Priorität)
1. Optional P2: Auto-Summarize bei Token-Limit (verbraucht Free-Quota)
2. Optional: Stream → `stream.py` nur bei Stream-Arbeit
3. Live-Smoke Local (Ollama), wenn Server läuft
4. Optional: Version **2.2.0** + Tag, wenn nächstes Feature-Release ansteht
5. Mutation-Score weiter härten nur auf Wunsch
1. **CI-Smoke auf Gitea** nach Push (Runner-Label / Action-Mirror prüfen)
2. Optional P2: Auto-Summarize bei Token-Limit
3. Optional: Stream → `stream.py` nur bei Stream-Arbeit
4. Live-Smoke Local (Ollama), wenn Server läuft
5. Optional: Version **2.2.0** + Tag, wenn nächstes Feature-Release ansteht
6. Optional später: Coverage-Report in CI (ohne hartes Gate), mutmut scheduled
### Bewusst nicht anfassen
- Keine neuen Runtime-Deps ohne Rücksprache
- Free-Tier-Schutz (OpenRouter `:free` / `max_price`) und Reasoning nur mit Test-Update
- Free-Tier-Schutz und Reasoning nur mit Test-Update
- Agent/MCP/Tool-Calling nur auf expliziten Wunsch
---
@@ -85,15 +63,8 @@ mise run check
## Start nächste Session
```bash
# 1) Kontext
cat HANDOFF.md
git status
# erwartet: clean, main == origin/main @ 302450d
# 2) Verifikation
mise run check # 619+ Unit-Tests OK
# 3) Weiter
# - nächstes Feature aus „Offen“
# - oder Release-Bump 2.2.0, wenn Feature-Stand reif
mise run check
# Falls CI noch rot: Runner-Label in .gitea/workflows/ci.yml anpassen
```
+3
View File
@@ -18,6 +18,7 @@ test-cov-html: test-cov
$(PYTHON) -m coverage html
@echo "HTML-Report: htmlcov/index.html"
# Glob deckt alle Module ab (inkl. stats, session_snapshot, attachments, types, …)
lint:
$(PYTHON) -m py_compile chat.py chatpy/*.py
@@ -26,8 +27,10 @@ typecheck:
(echo "mypy fehlt. Bitte: mise run install-dev oder pip install -e '.[dev]'" >&2; exit 1)
$(PYTHON) -m mypy
# Kanonisches Gate – lokal und in Gitea Actions (siehe .gitea/workflows/ci.yml)
check: lint typecheck test
# Optional: lokaler Pre-commit = gleiches Gate wie CI (langsam bei großer Suite)
setup-hooks:
printf '#!/bin/sh\nset -e\nmake check\n' > .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
+36 -6
View File
@@ -11,7 +11,7 @@ Architektur: [architecture.md](architecture.md).
mise trust && mise install
mise run install # Runtime: pip install -e .
mise run install-dev # Runtime + Dev (coverage)
mise run check # lint + tests
mise run check # lint + typecheck + test (CI-Parity)
```
Ohne mise:
@@ -34,9 +34,10 @@ Python: **3.12** (siehe `mise.toml` / `requires-python`).
| `mise run test-cov` / `make test-cov` | Tests + Coverage-Report |
| `mise run test-cov-html` / `make test-cov-html` | + HTML unter `htmlcov/` |
| `mise run mutmut` | Mutation Testing + Mutations-Score |
| `mise run lint` / `make lint` | `py_compile` der Package-Module |
| `mise run lint` / `make lint` | `py_compile chat.py chatpy/*.py` |
| `mise run typecheck` / `make typecheck` | mypy für Package `chatpy` |
| `mise run check` / `make check` | lint + typecheck + test (ohne Coverage) |
| `mise run check` / `make check` | lint + typecheck + test (ohne Coverage; **CI-Gate**) |
| `make setup-hooks` | optionaler Pre-commit-Hook → `make check` |
## Konventionen
@@ -153,12 +154,41 @@ Nach dem Package-Refactor müssen Patches die **Package-Pfade** treffen:
Sleeps und Rate-Limiter in Fehlerpfad-Tests patchen, sonst unnötig langsame Suite.
## CI (Gitea / Forgejo Actions)
Workflow: [`.gitea/workflows/ci.yml`](../.gitea/workflows/ci.yml) auf dem self-hosted
Remote (Gitea/Forgejo).
| | |
|--|--|
| **Trigger** | `push`/`pull_request` auf `main`, plus `workflow_dispatch` |
| **Gate** | `pip install -e ".[dev]"` → **`make check`** (lint + mypy + unittest) |
| **Parity** | Lokal dasselbe: `mise run check` oder `make check` |
| **Python** | 3.12 |
| **Secrets** | keine – Unit-Tests nutzen Dummy-Keys aus `tests/common.py` |
| **Nicht in CI** | Coverage-Gate, mutmut, Live-Tests (`RUN_LIVE_TESTS`) |
**Runner:** `runs-on: ubuntu-latest` muss zum Label des `act_runner` passen.
Stimmt der Job nicht an, Label im Workflow an den Runner anpassen (Gitea:
Admin → Actions → Runners).
**Actions:** `actions/checkout@v4` und `actions/setup-python@v5`. Wenn die
Instanz Actions nicht spiegelt und der Job beim Checkout scheitert, Mirror
einrichten oder den Job auf ein `python:3.12`-Container-Image umstellen.
Optional lokal vor jedem Commit:
```bash
make setup-hooks # schreibt .git/hooks/pre-commit → make check
```
## Verifikation vor Abgabe
1. `mise run lint` (oder `make lint`)
2. `mise run test` → alles grün (oder `mise run check`)
3. Bei Coverage-relevanten Änderungen optional `mise run test-cov`
4. Live-Tests nur bewusst mit Keys und `RUN_LIVE_TESTS=1`
2. `mise run typecheck` (mypy)
3. `mise run test` → alles grün (oder `mise run check`)
4. Bei Coverage-relevanten Änderungen optional `mise run test-cov`
5. Live-Tests nur bewusst mit Keys und `RUN_LIVE_TESTS=1`
## Weitere Docs
+2 -2
View File
@@ -130,8 +130,8 @@ PY
"""
[tasks.lint]
description = "Syntax-Check aller Package-Module"
run = "python -m py_compile chat.py chatpy/__init__.py chatpy/__main__.py chatpy/chat.py chatpy/client.py chatpy/models.py chatpy/history.py chatpy/settings.py chatpy/reasoning.py chatpy/ui.py chatpy/theme.py chatpy/config.py chatpy/utils.py chatpy/logging_setup.py chatpy/commands.py chatpy/providers.py"
description = "Syntax-Check aller Package-Module (chat.py + chatpy/*.py)"
run = "python -m py_compile chat.py chatpy/*.py"
[tasks.typecheck]
description = "mypy Typecheck für Package chatpy"