fix: beads-gitea sync
All checks were successful
Sync Beads to Gitea Issues / sync-beads (push) Successful in 7s

This commit is contained in:
Rootiest 2026-01-19 19:42:19 -05:00
parent d6124c3959
commit e77c98c674
Signed by: rootiest
GPG Key ID: 623CE33E5CF323D5

View File

@ -1,54 +1,56 @@
import json import json
import os import os
import requests import requests
import sys
# Configuration
TOKEN = os.getenv("GITEA_TOKEN") TOKEN = os.getenv("GITEA_TOKEN")
URL = os.getenv("GITEA_URL") URL = os.getenv("GITEA_URL")
REPO = os.getenv("REPO_NAME") REPO = os.getenv("REPO_NAME")
HEADERS = {"Authorization": f"token {TOKEN}", "Content-Type": "application/json"} HEADERS = {"Authorization": f"token {TOKEN}", "Content-Type": "application/json"}
def get_gitea_issues():
"""Fetch all issues from Gitea to map by their Beads ID."""
url = f"{URL}/api/v1/repos/{REPO}/issues?state=all"
resp = requests.get(url, headers=HEADERS)
resp.raise_for_status()
# We store the Beads ID in the title or a hidden comment to track them
return {issue['title'].split(']')[0][1:]: issue for issue in resp.json() if ']' in issue['title']}
def sync(): def sync():
beads_file = ".beads/issues.jsonl" # Your ls shows 'issues.jsonl' exists
if not os.path.exists(beads_file): beads_path = ".beads/issues.jsonl"
print("No beads found.")
return
gitea_issues = get_gitea_issues() if not os.path.exists(beads_path):
print(f"❌ ERROR: {beads_path} not found.")
# Print directory to debug what the Action user sees
print(f"Directory Contents: {os.listdir('.beads/') if os.path.exists('.beads') else 'None'}")
sys.exit(1)
with open(beads_file, "r") as f: print(f"🔍 Reading Beads from: {beads_path}")
for line in f:
data = json.loads(line)
bid = data.get("id")
title = data.get("title")
desc = data.get("description", "")
# Mapping Beads status to Gitea states
is_closed = data.get("status") in ["closed", "done", "finished"]
target_state = "closed" if is_closed else "open"
payload = { try:
"title": f"[{bid}] {title}", # Fetch existing Gitea issues
"body": f"{desc}\n\n---\n**Beads ID:** `{bid}`\n**Priority:** {data.get('priority', 'N/A')}", resp = requests.get(f"{URL}/api/v1/repos/{REPO}/issues?state=all", headers=HEADERS)
"state": target_state resp.raise_for_status()
} existing = {i['title'].split(']')[0][1:]: i for i in resp.json() if ']' in i['title']}
if bid in gitea_issues: with open(beads_path, "r") as f:
# Update existing issue if state or title changed for line in f:
issue_number = gitea_issues[bid]['number'] if not line.strip(): continue
print(f"Updating Issue #{issue_number} ({bid})") data = json.loads(line)
requests.patch(f"{URL}/api/v1/repos/{REPO}/issues/{issue_number}", headers=HEADERS, json=payload) bid, title = data.get("id"), data.get("title")
else:
# Create new issue payload = {
print(f"Creating New Issue for {bid}") "title": f"[{bid}] {title}",
requests.post(f"{URL}/api/v1/repos/{REPO}/issues", headers=HEADERS, json=payload) "body": f"{data.get('description', 'No description')}\n\n---\n**Beads ID:** `{bid}`",
"state": "closed" if data.get("status") in ["closed", "done"] else "open"
}
if bid in existing:
print(f"✅ Updating: {bid}")
requests.patch(f"{URL}/api/v1/repos/{REPO}/issues/{existing[bid]['number']}", headers=HEADERS, json=payload)
else:
print(f" Creating: {bid}")
requests.post(f"{URL}/api/v1/repos/{REPO}/issues", headers=HEADERS, json=payload)
except PermissionError:
print(f"❌ PERMISSION DENIED: Action user cannot read {beads_path}. Run 'chmod 644 {beads_path}' locally.")
sys.exit(1)
except Exception as e:
print(f"❌ ERROR: {e}")
sys.exit(1)
if __name__ == "__main__": if __name__ == "__main__":
sync() sync()