Files
layue13 05f8fad38a
Gatekeep evals / eval-floor (push) Successful in 8s
Dogfood: run Gatekeep on this repo's PRs
Add .github/workflows/gatekeep-pr.yml with uses: ./ and
OPENROUTER_API_KEY from secrets. Forge-agnostic API helper for Gitea.
2026-10-26 20:40:51 +00:00

80 lines
2.5 KiB
Python

#!/usr/bin/env python3
"""
Minimal GitHub / Gitea API helper for Gatekeep (no gh CLI required).
Uses GITHUB_API_URL + GITHUB_TOKEN (Gitea Actions sets these to the forge).
"""
from __future__ import annotations
import json
import os
import sys
import urllib.error
import urllib.parse
import urllib.request
def api_base() -> str:
base = (os.environ.get("GITHUB_API_URL") or "https://api.github.com").rstrip("/")
return base
def is_gitea() -> bool:
b = api_base().lower()
return "api.github.com" not in b
def token() -> str:
return (
os.environ.get("GITHUB_TOKEN")
or os.environ.get("GITEA_TOKEN")
or os.environ.get("GH_TOKEN")
or ""
)
def request(method: str, path: str, body: dict | None = None, accept: str | None = None) -> tuple[int, str]:
path = path if path.startswith("/") else f"/{path}"
url = f"{api_base()}{path}"
data = None if body is None else json.dumps(body).encode("utf-8")
headers = {
"Authorization": f"token {token()}" if is_gitea() else f"Bearer {token()}",
"Accept": accept or ("application/json" if is_gitea() else "application/vnd.github+json"),
"User-Agent": "gatekeep-action",
}
if body is not None:
headers["Content-Type"] = "application/json"
# GitHub also accepts token prefix
if not is_gitea() and token():
headers["Authorization"] = f"Bearer {token()}"
req = urllib.request.Request(url, data=data, headers=headers, method=method.upper())
try:
with urllib.request.urlopen(req, timeout=120) as resp:
return resp.status, resp.read().decode("utf-8", errors="replace")
except urllib.error.HTTPError as e:
return e.code, e.read().decode("utf-8", errors="replace")
def request_json(method: str, path: str, body: dict | None = None):
code, text = request(method, path, body)
if code >= 400:
raise RuntimeError(f"{method} {path} → HTTP {code}: {text[:500]}")
if not text.strip():
return None
return json.loads(text)
def main(argv: list[str]) -> int:
"""CLI: forge_api.py METHOD PATH [json-body] → prints response body"""
if len(argv) < 3:
print("usage: forge_api.py METHOD /path [json-body]", file=sys.stderr)
return 2
method, path = argv[1], argv[2]
body = json.loads(argv[3]) if len(argv) > 3 else None
code, text = request(method, path, body)
sys.stdout.write(text)
return 0 if code < 400 else 1
if __name__ == "__main__":
raise SystemExit(main(sys.argv))