-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathsentinel_github.py
More file actions
94 lines (74 loc) · 3.44 KB
/
Copy pathsentinel_github.py
File metadata and controls
94 lines (74 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/usr/bin/env python3
"""
Wrapper Python pour l'API GitHub (SentinelOS)
Permet aux agents de gérer issues, milestones, et PRs.
"""
import os
import requests
from typing import List, Dict, Optional
# Configuration
GITHUB_API_URL = "https://api.github.com"
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN", "your_token_here") # À configurer dans .env
HEADERS = {
"Authorization": f"token {GITHUB_TOKEN}",
"Accept": "application/vnd.github.v3+json"
}
class GitHubWrapper:
"""Wrapper pour l'API GitHub."""
def __init__(self, repo: str):
self.repo = repo # Format : "bahira/SentinelOS"
def _request(self, method: str, endpoint: str, data: Optional[Dict] = None) -> Dict:
"""Effectuer une requête API."""
url = f"{GITHUB_API_URL}/repos/{self.repo}{endpoint}"
response = requests.request(method, url, headers=HEADERS, json=data)
response.raise_for_status()
return response.json()
def create_issue(self, title: str, body: str, labels: List[str] = None) -> Dict:
"""Créer une issue."""
data = {"title": title, "body": body, "labels": labels or []}
return self._request("POST", "/issues", data)
def close_issue(self, issue_number: int) -> Dict:
"""Fermer une issue."""
return self._request("PATCH", f"/issues/{issue_number}", {"state": "closed"})
def add_comment(self, issue_number: int, body: str) -> Dict:
"""Ajouter un commentaire à une issue."""
return self._request("POST", f"/issues/{issue_number}/comments", {"body": body})
def list_issues(self, state: str = "open", labels: List[str] = None) -> List[Dict]:
"""Lister les issues (filtrées par état et labels)."""
params = {"state": state}
if labels:
params["labels"] = ",".join(labels)
return self._request("GET", "/issues", params)
def create_milestone(self, title: str, description: str = "", due_on: str = None) -> Dict:
"""Créer un milestone."""
data = {"title": title, "description": description}
if due_on:
data["due_on"] = due_on
return self._request("POST", "/milestones", data)
def list_milestones(self, state: str = "open") -> List[Dict]:
"""Lister les milestones."""
return self._request("GET", "/milestones", {"state": state})
# Tests unitaires
if __name__ == "__main__":
import unittest
from unittest.mock import patch, MagicMock
class TestGitHubWrapper(unittest.TestCase):
def setUp(self):
self.wrapper = GitHubWrapper("bahira/SentinelOS")
@patch('requests.request')
def test_create_issue(self, mock_request):
mock_response = MagicMock()
mock_response.json.return_value = {"number": 1, "title": "Test Issue"}
mock_response.raise_for_status.return_value = None
mock_request.return_value = mock_response
result = self.wrapper.create_issue("Test Issue", "Body", ["bug"])
self.assertEqual(result["title"], "Test Issue")
mock_request.assert_called_once()
@patch('requests.request')
def test_close_issue(self, mock_request):
mock_response = MagicMock()
mock_response.json.return_value = {"number": 1, "state": "closed"}
mock_request.return_value = mock_response
result = self.wrapper.close_issue(1)
self.assertEqual(result["state"], "closed")
unittest.main()