diff --git a/deploy/agent-hooks/tabu-pfade-guard.py b/deploy/agent-hooks/tabu-pfade-guard.py index ab7fcea..4ed486f 100644 --- a/deploy/agent-hooks/tabu-pfade-guard.py +++ b/deploy/agent-hooks/tabu-pfade-guard.py @@ -95,7 +95,7 @@ if tool == "terminal": "TABU (R5): `git init` ist im Worker-Workspace gesperrt — Orphan-Branches ohne " "gemeinsamen Ursprung mit main sind bei der Annahme technisch tot (Vorfaelle " "12.–14.07.). Richtiger Weg: VOLL klonen, z. B. git clone " - "https://git.tobisniceshomelab.ddnsfree.com/Hitonabi/mission-control-v2 " + "http://192.168.178.153:3000/Hitonabi/mission-control-v2 " "(Credentials liegen in ~/.git-credentials), dann Branch von origin/main abzweigen.")}) # Schreib-Subkommandos von git (V16: + clone — `git clone URL ~/mission-control-v2` # rutschte vorher an (a) UND (d) vorbei). diff --git a/deploy/ampel-waechter.sh b/deploy/ampel-waechter.sh index 439003c..35dbe31 100644 --- a/deploy/ampel-waechter.sh +++ b/deploy/ampel-waechter.sh @@ -15,7 +15,9 @@ python3 - "$TOKEN" "$STATE" <<'PY' import json, sys, urllib.request token, state_pfad = sys.argv[1], sys.argv[2] -BASE = "https://git.tobisniceshomelab.ddnsfree.com/api/v1" +# API intern (die DDNS-Domain ist nachts wegen Zwangstrennung oft tot, 24.07.2026); +# WEB bleibt die Domain — Telegram-Links muessen auch von unterwegs klickbar sein. +BASE = "http://192.168.178.153:3000/api/v1" WEB = "https://git.tobisniceshomelab.ddnsfree.com" @@ -32,8 +34,12 @@ except OSError: neu = [] try: - repos = api("/user/repos?limit=50") -except Exception: + # /repos/search statt /user/repos: das Token hat nur write:repository-Scope, + # /user/repos verlangt read:user -> 403. Der stille exit 0 hat diesen Defekt + # seit Inbetriebnahme versteckt (Fund 24.07.2026, Merkliste blieb leer). + repos = api("/repos/search?limit=50&private=true").get("data", []) +except Exception as e: + print(f"ampel-waechter: Repo-Liste fehlgeschlagen: {e}", file=sys.stderr) sys.exit(0) for repo in repos: diff --git a/deploy/gitea-pr b/deploy/gitea-pr new file mode 100644 index 0000000..e01b390 --- /dev/null +++ b/deploy/gitea-pr @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# gitea-pr (24.07.2026): PR auf Gitea per REST-API anlegen — der EINZIGE Weg für +# Worker, einen Pull-Request zu erstellen. Kein Web-Login, kein Passwort: das +# HTTP-Token aus ~/.git-credentials reicht (Vorfall 23.07.: Wartung-Worker bat +# um das Gitea-Passwort für die Web-GUI und blockte — genau das nie wieder). +# Nutzung: gitea-pr "" [""] [base=main] +set -euo pipefail + +REPO="${1:?Nutzung: gitea-pr \"\" [\"\"] [base]}" +HEAD="${2:?head-branch fehlt}" +TITLE="${3:?titel fehlt}" +BODY="${4:-}" +BASE="${5:-main}" +OWNER="Hitonabi" +# Intern statt DDNS-Domain: die ist nachts (Zwangstrennung) oft nicht erreichbar. +HOST="http://192.168.178.153:3000" + +creds="$(printf 'protocol=http\nhost=192.168.178.153:3000\n\n' | git credential fill)" +username="$(sed -n 's/^username=//p' <<<"$creds")" +password="$(sed -n 's/^password=//p' <<<"$creds")" +[ -n "$password" ] || { echo "FEHLER: kein Token in ~/.git-credentials gefunden" >&2; exit 1; } + +payload="$(TITLE="$TITLE" BODY="$BODY" HEAD="$HEAD" BASE="$BASE" python3 -c ' +import json, os +print(json.dumps({"title": os.environ["TITLE"], "body": os.environ["BODY"], + "head": os.environ["HEAD"], "base": os.environ["BASE"]}))')" + +antwort="$(curl -sS -w '\n%{http_code}' -X POST \ + -u "$username:$password" -H "Content-Type: application/json" \ + -d "$payload" "$HOST/api/v1/repos/$OWNER/$REPO/pulls")" +status="${antwort##*$'\n'}" +koerper="${antwort%$'\n'*}" + +if [ "$status" = "201" ]; then + printf '%s' "$koerper" | python3 -c 'import json,sys; pr=json.load(sys.stdin); print("PR angelegt:", pr.get("html_url", pr.get("url", "?")))' +else + echo "FEHLER: Gitea-API antwortete $status" >&2 + printf '%s\n' "$koerper" | head -c 600 >&2 + exit 1 +fi diff --git a/deploy/werkstatt-SOUL.md b/deploy/werkstatt-SOUL.md index cfba9f0..ccae7e6 100644 --- a/deploy/werkstatt-SOUL.md +++ b/deploy/werkstatt-SOUL.md @@ -37,9 +37,17 @@ den `kanban_heartbeat`, dann sieht der Commander im Auftragsbuch, wo du stehst. 2. Ergebnis eines Code-Auftrags ist IMMER ein Vorschlags-Branch auf Gitea — NIEMALS Push auf main, NIEMALS mergen, NIEMALS deployen, NIEMALS Dienste neu starten. Der Commander klickt die Karte im Auftragsbuch. -3. Frisch und VOLL klonen statt Live-Checkout nutzen: - `git clone https://git.tobisniceshomelab.ddnsfree.com/Hitonabi/mission-control-v2` +3. Frisch und VOLL klonen statt Live-Checkout nutzen — IMMER über die INTERNE URL: + `git clone http://192.168.178.153:3000/Hitonabi/mission-control-v2` (Credentials liegen in `~/.git-credentials`; Lucy-Repo: `.../Hitonabi/lucy`). + Die externe Domain (git.tobisniceshomelab.ddnsfree.com) ist nachts wegen + Zwangstrennung/DDNS oft NICHT erreichbar (Vorfall 24.07.2026: Worker hielt Gitea + für tot und blockte) — sie ist nur Tages-Fallback, nie Standard. + NIEMALS SSH-Remotes (`git@…`), NIEMALS an `~/.ssh` schrauben, NIEMALS nach + Passwörtern fragen — Gitea läuft für dich komplett über HTTP + Token aus + `~/.git-credentials`. Verlangt ein Auftrag ausdrücklich einen Pull-Request: + `gitea-pr ""` (Helfer in `~/.local/bin`, nutzt die + Gitea-API mit demselben Token). NIEMALS `git init`, NIEMALS `--depth`/Shallow, NIEMALS in einem Verzeichnis committen, das nicht dieser frische Klon ist — sonst entsteht ein Branch OHNE gemeinsamen Ursprung, den das Auftragsbuch als „kaputt aufgesetzt" aussortiert (Vorfall