rd13_copilot_setup/git-templates/hooks/pre-commit
Conrad Schulz 6ab2614df5 feat: pre-commit Check 6 – Session-Datei fuer heute erforderlich
- Blockiert Commit wenn keine history/prompts/HEUTE_*_session.md existiert
- Zwingt Agenten /history auszufuehren vor dem Commit
- Opt-out: .copilot-no-session fuer manuelle Commits ohne Chat-Kontext
- .gitignore: *.bak ergaenzt (copilot-update.sh legt .bak bei copilot-instructions.md an)
2026-06-02 18:02:52 +00:00

152 lines
7.9 KiB
Bash
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env sh
# pre-commit Agent Quality Gate
#
# Prüft bei jeder Code-Änderung ob:
# 1. Tests erstellt oder aktualisiert wurden
# 2. Mindestens eine Zielgruppen-Dokumentation aktualisiert wurde
# 3. Alle 3 Dokumentations-Zielgruppen vorhanden sind (USER/ADMIN/MAINTAINER)
# 4. history/summary/PROJECT_CONTEXT.md aktualisiert wurde
# 5. docs/requirements/REQUIREMENTS.md keine unstaged Änderungen hat
# 6. Eine Session-Datei für heute existiert (history/prompts/HEUTE_*_session.md)
#
# Hooks laufen immer kein --no-verify verwenden.
STAGED=$(git diff --cached --name-only --diff-filter=ACMR 2>/dev/null)
ERRORS=0
# Quellcode-Dateien (keine Tests, keine Konfiguration, keine Docs, keine Daten)
CODE_CHANGED=$(printf '%s\n' "$STAGED" \
| grep -E '\.(py|js|ts|mjs|cjs|go|java|rs|rb|php|c|cpp|h|hpp|cs|kt|swift|sh|bash)$' \
| grep -v -E '(test|spec|__tests__|_test)\.(py|js|ts|mjs|go|java|rs|rb|php|c|cpp|cs|kt|swift)$' \
| grep -v -E '^(docs/|\.github/|\.vscode/|data/|history/)' \
| grep -v -E '_test\.go$')
# Keine Code-Änderungen → Hook überspringen
if [ -z "$CODE_CHANGED" ]; then
exit 0
fi
# ── Check 1: Tests ────────────────────────────────────────────────────────────
# Opt-out: Datei '.copilot-no-tests' im Repo-Root deaktiviert diesen Check
# (für Repos ohne Test-Framework, z.B. reine Script/Config-Repos)
TESTS_CHANGED=$(printf '%s\n' "$STAGED" \
| grep -E '(test|spec|__tests__|_test)\.(py|js|ts|mjs|go|java|rs|rb|php|c|cpp|cs|kt|swift)$|_test\.go$|test_.*\.py$')
if [ -z "$TESTS_CHANGED" ] && [ ! -f ".copilot-no-tests" ]; then
echo ""
echo "✗ AGENT QUALITY GATE [1/4]: Keine Test-Dateien geändert"
echo " Code-Änderungen ohne Test-Updates:"
printf '%s\n' "$CODE_CHANGED" | sed 's/^/ /'
echo ""
echo " → Tests fehlen oder nicht als STAGED markiert"
echo " → Copilot Chat: /write-tests"
echo " → Kein Test-Framework vorhanden? Datei '.copilot-no-tests' anlegen um diesen Check zu deaktivieren"
ERRORS=$((ERRORS + 1))
fi
# ── Check 2: Dokumentation aktualisiert ───────────────────────────────────────
# Prüfen ob docs/ Verzeichnis überhaupt existiert
# Opt-out: Datei '.copilot-no-docs' im Repo-Root deaktiviert diesen Check
# (für reine Config/Script-Repos ohne nutzerseitige Dokumentationspflicht)
if [ -d "docs" ] && [ ! -f ".copilot-no-docs" ]; then
DOCS_CHANGED=$(printf '%s\n' "$STAGED" \
| grep -E '(^docs/USER\.md$|^docs/ADMIN\.md$|^docs/MAINTAINER\.md$|^README\.md$)')
if [ -z "$DOCS_CHANGED" ]; then
echo ""
echo "✗ AGENT QUALITY GATE [2/4]: Keine Dokumentation aktualisiert"
echo " Bei Code-Änderungen muss mindestens eine dieser Dateien angepasst werden:"
echo " docs/USER.md Nutzer-Dokumentation"
echo " docs/ADMIN.md Administrator-Dokumentation"
echo " docs/MAINTAINER.md Entwickler/Maintainer-Dokumentation"
echo " README.md"
echo ""
echo " → Copilot Chat: Frage den Agent die relevante Doku zu aktualisieren"
ERRORS=$((ERRORS + 1))
fi
fi
# ── Check 3: Vollständigkeit der 3 Zielgruppen ────────────────────────────────
# Nur prüfen wenn docs/ neu angelegt wird (noch nicht vollständig) oder ein
# neues Feature ein neues docs/-File staged hat.
DOCS_DIR_STAGED=$(printf '%s\n' "$STAGED" | grep -E '^docs/' | head -1)
if [ -n "$DOCS_DIR_STAGED" ] && [ -d "docs" ]; then
MISSING=""
[ ! -f "docs/USER.md" ] && MISSING="${MISSING}\n docs/USER.md (fehlt für Endnutzer)"
[ ! -f "docs/ADMIN.md" ] && MISSING="${MISSING}\n docs/ADMIN.md (fehlt für Administratoren)"
[ ! -f "docs/MAINTAINER.md" ] && MISSING="${MISSING}\n docs/MAINTAINER.md (fehlt für Entwickler)"
if [ -n "$MISSING" ]; then
echo ""
echo "✗ AGENT QUALITY GATE [3/4]: Fehlende Zielgruppen-Dokumentation"
printf " Nicht vorhanden:%b\n" "$MISSING"
echo ""
echo " Alle 3 Zielgruppen-Dokumente müssen existieren."
echo " Templates: docs/USER.md, docs/ADMIN.md, docs/MAINTAINER.md"
ERRORS=$((ERRORS + 1))
fi
fi
# ── Check 4: PROJECT_CONTEXT.md aktualisiert ──────────────────────────────────
if [ -f "history/summary/PROJECT_CONTEXT.md" ]; then
CONTEXT_STAGED=$(printf '%s\n' "$STAGED" | grep -F 'history/summary/PROJECT_CONTEXT.md')
if [ -z "$CONTEXT_STAGED" ]; then
echo ""
echo "✗ AGENT QUALITY GATE [4/4]: PROJECT_CONTEXT.md nicht aktualisiert"
echo " Bei Code-Änderungen muss der Agent-Kontext aktuell gehalten werden."
echo " history/summary/PROJECT_CONTEXT.md"
echo ""
echo " → Copilot Chat: /history (loggt Session + aktualisiert Kontext)"
ERRORS=$((ERRORS + 1))
fi
fi
# ── Check 5: Requirements-Konsistenz ─────────────────────────────────────────
# Wenn docs/requirements/REQUIREMENTS.md existiert und unstaged Änderungen hat,
# muss es vor dem Commit gestaged werden.
# Opt-out: Datei '.copilot-no-requirements' im Repo-Root deaktiviert diesen Check.
if [ -f "docs/requirements/REQUIREMENTS.md" ] && [ ! -f ".copilot-no-requirements" ]; then
REQ_UNSTAGED=$(git diff --name-only -- "docs/requirements/REQUIREMENTS.md" 2>/dev/null)
if [ -n "$REQ_UNSTAGED" ]; then
echo ""
echo "✗ AGENT QUALITY GATE [5/5]: Requirements-Datei hat unstaged Änderungen"
echo " docs/requirements/REQUIREMENTS.md wurde geändert aber nicht gestaged."
echo ""
echo " → git add docs/requirements/REQUIREMENTS.md"
echo " → Copilot Chat: /requirements (Requirements aktualisieren + konsistenz prüfen)"
ERRORS=$((ERRORS + 1))
fi
fi
# ── Check 6: Session-Datei für heute ──────────────────────────────────────────────────
# Prüft ob eine Agent-Session-Datei für heute existiert.
# Zwingt den Agenten /history auszuführen bevor er committet.
# Opt-out: Datei '.copilot-no-session' im Repo-Root für manuelle Commits ohne Chat-Kontext.
if [ -d "history/prompts" ] && [ ! -f ".copilot-no-session" ]; then
TODAY=$(date +%Y-%m-%d)
SESSION_FILE=$(ls "history/prompts/${TODAY}_"*"_session.md" 2>/dev/null | head -1)
if [ -z "$SESSION_FILE" ]; then
echo ""
echo "✗ AGENT QUALITY GATE [6/6]: Keine Session-Datei für heute"
echo " Es existiert kein Agent-Log für heute (${TODAY}_*_session.md)."
echo ""
echo " → Copilot Chat: /history (Session loggen + Kontext aktualisieren)"
echo " → Manueller Commit ohne Chat? Datei '.copilot-no-session' anlegen:"
echo " touch .copilot-no-session && git add .copilot-no-session"
ERRORS=$((ERRORS + 1))
fi
fi
# ── Ergebnis ──────────────────────────────────────────────────────────────────
if [ "$ERRORS" -gt 0 ]; then
echo ""
echo "══════════════════════════════════════════════════════════"
echo " $ERRORS von 6 Quality Gate(s) nicht bestanden."
echo " Behebe die Probleme bevor du committst."
echo " ══════════════════════════════════════════════════════════"
echo ""
exit 1
fi
exit 0