Erste Etappe des v3-Umbaus. Bewusst ohne jede Architektur-Aenderung: nur Entruempeln, damit der Rest des Umbaus auf einem messbar leichten Stand aufsetzt. Gemessen (vorher -> nachher): dist gesamt 27 375 720 B -> 1 477 852 B (-94,6 %) Dateien in dist 135 -> 35 Start-Chunk gzip 220 278 B -> 110 571 B (-49,8 %) CSS gzip 31 577 B -> 15 121 B (-52,1 %) Schrift-Dateien 112 -> 11 (WOFF 1: 0) Vier Eingriffe: 1) avatar.vrm (24,5 MB) entfernt. Lag in public/ und dist/, wurde von KEINER Zeile des Repos referenziert — der Renderer Avatar3D.tsx war schon vorher verschwunden. War 89,5 % der Nutzlast, die auf die Box ging. Damit fallen auch die .gitignore-Sonderregel und der Direkt-Deploy-Schritt weg. DISASTER_RECOVERY.md §3·D ehrlich auf "ausgebaut" gesetzt (7 Stellen). 2) Schriften: die 11 @fontsource-Sammelimporte zogen ALLE Subsets (latin-ext, griechisch, kyrillisch) und je eine WOFF-1-Fassung mit — 112 Dateien, 1,58 MB, davon 902 kB WOFF 1, das kein Browser dieser App je abruft. Jetzt stehen die @font-face-Regeln direkt in index.css: nur latin, nur WOFF 2, nur die Schnitte, die per grep ueber die font-*-Klassen wirklich belegt sind. Nebenbei behoben: JetBrains Mono 600/700 fehlten komplett — die 19 Stellen mit `font-mono font-bold/semibold` wurden vom Browser synthetisch fettgerechnet. Jetzt echte Schnitte; bei Monospace ist die Laufweite gleich, kein Layout-Versatz. 3) Recharts aus dem Startbuendel. Das Cockpit ist die Startseite und laedt daher NICHT lazy; ueber SystemStatusCard/TokenPerformanceCard zog es Recharts samt d3 in index-*.js. LiveAreaChart ist jetzt eine Lazy-Huelle (Suspense mit hoehengleichem Platzhalter, damit nichts springt), die Recharts-Umsetzung liegt in LiveAreaChartImpl.tsx und kommt als eigener Chunk nach (105 kB gzip). 4) index.css: height 100dvh mit 100% als Rueckfall. Auf Mobilbrowsern mit einfahrender Adressleiste ist 100 % nicht die sichtbare Hoehe. Dazu ein Buendel-Budget in beiden Ampel-Dateien (.gitea/ = MC2-Fassung, deploy/ = universelle Vorlage): Start-Chunk und dist-Gesamtgroesse werden am FRISCHEN Build im Runner gemessen. Bewusst kein Vergleich mit dem committeten dist — der waere ueber Node-Versionen hinweg flatterhaft und wuerde dauerhaft rot leuchten, was das Signal zerstoert. Verifiziert gegen die Box (Frontend-Dev mit MC_API_TARGET=192.168.178.151:9001): Cockpit rendert mit Live-Daten, keine Konsolenfehler, alle 11 Schriftschnitte registriert, LiveAreaChartImpl + recharts laden nachweislich als Nachlade-Chunk. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
104 lines
5.2 KiB
YAML
104 lines
5.2 KiB
YAML
# Ampel-CI fuer MC2 — auf dieses Multi-Service-Monorepo zugeschnitten (24.07.2026).
|
||
#
|
||
# Die universelle Vorlage (deploy/ampel-ci.yml) passt fuer EIN-Service-Repos. MC2 hat
|
||
# 5 Python-Dienste (backend/voice_service/mem0_service/mcp/client) mit schweren ML-
|
||
# Abhaengigkeiten (Whisper/TTS/Embeddings) + ein Frontend. "pip install ALLER requirements
|
||
# + pytest repo-weit" in einem stateless Container ist weder machbar (GB-schwere Wheels,
|
||
# CUDA) noch aussagekraeftig — die echten Tests sind der Pruefstand (deploy/pruefstand)
|
||
# und die Integration auf der Box mit LIVE-Diensten/Modellen, nicht isolierte Unit-Tests.
|
||
#
|
||
# Darum prueft die MC2-Ampel, was im Container EHRLICH gruen sein kann und trotzdem echte
|
||
# Fehler faengt: Lint (ruff, Projekt-Politik in ruff.toml) + Import/Syntax (compileall) +
|
||
# Frontend-Build inkl. TypeScript-Typecheck (tsc). Rot ist ein Ergebnis, kein Aergernis.
|
||
name: Ampel
|
||
on: [push, pull_request]
|
||
|
||
jobs:
|
||
ampel:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: Ampel — Lint + Import + Frontend-Build (MC2-Zuschnitt)
|
||
shell: bash
|
||
run: |
|
||
# Runner-bash laeuft mit -e; abschalten und JEDEN Fehler selbst werten (rot=1),
|
||
# am Ende EIN Klartext-Urteil (Lehre Ampel-Lauf #5).
|
||
set -u +e
|
||
rot=0
|
||
|
||
echo "== Python: Lint (ruff, Projekt-Politik aus ruff.toml) =="
|
||
python3 -m venv /tmp/ampel-venv && . /tmp/ampel-venv/bin/activate || { echo "❌ venv kaputt"; exit 1; }
|
||
pip install -q ruff || { echo "❌ ruff-Install kaputt"; exit 1; }
|
||
ruff check . || rot=1
|
||
|
||
echo "== Python: Import/Syntax (compileall) =="
|
||
python3 -m compileall -q backend voice_service mem0_service mcp client deploy hermes scripts || rot=1
|
||
|
||
echo "== Frontend: reproduzierbarer Build (npm ci + tsc + vite) =="
|
||
if [ -f frontend/package.json ]; then
|
||
if [ ! -f frontend/package-lock.json ]; then
|
||
echo "❌ frontend/: kein package-lock.json — Build nicht reproduzierbar."
|
||
rot=1
|
||
else
|
||
( cd frontend && npm ci --no-audit --no-fund && npm run build ) || rot=1
|
||
|
||
# Bündel-Budget (v3-Umbau P0, 28.08.2026): Der Start-Chunk ist das, was der
|
||
# Nutzer VOR dem ersten Bild lädt. Er lag bei 220 kB gzip, weil das eifrig
|
||
# geladene Cockpit Recharts mitzog; dist lag bei 27 MB wegen eines verwaisten
|
||
# Avatar-Modells. Ohne Deckel wächst beides unbemerkt zurück. Gemessen wird der
|
||
# FRISCHE Build im Runner — kein Vergleich mit dem committeten dist (das wäre
|
||
# über Node-Versionen hinweg flatterhaft und würde dauerhaft rot leuchten).
|
||
if [ $rot -eq 0 ] && [ -d frontend/dist/assets ]; then
|
||
budget_gz=125000 # Stand nach P0: 110 571 B gzip
|
||
budget_dist=3145728 # Stand nach P0: 1 477 852 B
|
||
haupt=$(ls frontend/dist/assets/index-*.js 2>/dev/null | head -1)
|
||
if [ -n "$haupt" ]; then
|
||
gz=$(gzip -c "$haupt" | wc -c)
|
||
echo "-- Start-Chunk: $gz B gzip (Budget $budget_gz)"
|
||
if [ "$gz" -gt "$budget_gz" ]; then
|
||
echo "❌ Start-Bündel über Budget. Meist eine neue Bibliothek, die über"
|
||
echo " das eifrig geladene Cockpit hereinkommt — hinter lazy() legen."
|
||
rot=1
|
||
fi
|
||
fi
|
||
gesamt=$(du -sb frontend/dist | cut -f1)
|
||
echo "-- dist gesamt: $gesamt B (Budget $budget_dist)"
|
||
if [ "$gesamt" -gt "$budget_dist" ]; then
|
||
echo "❌ dist über Budget — Ballast? (Schrift-Subsets, Medien, WOFF 1)"
|
||
rot=1
|
||
fi
|
||
fi
|
||
|
||
if [ $rot -eq 0 ]; then
|
||
echo "== Frontend: Push nach release-dist =="
|
||
git config --global user.name "Gitea Actions"
|
||
git config --global user.email "actions@gitea.local"
|
||
CURRENT_COMMIT=$(git rev-parse HEAD)
|
||
# Erzeuge (oder hole) den orphan branch 'release-dist'
|
||
git checkout --orphan release-dist 2>/dev/null || git checkout release-dist
|
||
git rm -rf . >/dev/null 2>&1 || true
|
||
|
||
# Checkout nur frontend/dist vom aktuellen Stand
|
||
git add -f frontend/dist
|
||
|
||
if ! git diff-index --quiet HEAD; then
|
||
git commit -m "Automatischer Frontend Build ($CURRENT_COMMIT) [skip ci]"
|
||
# Push to release-dist. Token auth from runner is expected to work for Gitea Actions.
|
||
git push origin HEAD:release-dist -f
|
||
else
|
||
echo "Keine Änderungen am Frontend-Build."
|
||
fi
|
||
# Zurück zum originalen Branch für den Rest des Skripts
|
||
git checkout $CURRENT_COMMIT
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
if [ $rot -ne 0 ]; then
|
||
echo "❌ AMPEL ROT — nichts heißt ‚fertig', solange das rot ist."
|
||
else
|
||
echo "✅ AMPEL GRÜN — Lint + Import + Frontend-Build sauber."
|
||
fi
|
||
exit $rot
|