ci: Gitea Actions PR-Gate und Tooling-Hygiene
CI / lint + typecheck + test (push) Has been cancelled
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:
1 parent
5f15d42b26
commit
c0534541f8
8 files changed
+135
-79
No files matched your search
@@ -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"
|
||||
@@ -24,3 +24,5 @@ mutants/
|
||||
.mutmut-cache
|
||||
mutmut-stats.json
|
||||
mutmut_stats.json
|
||||
.mypy_cache/
|
||||
.pytest_cache/
|
||||
@@ -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)`).
|
||||
|
||||
@@ -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
@@ -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
|
||||
```
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in new issue
Block a user