The regex r'[:/]([^/]+/[^/]+?)(?:\.git)?$' fails on URLs with trailing slashes like 'https://git.softuniq.eu/UniqueSoft/APAW/' because the final '/' breaks the pattern. Added .rstrip('/') in Python and sed 's:/*' in Bash to all get_target_repo() implementations across 11 files.
4.2 KiB
4.2 KiB
Gitea API Client (Shared)
Common Gitea API functions for issue comments, checkbox updates, and issue management.
IMPORTANT: Target Project Resolution
NEVER hardcode UniqueSoft/APAW in API calls. Always detect the target project from git remote.
How to Detect Target Project
import re, subprocess
def get_target_repo():
"""Detect target project from git remote - NEVER hardcode"""
result = subprocess.run(
['git', 'remote', 'get-url', 'origin'],
capture_output=True, text=True
)
remote_url = result.stdout.strip().rstrip('/')
# HTTPS: https://git.softuniq.eu/Owner/Repo.git
# SSH: git@git.softuniq.eu:Owner/Repo.git
match = re.search(r'[:/]([^/]+/[^/]+?)(?:\.git)?$', remote_url)
if match:
return match.group(1)
# Fallback: use env var or default
return os.environ.get('GITEA_TARGET_REPO', 'UniqueSoft/APAW')
Python Client
import urllib.request, json, base64, os, re, subprocess
def gitea_api(path, data=None, method='GET', repo=None):
"""Call Gitea API. Uses get_gitea_token() from gitea-auth.md. Auto-detects target repo."""
target_repo = repo or get_target_repo()
token = get_gitea_token() # From .kilo/shared/gitea-auth.md
url = f"{os.environ.get('GITEA_API_URL', 'https://git.softuniq.eu/api/v1')}/repos/{target_repo}{path}"
headers = {'Content-Type': 'application/json', 'Authorization': f'token {token}'}
req = urllib.request.Request(url, data=json.dumps(data).encode() if data else None,
headers=headers, method=method)
with urllib.request.urlopen(req) as r: return json.loads(r.read())
def get_target_repo():
"""Detect target project from git remote - NEVER hardcode"""
try:
result = subprocess.run(
['git', 'remote', 'get-url', 'origin'],
capture_output=True, text=True
)
remote_url = result.stdout.strip().rstrip('/')
match = re.search(r'[:/]([^/]+/[^/]+?)(?:\.git)?$', remote_url)
if match:
return match.group(1)
except Exception:
pass
return os.environ.get('GITEA_TARGET_REPO', 'UniqueSoft/APAW')
def post_gitea_comment(issue_number, body, repo=None):
"""Post comment to Gitea issue in the correct project."""
target_repo = repo or get_target_repo()
return gitea_api(f"/issues/{issue_number}/comments", {"body": body}, 'POST', target_repo)
def update_issue_checkboxes(issue_number, repo=None):
"""Mark all checkboxes as done and close issue."""
target_repo = repo or get_target_repo()
import re
issue = gitea_api(f"/issues/{issue_number}", repo=target_repo)
body = issue['body']
body = re.sub(r'- \[ \] ', '- [x] ', body)
body = re.sub(r'\* \[ \] ', '* [x] ', body)
gitea_api(f"/issues/{issue_number}", {"body": body, "state": "closed"}, 'PATCH', target_repo)
def close_issue(issue_number, repo=None):
"""Close a Gitea issue in the correct project."""
target_repo = repo or get_target_repo()
gitea_api(f"/issues/{issue_number}", {"state": "closed"}, 'PATCH', target_repo)
def create_issue(title, body, labels=None, repo=None):
"""Create a Gitea issue in the correct project."""
target_repo = repo or get_target_repo()
return gitea_api("/issues", {"title": title, "body": body, "labels": labels or []}, 'POST', target_repo)
Bash Client
# Auto-detect target repo
TARGET_REPO=$(git remote get-url origin | sed 's:/*$::' | sed -E 's|.*[:/]([^/]+/[^/]+?)(\.git)?$|\1|')
# Post comment
curl -X POST -H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"body":"comment body"}' \
"https://git.softuniq.eu/api/v1/repos/${TARGET_REPO}/issues/{issue_number}/comments"
# Create issue
curl -X POST -H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"title":"Issue title","body":"Issue body"}' \
"https://git.softuniq.eu/api/v1/repos/${TARGET_REPO}/issues"
CRITICAL REMINDERS
- NEVER hardcode
UniqueSoft/APAW- always useget_target_repo() - Issues belong in the target project - the project being worked on
- APAW is the agent framework - not the default target for all issues
- Use
GITEA_TARGET_REPOenv var for explicit override when needed