| import os | |
| import base64 | |
| from typing import Optional | |
| try: | |
| from github import Github, GithubException | |
| LIBS_OK = True | |
| except ImportError: | |
| LIBS_OK = False | |
| class GitHubLogger: | |
| """Dedicated logger that appends JSONL entries to a GitHub repo/branch/file. | |
| Env vars: | |
| - LOG_GITHUB_TOKEN (fallback: GITHUB_TOKEN) | |
| - LOG_REPO (format: owner/repo) | |
| - LOG_BRANCH (default: 'log_event') | |
| - LOG_FILE_PATH (default: 'pr_success.log') | |
| """ | |
| def __init__(self): | |
| if not LIBS_OK: | |
| raise ImportError("PyGithub not installed. Please install PyGithub.") | |
| token = os.environ.get("LOG_GITHUB_TOKEN") or os.environ.get("GITHUB_TOKEN") | |
| if not token: | |
| raise ValueError("Missing LOG_GITHUB_TOKEN or GITHUB_TOKEN for logging") | |
| self._client = Github(token) | |
| repo_spec = os.environ.get("LOG_REPO") | |
| if not repo_spec or "/" not in repo_spec: | |
| raise ValueError("Missing or invalid LOG_REPO. Expected 'owner/repo'.") | |
| self.owner, self.repo_name = repo_spec.split("/", 1) | |
| self.branch = os.environ.get("LOG_BRANCH", "log_event") | |
| self.path = os.environ.get("LOG_FILE_PATH", "pr_success.log") | |
| def _ensure_branch(self, repo): | |
| try: | |
| repo.get_branch(self.branch) | |
| except GithubException as e: | |
| if e.status == 404: | |
| base = repo.get_branch(repo.default_branch) | |
| repo.create_git_ref(ref=f"refs/heads/{self.branch}", sha=base.commit.sha) | |
| else: | |
| raise | |
| def append_jsonl(self, jsonl_line: str, commit_message: str = "chore(log): append entry") -> str: | |
| repo = self._client.get_repo(f"{self.owner}/{self.repo_name}") | |
| self._ensure_branch(repo) | |
| try: | |
| existing = repo.get_contents(self.path, ref=self.branch) | |
| existing_content = base64.b64decode(existing.content).decode("utf-8") | |
| new_content = existing_content + jsonl_line | |
| repo.update_file( | |
| path=self.path, | |
| message=commit_message, | |
| content=new_content, | |
| sha=existing.sha, | |
| branch=self.branch, | |
| ) | |
| return "SUCCESS: Log appended" | |
| except GithubException as e: | |
| if e.status == 404: | |
| repo.create_file( | |
| path=self.path, | |
| message=commit_message, | |
| content=jsonl_line, | |
| branch=self.branch, | |
| ) | |
| return "SUCCESS: Log file created and first entry appended" | |
| raise | |