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:
@@ -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).
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user