Files
ankn a5f8fb49ab Migrate all repos into monorepo context folders
Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
      Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
      Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)

Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
2026-06-30 20:39:52 +02:00

127 lines
4.3 KiB
Python

"""
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 <andre.knie@deutschebahn.com>",
committer=b"Andre Knie <andre.knie@deutschebahn.com>"
)
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()