Skip to content
Merged

Ref #81

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions .husky/pre-push
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
#!/bin/sh
# ⚠️ SECURITY GATE – KEIN BYPASS ERLAUBT
# git push --no-verify ist verboten (ssot_agent_policy.md §2.2).
# Fehlschlagende Tests müssen behoben werden, nicht umgangen.

echo "🔍 Starte Qualitäts-Checks vor dem Push..."

# 1. Schnelle Tests mit Coverage ausführen
# Hinweis: Falls Tests zu lange dauern, können Sie diese Hook mit:
# git push --no-verify
# umgehen (nicht empfohlen!)
# 1. Schnelle Tests ausführen (Quality Gate – blockierend)
echo "⏳ Starte npm run test:fast..."
LOG_LEVEL=warn npx vitest run --exclude tests/server/load-suite.test.ts --exclude tests/integration/serial-flow.test.ts
if [ $? -ne 0 ]; then
if LOG_LEVEL=warn npx vitest run --exclude tests/server/load-suite.test.ts --exclude tests/integration/serial-flow.test.ts; then
echo "✅ Alle Tests bestanden"
else
echo "❌ Fehler: Die schnellen Tests sind fehlgeschlagen!"
echo "💡 Tipp: Um den Hook zu überspringen, verwende: git push --no-verify"
echo " → Tests reparieren, dann erneut pushen."
exit 1
fi

# 2. SonarQube Integration (optional - nur wenn Token gesetzt)
if [ -n "$SONAR_TOKEN" ]; then
echo "📡 Starte SonarQube Scan..."
sonar-scanner -Dsonar.token=$SONAR_TOKEN -Dsonar.qualitygate.wait=false
if [ $? -ne 0 ]; then
# Wrap in if-condition to prevent sh -e from exiting on scanner failure (non-blocking)
if sonar-scanner -Dsonar.token="$SONAR_TOKEN" -Dsonar.qualitygate.wait=false; then
echo "✅ SonarQube Scan abgeschlossen"
else
echo "⚠️ Warnung: SonarQube Scan fehlgeschlagen (nicht blockierend)"
# Nicht mit exit 1 abbrechen - SonarQube Fehler sollten Push nicht blockieren
fi
else
echo "💡 Tipp: Um SonarQube zu aktivieren, setzen Sie: export SONAR_TOKEN=\"<token>\""
echo "ℹ️ Kein SONAR_TOKEN gesetzt — SonarQube Scan übersprungen"
fi

echo "✅ Pre-Push Checks abgeschlossen. Push wird fortgesetzt..."
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,17 +135,16 @@ docker run --rm -p 3000:3000 \
unosim-server:latest
```

Or with Docker Compose:
Or with Docker Compose (backend only):

```bash
docker compose up --build
```
This will now start the UnoSim backend plus two SonarQube services:
This will start the UnoSim backend only. Sandbox execution remains dynamic and uses the Docker socket at runtime.

- `sonarqube` at `http://localhost:9000`
- `mcp-sonarqube` at `http://localhost:9001`
If you need SonarQube, run it separately in its own stack or service; the UnoSim compose file does not include SonarQube or MCP.

The full application runs inside a container with `arduino-cli` pre-installed and is available at `http://localhost:3000`.
The application runs inside a container and is available at `http://localhost:3000`.

For sandboxed sketch execution, the server container must use a temp directory that is bind-mounted from the host at the same absolute path. The provided Compose file does this via `UNOSIM_SHARED_TEMP_DIR=/Users/to/Documents/TT_Web/UnoSim/temp` and `./temp:/Users/to/Documents/TT_Web/UnoSim/temp`.

Expand Down
3 changes: 2 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
services:

# Minimal backend-only stack. Sandbox containers are created dynamically
# by the UnoSim backend via the Docker socket and are not persistent services.
unosim-backend:
build:
context: .
Expand Down
24 changes: 13 additions & 11 deletions run-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

# Konfiguration
LOG_FILE="run-tests_output.log"
TOTAL_STEPS=8
TOTAL_STEPS=7
STEP=0
SERVER_PID=""

Expand All @@ -15,10 +15,12 @@ export LOG_LEVEL=1
export NODE_ENV=test

# Docker-Konfiguration (überschreibbar per Umgebungsvariable)
DOCKER_HOST="${DOCKER_HOST:-unix:///$(echo $HOME)/.docker/run/docker.sock}"
DOCKER_IMAGE="unosim:latest"
# unix:// + absolute path = 3 slashes total; $HOME already starts with /
DOCKER_HOST="${DOCKER_HOST:-unix://${HOME}/.docker/run/docker.sock}"
DOCKER_SANDBOX_IMAGE="${DOCKER_SANDBOX_IMAGE:-unosim-sandbox:latest}"
export DOCKER_HOST DOCKER_SANDBOX_IMAGE
# Temp-Verzeichnis unter /Users/… damit Docker Desktop es per default mounten kann
UNOSIM_SHARED_TEMP_DIR="${UNOSIM_SHARED_TEMP_DIR:-$(pwd)/temp}"
export DOCKER_HOST DOCKER_SANDBOX_IMAGE UNOSIM_SHARED_TEMP_DIR

# Farben & Icons
G="\033[32m"; Y="\033[33m"; R="\033[31m"; C="\033[36m"; B="\033[1m"; D="\033[2m"; RS="\033[0m"
Expand All @@ -31,10 +33,10 @@ cleanup() {
if [ -n "$SERVER_PID" ]; then
kill "$SERVER_PID" 2>/dev/null
fi
# Docker-Container aufräumen: alle laufenden unosim-Container stoppen und entfernen
# Sandbox-Container aufräumen (ephemeral, aus unosim-sandbox:latest entstanden)
if docker info > /dev/null 2>&1; then
local containers
containers=$(docker ps -aq --filter "ancestor=$DOCKER_IMAGE" 2>/dev/null)
containers=$(docker ps -aq --filter "ancestor=$DOCKER_SANDBOX_IMAGE" 2>/dev/null)
if [ -n "$containers" ]; then
echo "$containers" | xargs docker stop --time 5 > /dev/null 2>&1 || true
echo "$containers" | xargs docker rm -f > /dev/null 2>&1 || true
Expand Down Expand Up @@ -115,10 +117,10 @@ run_task "Statische Analyse" "npm run check"
run_task "Unit-Tests" "NODE_OPTIONS='--no-warnings' npm run test:fast -- --reporter=default --maxConcurrency=2"
parse_test_results "Tests.*passed"

# 4+5. Docker Image Build & Docker-Tests (optional, wenn Docker verfügbar)
# 3+4. Sandbox Image Build & Docker-Tests (optional, wenn Docker verfügbar)
# HINWEIS: unosim-server:latest wird von docker compose gebaut, nicht hier.
# Nur das Sandbox-Image wird benötigt und nur wenn es noch nicht existiert.
if docker info > /dev/null 2>&1; then
run_task "Docker Image Build" "docker build -t $DOCKER_IMAGE ."

# Sandbox Image nur bauen wenn es noch nicht existiert
if ! docker image inspect "$DOCKER_SANDBOX_IMAGE" > /dev/null 2>&1; then
run_task "Sandbox Image Build" "docker build -f Dockerfile.sandbox -t $DOCKER_SANDBOX_IMAGE ."
Expand All @@ -140,7 +142,7 @@ if docker info > /dev/null 2>&1; then
tests/server/services/serial-backpressure.test.ts"
parse_test_results "Tests.*passed"
else
echo -e " ${WARN} Docker nicht verfügbar – Docker-Tests werden übersprungen (Steps 4+5)"
echo -e " ${WARN} Docker nicht verfügbar – Docker-Tests werden übersprungen (Steps 3+4)"
STEP=$((STEP+2))
fi

Expand All @@ -153,7 +155,7 @@ export PORT=3000
# Server startet im Hintergrund (NODE_ENV=development für Vite-Snapshots)
# FORCE_DOCKER + DOCKER_SANDBOX_IMAGE werden gesetzt, wenn Docker verfügbar ist (s. oben)
if docker info > /dev/null 2>&1; then
FORCE_DOCKER=1 DOCKER_SANDBOX_IMAGE=$DOCKER_SANDBOX_IMAGE NODE_ENV=development npm run dev >> "$LOG_FILE" 2>&1 &
FORCE_DOCKER=1 DOCKER_SANDBOX_IMAGE=$DOCKER_SANDBOX_IMAGE UNOSIM_SHARED_TEMP_DIR=$UNOSIM_SHARED_TEMP_DIR NODE_ENV=development npm run dev >> "$LOG_FILE" 2>&1 &
else
NODE_ENV=development npm run dev >> "$LOG_FILE" 2>&1 &
fi
Expand Down
3 changes: 2 additions & 1 deletion ssot/ssot_agent_policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
2.2 Test-Integrität:

- Kompletter lokaler Test-Lauf (unit, integration, e2e) vor jedem Push.
- **`git push --no-verify` ist VERBOTEN** – der pre-push Hook ist ein nicht umgehbares Security Gate.
- Bestehende Tests sind unantastbare Spezifikationen (Immutability).
- Test-Anpassungen erfordern technische Begründung und explizite User-Genehmigung.

Expand All @@ -32,7 +33,7 @@
## 4. Checkliste für jeden Agenten-Durchlauf
- [ ] Working-Branch genutzt?
- [ ] State/DOM-Bindung korrekt (Sichtbarkeit/Klassen)?
- [ ] Alle 826 Tests lokal ohne unautorisierte Änderungen bestanden?
- [ ] Alle Tests lokal ohne unautorisierte Änderungen bestanden?
- [ ] User-Intent gewahrt?
- [ ] Numerische/DOM Evidenzen dokumentiert?

Expand Down
Loading