133 lines
5.3 KiB
Bash
Executable file
133 lines
5.3 KiB
Bash
Executable file
#!/usr/bin/env bash
|
||
|
||
# ============================================================
|
||
# Steuerkram Test-Runner mit automatischer Issue-Erstellung
|
||
#
|
||
# Verwendung:
|
||
# ./scripts/run-tests.sh [ISSUE_NUMMER]
|
||
#
|
||
# Parameter:
|
||
# ISSUE_NUMMER (optional) Nummer des aktuell bearbeiteten Issues,
|
||
# auf das bei neu erstellten Bug-Issues verwiesen wird.
|
||
#
|
||
# Umgebungsvariablen:
|
||
# CODEBERG_TOKEN Codeberg-API-Token (für Issue-Erstellung)
|
||
#
|
||
# Exit-Code: 0 = alle Tests OK, 1 = Fehler gefunden
|
||
# ============================================================
|
||
|
||
set -euo pipefail
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||
CURRENT_ISSUE="${1:-}"
|
||
REPO="fds2610/Steuerkram"
|
||
API_BASE="https://codeberg.org/api/v1"
|
||
|
||
cd "$PROJECT_DIR"
|
||
|
||
# ── PHP als www-data ausführen ───────────────────────────────
|
||
# Als root angelegte Dateien unterhalb von data/ sind für Apache/PHP (www-data)
|
||
# nicht beschreibbar und blockieren später echte Uploads. Deshalb laufen die
|
||
# Tests mit derselben Kennung wie die Anwendung.
|
||
if [ "$(id -u)" = "0" ] && id www-data >/dev/null 2>&1; then
|
||
PHP="setpriv --reuid=www-data --regid=www-data --clear-groups php"
|
||
else
|
||
PHP="php"
|
||
fi
|
||
|
||
# ── Tests ausführen ──────────────────────────────────────────
|
||
echo ""
|
||
echo "Führe Tests aus..."
|
||
JSON_OUTPUT=$($PHP tests/run.php --json 2>&1) || true
|
||
EXIT_CODE=$?
|
||
|
||
# Auch die lesbare Ausgabe zeigen
|
||
$PHP tests/run.php || true
|
||
|
||
# ── Ergebnis auswerten ───────────────────────────────────────
|
||
FAILED=$(echo "$JSON_OUTPUT" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('failed',0))" 2>/dev/null || echo "0")
|
||
FAILURES_JSON=$(echo "$JSON_OUTPUT" | python3 -c "import json,sys; d=json.load(sys.stdin); print(json.dumps(d.get('failures',[])))" 2>/dev/null || echo "[]")
|
||
|
||
if [ "$FAILED" = "0" ] || [ "$FAILED" = "" ]; then
|
||
echo ""
|
||
echo "✓ Alle Tests bestanden. Commit kann fortgesetzt werden."
|
||
exit 0
|
||
fi
|
||
|
||
echo ""
|
||
echo "✗ ${FAILED} Test(s) fehlgeschlagen."
|
||
|
||
# ── Issues erstellen (nur wenn Token vorhanden) ──────────────
|
||
if [ -z "${CODEBERG_TOKEN:-}" ]; then
|
||
echo ""
|
||
echo "Hinweis: CODEBERG_TOKEN nicht gesetzt – keine automatischen Issues erstellt."
|
||
echo "Fehlgeschlagene Tests:"
|
||
echo "$FAILURES_JSON" | python3 -c "import json,sys; [print(' •', f) for f in json.load(sys.stdin)]" 2>/dev/null || true
|
||
exit 1
|
||
fi
|
||
|
||
echo ""
|
||
echo "Erstelle automatische Bug-Issues auf Codeberg..."
|
||
|
||
CREATED_ISSUES=()
|
||
|
||
# Jede Fehlermeldung als eigenes Issue anlegen
|
||
while IFS= read -r failure; do
|
||
[ -z "$failure" ] && continue
|
||
|
||
# Titel kürzen (max. 100 Zeichen)
|
||
TITLE="[BUG] Test fehlgeschlagen: ${failure:0:80}"
|
||
|
||
# Body zusammenbauen
|
||
BODY="## Automatisch erkannter Testfehler\n\n"
|
||
BODY+="**Fehlermeldung:** \`${failure}\`\n\n"
|
||
BODY+="**Erkannt am:** $(date '+%Y-%m-%d %H:%M:%S')\n\n"
|
||
BODY+="**Commit:** $(git rev-parse --short HEAD 2>/dev/null || echo 'unbekannt')\n\n"
|
||
|
||
if [ -n "$CURRENT_ISSUE" ]; then
|
||
BODY+="Dieser Fehler wurde beim Bearbeiten von Issue #${CURRENT_ISSUE} entdeckt.\n\n"
|
||
fi
|
||
|
||
BODY+="### Schritte zur Reproduktion\n"
|
||
BODY+="1. \`docker compose exec -u www-data web php tests/run.php\` ausführen\n"
|
||
BODY+="2. Fehler tritt im oben genannten Test auf\n\n"
|
||
BODY+="_Dieser Issue wurde automatisch durch den Test-Runner erstellt._\n"
|
||
BODY+="_Das Label 'automate' wurde bewusst NICHT gesetzt (Human-in-the-loop)._"
|
||
|
||
RESPONSE=$(curl -s -X POST \
|
||
-H "Authorization: token $CODEBERG_TOKEN" \
|
||
-H "Content-Type: application/json" \
|
||
-d "$(python3 -c "import json; print(json.dumps({'title': '${TITLE}', 'body': '${BODY}', 'labels': []}))")" \
|
||
"${API_BASE}/repos/${REPO}/issues")
|
||
|
||
ISSUE_NR=$(echo "$RESPONSE" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('number','?'))" 2>/dev/null || echo "?")
|
||
CREATED_ISSUES+=("#${ISSUE_NR}")
|
||
echo " → Issue #${ISSUE_NR} erstellt: ${failure:0:60}..."
|
||
|
||
done < <(echo "$FAILURES_JSON" | python3 -c "import json,sys; [print(f) for f in json.load(sys.stdin)]" 2>/dev/null)
|
||
|
||
# ── Kommentar im aktuellen Issue hinterlassen ─────────────────
|
||
if [ -n "$CURRENT_ISSUE" ] && [ ${#CREATED_ISSUES[@]} -gt 0 ]; then
|
||
ISSUE_LINKS=$(printf '%s, ' "${CREATED_ISSUES[@]}")
|
||
ISSUE_LINKS="${ISSUE_LINKS%, }"
|
||
|
||
COMMENT="### Automatische Testläufe\n\n"
|
||
COMMENT+="Beim Bearbeiten dieses Issues wurden **${FAILED} Test(s)** fehlgeschlagen.\n\n"
|
||
COMMENT+="Folgende Bug-Issues wurden automatisch erstellt (ohne 'automate'-Label – bitte manuell prüfen):\n\n"
|
||
for issue in "${CREATED_ISSUES[@]}"; do
|
||
COMMENT+="- ${issue}\n"
|
||
done
|
||
COMMENT+="\n_Commit: $(git rev-parse --short HEAD 2>/dev/null || echo 'unbekannt')_"
|
||
|
||
curl -s -X POST \
|
||
-H "Authorization: token $CODEBERG_TOKEN" \
|
||
-H "Content-Type: application/json" \
|
||
-d "$(python3 -c "import json; print(json.dumps({'body': '${COMMENT}'}))")" \
|
||
"${API_BASE}/repos/${REPO}/issues/${CURRENT_ISSUE}/comments" > /dev/null
|
||
|
||
echo ""
|
||
echo "Kommentar mit Links zu Bug-Issues in Issue #${CURRENT_ISSUE} hinterlassen."
|
||
fi
|
||
|
||
exit 1
|