""" Git Push v2 - mit korrekter Auth (oauth2:token als Basic Auth). Behebt den 502-Fehler der durch falsche Auth-Methode verursacht wurde. Usage: python project-audit/scripts/git-push-v2.py "Commit-Nachricht" """ import os, sys from pathlib import Path from dulwich import porcelain from dulwich.repo import Repo REPO_PATH = Path(__file__).parent.parent # project-audit/ SECRETS_PATH = REPO_PATH / ".secrets" REMOTE_URL = "https://git.tech.rz.db.de/AndreKnie/project-audit.git" def load_token(): with open(SECRETS_PATH, "r", encoding="utf-8-sig") as f: for line in f: line = line.strip() if line.startswith("GITLAB_TOKEN_AUDIT="): return line.split("=", 1)[1].strip() print("FEHLER: GITLAB_TOKEN_AUDIT nicht in .secrets!") sys.exit(1) def main(): message = " ".join(sys.argv[1:]) if len(sys.argv) > 1 else "Update pathOS Audit" token = load_token() print(f"=== Git Push v2: {message} ===") print(f" Token: ...{token[-4:]}") print(f" Auth: oauth2 (Basic Auth)") # Stage + Commit falls noetig from dulwich import porcelain as p st = p.status(str(REPO_PATH)) needs_commit = st.unstaged or st.untracked if needs_commit: print(f" Unstaged: {len(st.unstaged)}, Untracked: {len(st.untracked)}") # Stage all patterns = [] gitignore = REPO_PATH / ".gitignore" if gitignore.exists(): with open(gitignore) as f: patterns = [l.strip().strip("/") for l in f if l.strip() and not l.startswith("#")] staged = 0 for root, dirs, files in os.walk(REPO_PATH): if ".git" in root: continue for fname in files: full = Path(root) / fname rel = full.relative_to(REPO_PATH) rel_str = str(rel).replace("\\", "/") if any(p in rel_str for p in patterns): continue try: porcelain.add(str(REPO_PATH), paths=[str(rel)]) staged += 1 except Exception: pass print(f" {staged} Dateien gestaged") try: porcelain.commit( str(REPO_PATH), message=message.encode("utf-8"), author=b"Andre Knie ", committer=b"Andre Knie " ) print(f" Commit erstellt: {message}") except Exception as e: if "nothing to commit" not in str(e).lower(): print(f" Commit-Fehler: {e}") else: print(" Keine neuen Aenderungen, pushe bestehenden Commit.") # Push mit oauth2 als Username (korrektes GitLab-Auth-Schema) print(" Push zu origin (master)...") try: porcelain.push( str(REPO_PATH), REMOTE_URL, refspecs=b"refs/heads/master:refs/heads/master", username="oauth2", password=token ) print(" PUSH ERFOLGREICH!") except Exception as e: err = str(e) print(f" Push-Fehler: {err}") if "502" in err: print(" 502 = Server-Problem oder Auth-Reject durch Proxy") print(" Versuche Alternative: Push via GitLab API...") push_via_api(token) def push_via_api(token): """Fallback: Datei-Upload via GitLab Repository Files API.""" import urllib.request, json, ssl ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE base = "https://git.tech.rz.db.de/api/v4/projects/AndreKnie%2Fproject-audit" headers = {"PRIVATE-TOKEN": token, "Content-Type": "application/json"} # Pruefe welche Dateien sich geaendert haben (vergleiche mit Remote) print(" API-Fallback: Pruefe Remote-Status...") url = f"{base}/repository/tree?per_page=100&ref=master" req = urllib.request.Request(url) req.add_header("PRIVATE-TOKEN", token) try: resp = urllib.request.urlopen(req, context=ctx, timeout=15) print(f" Remote-Tree erreichbar. Aber API-Push ist komplex.") print(" Empfehlung: git binary installieren oder spaeter erneut versuchen.") except Exception as e2: print(f" API-Fallback auch fehlgeschlagen: {e2}") if __name__ == "__main__": main()