Spaces:
Sleeping
Sleeping
| import os | |
| import json | |
| import subprocess | |
| from pathlib import Path | |
| # Base directory of the project | |
| BASE_DIR = Path(__file__).resolve().parents[1] | |
| STATE_FILE = BASE_DIR / "issue_tracker_state.json" | |
| TEMPLATE_FILE = BASE_DIR / "templates" / "owner_reply.txt" | |
| REPO = "ritesh-1918/HELPDESK.AI" | |
| # Load or initialize state | |
| if STATE_FILE.exists(): | |
| with open(STATE_FILE, "r", encoding="utf-8") as f: | |
| state = json.load(f) | |
| else: | |
| state = {"processed_items": {}} | |
| def run_gh(args): | |
| """Run a gh CLI command. | |
| Returns stdout string on success, None on failure. | |
| """ | |
| try: | |
| result = subprocess.run(["gh"] + args, capture_output=True, text=True, check=False) | |
| except Exception as e: | |
| print(f"[ERROR] Exception while running gh: {e}") | |
| return None | |
| if result.returncode != 0: | |
| print(f"[ERROR] gh {' '.join(args)} failed (code {result.returncode}):\n{result.stderr}") | |
| return None | |
| return result.stdout.strip() | |
| def fetch_issues(): | |
| out = run_gh(["issue", "list", "--repo", REPO, "--json", "number,title,labels,state,updatedAt"]) | |
| return json.loads(out) if out else [] | |
| def fetch_prs(): | |
| out = run_gh(["pr", "list", "--repo", REPO, "--json", "number,title,labels,state,updatedAt"]) | |
| return json.loads(out) if out else [] | |
| def view_issue(num): | |
| out = run_gh(["issue", "view", str(num), "--repo", REPO, "--json", "number,title,body,author,labels,comments,updatedAt"]) | |
| return json.loads(out) if out else None | |
| def view_pr(num): | |
| out = run_gh(["pr", "view", str(num), "--repo", REPO, "--json", "number,title,body,author,labels,comments,updatedAt"]) | |
| return json.loads(out) if out else None | |
| def determine_labels(item): | |
| title = item.get("title", "").lower() | |
| existing = set(label["name"] for label in item.get("labels", [])) | |
| # Simple keyword based heuristics | |
| if "bug" in title: | |
| existing.add("bug") | |
| if "feature" in title or "enhancement" in title: | |
| existing.add("enhancement") | |
| # Always tag with gssoc for tracking | |
| existing.add("gssoc") | |
| return list(existing) | |
| def ensure_labels(item_type, number, desired_labels): | |
| for label in desired_labels: | |
| run_gh([item_type, "edit", str(number), "--repo", REPO, "--add-label", label]) | |
| def load_template(): | |
| if TEMPLATE_FILE.exists(): | |
| return TEMPLATE_FILE.read_text(encoding="utf-8") | |
| # Fallback simple template | |
| return ( | |
| "Hi @{author},\n\n" | |
| "Thank you for your contribution! 🙌\n" | |
| "We appreciate your effort and encourage you to continue working on the `gssoc` branch.\n" | |
| "If you are new, please follow the onboarding steps: sign‑up, select *Ritesh Private Limited*, verify email, request access via an issue, and wait for approval.\n" | |
| "Feel free to ask any questions. 🚀\n\n" | |
| "Best,\nRitesh" | |
| ) | |
| def post_comment(item_type, number, body): | |
| run_gh([item_type, "comment", str(number), "--repo", REPO, "--body", body]) | |
| def process_item(item_type, item): | |
| number = item["number"] | |
| key = f"{item_type}:{number}" | |
| last_updated = item.get("updatedAt") | |
| if state["processed_items"].get(key) == last_updated: | |
| return # No changes since last run | |
| full = view_issue(number) if item_type == "issue" else view_pr(number) | |
| if not full: | |
| print(f"[WARN] Could not fetch full details for {item_type} #{number}. Skipping.") | |
| return | |
| desired = determine_labels(full) | |
| ensure_labels(item_type, number, desired) | |
| template = load_template() | |
| reply = template.replace("{title}", full.get("title", "")) | |
| reply = reply.replace("{author}", full.get("author", {}).get("login", "contributor")) | |
| post_comment(item_type, number, reply) | |
| state["processed_items"][key] = last_updated | |
| def main(): | |
| issues = fetch_issues() | |
| prs = fetch_prs() | |
| for issue in issues: | |
| process_item("issue", issue) | |
| for pr in prs: | |
| process_item("pr", pr) | |
| # Save updated state | |
| with open(STATE_FILE, "w", encoding="utf-8") as f: | |
| json.dump(state, f, indent=2) | |
| if __name__ == "__main__": | |
| main() | |