diff --git a/.gitea/sync_beads.py b/.gitea/sync_beads.py new file mode 100644 index 0000000..c7c0e70 --- /dev/null +++ b/.gitea/sync_beads.py @@ -0,0 +1,54 @@ +import json +import os +import requests + +# Configuration +TOKEN = os.getenv("GITEA_TOKEN") +URL = os.getenv("GITEA_URL") +REPO = os.getenv("REPO_NAME") +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(): + beads_file = ".beads/issues.jsonl" + if not os.path.exists(beads_file): + print("No beads found.") + return + + gitea_issues = get_gitea_issues() + + with open(beads_file, "r") as f: + 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 = { + "title": f"[{bid}] {title}", + "body": f"{desc}\n\n---\n**Beads ID:** `{bid}`\n**Priority:** {data.get('priority', 'N/A')}", + "state": target_state + } + + if bid in gitea_issues: + # Update existing issue if state or title changed + issue_number = gitea_issues[bid]['number'] + print(f"Updating Issue #{issue_number} ({bid})") + requests.patch(f"{URL}/api/v1/repos/{REPO}/issues/{issue_number}", headers=HEADERS, json=payload) + else: + # Create new issue + print(f"Creating New Issue for {bid}") + requests.post(f"{URL}/api/v1/repos/{REPO}/issues", headers=HEADERS, json=payload) + +if __name__ == "__main__": + sync() diff --git a/.gitea/workflows/beads-sync.yml b/.gitea/workflows/beads-sync.yml new file mode 100644 index 0000000..3e0dd0f --- /dev/null +++ b/.gitea/workflows/beads-sync.yml @@ -0,0 +1,27 @@ +name: Sync Beads to Gitea Issues +on: + push: + branches: + - main # Adjust if your default branch is different + +jobs: + sync-beads: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.x" + + - name: Install dependencies + run: pip install requests + + - name: Run Sync Script + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + GITEA_URL: ${{ github.server_url }} + REPO_NAME: ${{ github.repository }} + run: python .gitea/sync_beads.py