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.
112 lines
4.2 KiB
Markdown
112 lines
4.2 KiB
Markdown
# 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
|
|
|
|
```python
|
|
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
|
|
|
|
```python
|
|
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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
1. **NEVER hardcode `UniqueSoft/APAW`** - always use `get_target_repo()`
|
|
2. **Issues belong in the target project** - the project being worked on
|
|
3. **APAW is the agent framework** - not the default target for all issues
|
|
4. **Use `GITEA_TARGET_REPO` env var** for explicit override when needed |