Steuerkram/scripts/container/run-tests.sh

188 lines
6.7 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 bash
# ============================================================
# Steuerkram Test-Runner mit automatischer Issue-Erstellung
#
# Verwendung (im Container):
# docker compose exec -u www-data web ./scripts/container/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 (oder Auswertung fehlgeschlagen)
# ============================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$(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..."
# STDERR wird bewusst NICHT mitgefangen: tests/run.php schreibt im --json-Modus
# etwaige PHP-Warnungen/-Notices dorthin, damit STDOUT ausschließlich das JSON
# enthält (siehe tests/run.php). STDERR landet direkt im Terminal.
JSON_OUTPUT=$($PHP tests/run.php --json) && EXIT_CODE=0 || EXIT_CODE=$?
# Auch die lesbare Ausgabe zeigen
$PHP tests/run.php || true
# ── Ergebnis auswerten ───────────────────────────────────────
if [ "$EXIT_CODE" -eq 0 ]; then
echo ""
echo "✓ Alle Tests bestanden. Commit kann fortgesetzt werden."
exit 0
fi
# tests/run.php meldet Fehlschläge (oder einen sonstigen Fehler) über den
# Exit-Code. Die Details holen wir uns per PHP aus dem JSON – lässt sich die
# Ausgabe nicht auswerten, bricht das Skript hier ab (set -e), statt
# fälschlich Erfolg zu melden.
FAILED=$(echo "$JSON_OUTPUT" | php -r '
$d = json_decode(stream_get_contents(STDIN), true);
if (!is_array($d) || !array_key_exists("failed", $d)) {
fwrite(STDERR, "Ungültige JSON-Ausgabe von tests/run.php --json\n");
exit(1);
}
echo $d["failed"];
')
FAILURES_JSON=$(echo "$JSON_OUTPUT" | php -r '
$d = json_decode(stream_get_contents(STDIN), true);
if (!is_array($d) || !array_key_exists("failures", $d)) {
fwrite(STDERR, "Ungültige JSON-Ausgabe von tests/run.php --json\n");
exit(1);
}
echo json_encode($d["failures"]);
')
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" | php -r '
$d = json_decode(stream_get_contents(STDIN), true);
foreach ((is_array($d) ? $d : []) as $f) { echo " • {$f}\n"; }
'
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 (mit echten Zeilenumbrüchen, kein "\n"-Text)
BODY_LINES=(
"## Automatisch erkannter Testfehler"
""
"**Fehlermeldung:** \`${failure}\`"
""
"**Erkannt am:** $(date '+%Y-%m-%d %H:%M:%S')"
""
"**Commit:** $(git rev-parse --short HEAD 2>/dev/null || echo 'unbekannt')"
""
)
if [ -n "$CURRENT_ISSUE" ]; then
BODY_LINES+=("Dieser Fehler wurde beim Bearbeiten von Issue #${CURRENT_ISSUE} entdeckt." "")
fi
BODY_LINES+=(
"### Schritte zur Reproduktion"
"1. \`docker compose exec -u www-data web php tests/run.php\` ausführen"
"2. Fehler tritt im oben genannten Test auf"
""
"_Dieser Issue wurde automatisch durch den Test-Runner erstellt._"
"_Das Label 'automate' wurde bewusst NICHT gesetzt (Human-in-the-loop)._"
)
BODY=$(printf '%s\n' "${BODY_LINES[@]}")
PAYLOAD=$(TITLE="$TITLE" BODY="$BODY" php -r '
echo json_encode([
"title" => getenv("TITLE"),
"body" => getenv("BODY"),
"labels" => [],
]);
')
RESPONSE=$(curl -s -X POST \
-H "Authorization: token $CODEBERG_TOKEN" \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
"${API_BASE}/repos/${REPO}/issues")
ISSUE_NR=$(echo "$RESPONSE" | php -r '
$d = json_decode(stream_get_contents(STDIN), true);
echo (is_array($d) && isset($d["number"])) ? $d["number"] : "?";
')
CREATED_ISSUES+=("#${ISSUE_NR}")
echo " → Issue #${ISSUE_NR} erstellt: ${failure:0:60}..."
done < <(echo "$FAILURES_JSON" | php -r '
$d = json_decode(stream_get_contents(STDIN), true);
foreach ((is_array($d) ? $d : []) as $f) { echo $f, "\n"; }
')
# ── 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_LINES=(
"### Automatische Testläufe"
""
"Beim Bearbeiten dieses Issues wurden **${FAILED} Test(s)** fehlgeschlagen."
""
"Folgende Bug-Issues wurden automatisch erstellt (ohne 'automate'-Label – bitte manuell prüfen):"
""
)
for issue in "${CREATED_ISSUES[@]}"; do
COMMENT_LINES+=("- ${issue}")
done
COMMENT_LINES+=("" "_Commit: $(git rev-parse --short HEAD 2>/dev/null || echo 'unbekannt')_")
COMMENT=$(printf '%s\n' "${COMMENT_LINES[@]}")
PAYLOAD=$(COMMENT="$COMMENT" php -r '
echo json_encode(["body" => getenv("COMMENT")]);
')
curl -s -X POST \
-H "Authorization: token $CODEBERG_TOKEN" \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
"${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