Gitea-Weg der Worker: intern statt DDNS + gitea-pr-Helfer + Waechter-Scope-Fix

- werkstatt-SOUL Regel 3: Klonen IMMER ueber http://192.168.178.153:3000
  (DDNS-Domain nachts wegen Zwangstrennung tot -> Worker hielt Gitea am
  24.07. faelschlich fuer kaputt und blockte). Nie SSH-Remotes, nie nach
  Passwoertern fragen.
- deploy/gitea-pr (neu): PR per Gitea-REST-API mit Token aus
  ~/.git-credentials (Vorfall 23.07.: Worker bat um Web-Passwort).
- ampel-waechter: /repos/search statt /user/repos - Token hat nur
  write:repository, /user/repos gab 403 und der stille exit 0 versteckte
  das seit Inbetriebnahme (Merkliste blieb leer, kein Alarm ging je raus).
  API jetzt intern, Telegram-Links bleiben auf der Domain.
- tabu-pfade-guard: Klon-Empfehlung in der Blockmeldung auf interne URL.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-07-24 08:40:40 +02:00
parent 057cc2bb47
commit 8e735df32d
4 changed files with 60 additions and 6 deletions
+1 -1
View File
@@ -95,7 +95,7 @@ if tool == "terminal":
"TABU (R5): `git init` ist im Worker-Workspace gesperrt — Orphan-Branches ohne " "TABU (R5): `git init` ist im Worker-Workspace gesperrt — Orphan-Branches ohne "
"gemeinsamen Ursprung mit main sind bei der Annahme technisch tot (Vorfaelle " "gemeinsamen Ursprung mit main sind bei der Annahme technisch tot (Vorfaelle "
"12.14.07.). Richtiger Weg: VOLL klonen, z. B. git clone " "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.")}) "(Credentials liegen in ~/.git-credentials), dann Branch von origin/main abzweigen.")})
# Schreib-Subkommandos von git (V16: + clone — `git clone URL ~/mission-control-v2` # Schreib-Subkommandos von git (V16: + clone — `git clone URL ~/mission-control-v2`
# rutschte vorher an (a) UND (d) vorbei). # rutschte vorher an (a) UND (d) vorbei).
+9 -3
View File
@@ -15,7 +15,9 @@ python3 - "$TOKEN" "$STATE" <<'PY'
import json, sys, urllib.request import json, sys, urllib.request
token, state_pfad = sys.argv[1], sys.argv[2] 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" WEB = "https://git.tobisniceshomelab.ddnsfree.com"
@@ -32,8 +34,12 @@ except OSError:
neu = [] neu = []
try: try:
repos = api("/user/repos?limit=50") # /repos/search statt /user/repos: das Token hat nur write:repository-Scope,
except Exception: # /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) sys.exit(0)
for repo in repos: for repo in repos:
+40
View File
@@ -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 <repo> <head-branch> "<titel>" ["<body>"] [base=main]
set -euo pipefail
REPO="${1:?Nutzung: gitea-pr <repo> <head-branch> \"<titel>\" [\"<body>\"] [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
+10 -2
View File
@@ -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 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 auf main, NIEMALS mergen, NIEMALS deployen, NIEMALS Dienste neu starten. Der Commander
klickt die Karte im Auftragsbuch. klickt die Karte im Auftragsbuch.
3. Frisch und VOLL klonen statt Live-Checkout nutzen: 3. Frisch und VOLL klonen statt Live-Checkout nutzen — IMMER über die INTERNE URL:
`git clone https://git.tobisniceshomelab.ddnsfree.com/Hitonabi/mission-control-v2` `git clone http://192.168.178.153:3000/Hitonabi/mission-control-v2`
(Credentials liegen in `~/.git-credentials`; Lucy-Repo: `.../Hitonabi/lucy`). (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 <repo> <head-branch> "<titel>"` (Helfer in `~/.local/bin`, nutzt die
Gitea-API mit demselben Token).
NIEMALS `git init`, NIEMALS `--depth`/Shallow, NIEMALS in einem Verzeichnis committen, NIEMALS `git init`, NIEMALS `--depth`/Shallow, NIEMALS in einem Verzeichnis committen,
das nicht dieser frische Klon ist — sonst entsteht ein Branch OHNE gemeinsamen das nicht dieser frische Klon ist — sonst entsteht ein Branch OHNE gemeinsamen
Ursprung, den das Auftragsbuch als „kaputt aufgesetzt" aussortiert (Vorfall Ursprung, den das Auftragsbuch als „kaputt aufgesetzt" aussortiert (Vorfall