diff --git a/app/plugins/builtins/forgejo_error_reporter/service.py b/app/plugins/builtins/forgejo_error_reporter/service.py index 602d7a1..74e7eba 100644 --- a/app/plugins/builtins/forgejo_error_reporter/service.py +++ b/app/plugins/builtins/forgejo_error_reporter/service.py @@ -103,10 +103,11 @@ async def _check_rate_limit() -> bool: return True -async def _ensure_labels_exist(client: httpx.AsyncClient, settings: dict[str, str]) -> None: +async def _ensure_labels_exist(client: httpx.AsyncClient, settings: dict[str, str]) -> list[int]: """Ensure required labels exist in the Forgejo repository. Creates 'auto-reported' and 'bug' labels if they don't exist. + Returns the list of label IDs for use in issue creation. """ url = f"{settings['url']}/api/v1/repos/{settings['owner']}/{settings['repo']}/labels" headers = { @@ -114,33 +115,38 @@ async def _ensure_labels_exist(client: httpx.AsyncClient, settings: dict[str, st "Content-Type": "application/json", } + required_names = ["auto-reported", "bug"] + label_ids: list[int] = [] + try: response = await client.get(url, headers=headers) response.raise_for_status() existing_labels = response.json() - existing_names = {label.get("name", "") for label in existing_labels} + existing_map = {label.get("name", ""): label.get("id") for label in existing_labels} - required_labels = [ - {"name": "auto-reported", "color": "0366d6", "description": "Automatically reported by error reporter"}, - {"name": "bug", "color": "d73a4a", "description": "Bug report"}, - ] - - for label_data in required_labels: - if label_data["name"] not in existing_names: + for name in required_names: + if name in existing_map and existing_map[name] is not None: + label_ids.append(existing_map[name]) + else: + label_data = { + "name": name, + "color": "0366d6" if name == "auto-reported" else "d73a4a", + "description": "Automatically reported by error reporter" if name == "auto-reported" else "Bug report", + } create_response = await client.post(url, headers=headers, json=label_data) if create_response.status_code in (201, 200): - logger.info("Created label '%s' in Forgejo repo", label_data["name"]) + new_label = create_response.json() + label_ids.append(new_label.get("id")) + logger.info("Created label '%s' (id=%s) in Forgejo repo", name, new_label.get("id")) else: - logger.warning( - "Failed to create label '%s': %s", - label_data["name"], - create_response.text, - ) + logger.warning("Failed to create label '%s': %s", name, create_response.text) except httpx.HTTPStatusError as exc: logger.warning("Failed to fetch/create labels: %s", exc) except httpx.RequestError as exc: logger.warning("Network error while managing labels: %s", exc) + return label_ids + async def report_error_to_forgejo(entry: dict[str, Any]) -> bool: """Report an error to Forgejo as a new issue. @@ -199,21 +205,21 @@ async def report_error_to_forgejo(entry: dict[str, Any]) -> bool: if len(title) > 255: title = title[:252] + "..." - issue_data = { - "title": title, - "body": body, - "labels": ["auto-reported", "bug"], - } - - url = f"{settings['url']}/api/v1/repos/{settings['owner']}/{settings['repo']}/issues" - headers = { - "Authorization": f"token {settings['token']}", - "Content-Type": "application/json", - } - async with httpx.AsyncClient(timeout=30.0) as client: - # Ensure labels exist first - await _ensure_labels_exist(client, settings) + # Ensure labels exist first and get their IDs + label_ids = await _ensure_labels_exist(client, settings) + + issue_data = { + "title": title, + "body": body, + "labels": label_ids, + } + + url = f"{settings['url']}/api/v1/repos/{settings['owner']}/{settings['repo']}/issues" + headers = { + "Authorization": f"token {settings['token']}", + "Content-Type": "application/json", + } try: response = await client.post(url, headers=headers, json=issue_data) diff --git a/dump.rdb b/dump.rdb index 9d21003..7d06d0b 100644 Binary files a/dump.rdb and b/dump.rdb differ