""" Sucht BSSUPPORT-Tickets die in den letzten 2 Wochen durch Releases gefixt wurden. Nur Defects/Bugs. """ import urllib.request, json, ssl, urllib.parse from datetime import datetime, timedelta secrets = {} with open("project-audit/.secrets", "r", encoding="utf-8-sig") as f: for line in f: if "=" in line and not line.startswith("#"): k, v = line.strip().split("=", 1) secrets[k.strip()] = v.strip() TOKEN = secrets.get("JIRA_TOKEN", "") ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE def search(jql, max_results=100): url = f"https://arija.jaas.service.deutschebahn.com/rest/api/2/search?jql={urllib.parse.quote(jql)}&maxResults={max_results}&fields=key,summary,status,priority,assignee,updated,resolved,issuetype,labels,fixVersions,resolution" req = urllib.request.Request(url) req.add_header("Authorization", f"Bearer {TOKEN}") try: resp = urllib.request.urlopen(req, context=ctx, timeout=30) return json.loads(resp.read().decode("utf-8")) except Exception as e: print(f" API-Fehler: {e}") return {"issues": [], "total": 0} two_weeks_ago = (datetime.now() - timedelta(days=14)).strftime("%Y-%m-%d") print(f"=== BSSUPPORT: Bugs/Defects gefixt seit {two_weeks_ago} ===") print() # Suche 1: Resolved in letzten 2 Wochen, Typ Bug/Defect jql = f'project = BSSUPPORT AND issuetype in (Bug, Defect, Fehler) AND resolved >= "{two_weeks_ago}" ORDER BY resolved DESC' r = search(jql) print(f"Suche 1 (resolved >= {two_weeks_ago}, Bug/Defect): {r['total']} Treffer") for i in r.get("issues", []): f = i["fields"] s = f["status"]["name"] p = (f.get("priority") or {}).get("name", "?") res = (f.get("resolution") or {}).get("name", "?") resolved = f.get("resolved", "")[:10] if f.get("resolved") else "?" fix_versions = ", ".join([v["name"] for v in f.get("fixVersions", [])]) print(f" {i['key']:<18} [{s:<14}] Res={res:<10} Resolved={resolved} {f['summary'][:55]}") if fix_versions: print(f" {'':18} FixVersion: {fix_versions}") # Suche 2: Status Done/Geschlossen in letzten 2 Wochen (breiter) print() jql2 = f'project = BSSUPPORT AND issuetype in (Bug, Defect, Fehler, "Sub-task") AND statusCategory = Done AND updated >= "{two_weeks_ago}" ORDER BY updated DESC' r2 = search(jql2) print(f"Suche 2 (Done + updated >= {two_weeks_ago}): {r2['total']} Treffer") for i in r2.get("issues", [])[:30]: f = i["fields"] s = f["status"]["name"] itype = f.get("issuetype", {}).get("name", "?") res = (f.get("resolution") or {}).get("name", "?") fix_versions = ", ".join([v["name"] for v in f.get("fixVersions", [])]) print(f" {i['key']:<18} [{itype:<10}] [{s:<14}] Res={res:<10} {f['summary'][:55]}") if fix_versions: print(f" {'':18} FixVersion: {fix_versions}") # Suche 3: Alle Typen die "fix" im Resolution haben print() jql3 = f'project = BSSUPPORT AND resolution = Fixed AND resolved >= "{two_weeks_ago}" ORDER BY resolved DESC' r3 = search(jql3) print(f"Suche 3 (resolution=Fixed, alle Typen): {r3['total']} Treffer") for i in r3.get("issues", [])[:30]: f = i["fields"] itype = f.get("issuetype", {}).get("name", "?") resolved = f.get("resolved", "")[:10] if f.get("resolved") else "?" fix_versions = ", ".join([v["name"] for v in f.get("fixVersions", [])]) print(f" {i['key']:<18} [{itype:<10}] Resolved={resolved} {f['summary'][:55]}") if fix_versions: print(f" {'':18} FixVersion: {fix_versions}")