feat: bd-gitea sync
All checks were successful
Sync Beads to Gitea Issues / sync-beads (push) Successful in 2m9s
All checks were successful
Sync Beads to Gitea Issues / sync-beads (push) Successful in 2m9s
This commit is contained in:
parent
c3eb5f5c68
commit
d6124c3959
54
.gitea/sync_beads.py
Normal file
54
.gitea/sync_beads.py
Normal file
@ -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()
|
||||||
27
.gitea/workflows/beads-sync.yml
Normal file
27
.gitea/workflows/beads-sync.yml
Normal file
@ -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
|
||||||
Loading…
Reference in New Issue
Block a user