GitPasha MCP Server - Ready for deployment
هذا الالتزام موجود في:
15
api/__init__.py
Normal file
15
api/__init__.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from api.repos import api_create_repo, api_update_repo, api_delete_repo
|
||||
from api.issues import api_list_issues, api_create_issue, api_update_issue
|
||||
from api.files import api_create_readme
|
||||
from api.pulls import api_open_pr
|
||||
|
||||
__all__ = [
|
||||
"api_create_repo",
|
||||
"api_update_repo",
|
||||
"api_delete_repo",
|
||||
"api_list_issues",
|
||||
"api_create_issue",
|
||||
"api_update_issue",
|
||||
"api_create_readme",
|
||||
"api_open_pr",
|
||||
]
|
||||
5
api/files/__init__.py
Normal file
5
api/files/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from api.files.create_readme import api_create_readme
|
||||
|
||||
__all__ = [
|
||||
"api_create_readme"
|
||||
]
|
||||
37
api/files/create_readme.py
Normal file
37
api/files/create_readme.py
Normal file
@@ -0,0 +1,37 @@
|
||||
import os
|
||||
import base64
|
||||
from typing import Dict, Any
|
||||
from helpers import get_headers, build_client
|
||||
|
||||
USERNAME = os.getenv("GITPASHA__USERNAME", "")
|
||||
BASE_URL = os.getenv(
|
||||
"GITPASHA_BASE_URL",
|
||||
"https://app.gitpasha.com/api/v1"
|
||||
).rstrip("/")
|
||||
|
||||
|
||||
def api_create_readme(repo: str, content: str) -> Dict[str, Any]:
|
||||
if "/" not in repo:
|
||||
if not USERNAME:
|
||||
raise ValueError("GITPASHA__USERNAME not set in .env")
|
||||
repo = f"{USERNAME}/{repo}"
|
||||
|
||||
with build_client() as client:
|
||||
url = f"{BASE_URL}/repos/{repo}/contents/README.md"
|
||||
encoded = base64.b64encode(content.encode("utf-8")).decode("utf-8")
|
||||
body = {
|
||||
"message": "Add README",
|
||||
"content": encoded,
|
||||
}
|
||||
res = client.put(
|
||||
url,
|
||||
headers=get_headers(),
|
||||
json=body
|
||||
)
|
||||
|
||||
if res.status_code < 300:
|
||||
return res.json()
|
||||
return {
|
||||
"error": "Failed to create README",
|
||||
"response": res.text,
|
||||
}
|
||||
9
api/issues/__init__.py
Normal file
9
api/issues/__init__.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from api.issues.list import api_list_issues
|
||||
from api.issues.create import api_create_issue
|
||||
from api.issues.update import api_update_issue
|
||||
|
||||
__all__ = [
|
||||
"api_list_issues",
|
||||
"api_create_issue",
|
||||
"api_update_issue"
|
||||
]
|
||||
39
api/issues/create.py
Normal file
39
api/issues/create.py
Normal file
@@ -0,0 +1,39 @@
|
||||
import os
|
||||
from typing import Dict, Any, Optional, List
|
||||
from helpers import get_headers, build_client
|
||||
|
||||
BASE_URL = os.getenv(
|
||||
"GITPASHA_BASE_URL",
|
||||
"https://app.gitpasha.com/api/v1"
|
||||
).rstrip("/")
|
||||
|
||||
|
||||
def api_create_issue(
|
||||
repo: str,
|
||||
title: str,
|
||||
body: str = "",
|
||||
labels: Optional[List[str]] = None,
|
||||
assignees: Optional[List[str]] = None
|
||||
) -> Dict[str, Any]:
|
||||
username = os.getenv("GITPASHA__USERNAME", "")
|
||||
|
||||
if "/" not in repo:
|
||||
if not username:
|
||||
raise ValueError("GITPASHA__USERNAME not set in .env")
|
||||
repo = f"{username}/{repo}"
|
||||
|
||||
payload: Dict[str, Any] = {"title": title, "body": body}
|
||||
if labels:
|
||||
payload["labels"] = labels
|
||||
if assignees:
|
||||
payload["assignees"] = assignees
|
||||
with build_client() as client:
|
||||
url = f"{BASE_URL}/repos/{repo}/issues"
|
||||
res = client.post(
|
||||
url,
|
||||
headers=get_headers(),
|
||||
json=payload
|
||||
)
|
||||
res.raise_for_status()
|
||||
data = res.json()
|
||||
return data
|
||||
38
api/issues/list.py
Normal file
38
api/issues/list.py
Normal file
@@ -0,0 +1,38 @@
|
||||
import os
|
||||
from typing import List, Dict, Any, Optional
|
||||
from helpers import get_headers, build_client
|
||||
|
||||
|
||||
BASE_URL = os.getenv(
|
||||
"GITPASHA_BASE_URL",
|
||||
"https://app.gitpasha.com/api/v1"
|
||||
).rstrip("/")
|
||||
|
||||
|
||||
def api_list_issues(
|
||||
repo: str,
|
||||
state: Optional[str] = None
|
||||
) -> List[Dict[str, Any]]:
|
||||
username = os.getenv("GITPASHA__USERNAME", "")
|
||||
|
||||
if "/" not in repo:
|
||||
if not username:
|
||||
raise ValueError("GITPASHA__USERNAME not set in .env")
|
||||
repo = f"{username}/{repo}"
|
||||
|
||||
params = {}
|
||||
if state:
|
||||
params["state"] = state
|
||||
with build_client() as client:
|
||||
url = f"{BASE_URL}/repos/{repo}/issues"
|
||||
res = client.get(
|
||||
url,
|
||||
headers=get_headers(),
|
||||
params=params
|
||||
)
|
||||
res.raise_for_status()
|
||||
try:
|
||||
data = res.json()
|
||||
except Exception:
|
||||
data = []
|
||||
return data
|
||||
78
api/issues/update.py
Normal file
78
api/issues/update.py
Normal file
@@ -0,0 +1,78 @@
|
||||
import os
|
||||
from typing import Dict, Any, Optional, List
|
||||
from helpers import get_headers, build_client
|
||||
|
||||
BASE_URL = os.getenv(
|
||||
"GITPASHA_BASE_URL",
|
||||
"https://app.gitpasha.com/api/v1"
|
||||
).rstrip("/")
|
||||
|
||||
|
||||
def api_update_issue(
|
||||
repo: str,
|
||||
issue: str,
|
||||
title: Optional[str] = None,
|
||||
body: Optional[str] = None,
|
||||
state: Optional[str] = None,
|
||||
labels: Optional[List[str]] = None,
|
||||
assignees: Optional[List[str]] = None,
|
||||
comment: Optional[str] = None
|
||||
) -> Dict[str, Any]:
|
||||
repo = repo.strip()
|
||||
issue = issue.strip()
|
||||
|
||||
username = os.getenv("GITPASHA__USERNAME", "")
|
||||
|
||||
if "/" not in repo:
|
||||
if not username:
|
||||
raise ValueError("GITPASHA__USERNAME not set in .env")
|
||||
repo = f"{username}/{repo}"
|
||||
|
||||
out: Dict[str, Any] = {}
|
||||
with build_client() as client:
|
||||
patch_payload: Dict[str, Any] = {}
|
||||
if title is not None:
|
||||
patch_payload["title"] = title
|
||||
if body is not None:
|
||||
patch_payload["body"] = body
|
||||
if state is not None:
|
||||
patch_payload["state"] = state
|
||||
if labels is not None:
|
||||
patch_payload["labels"] = labels
|
||||
if assignees is not None:
|
||||
patch_payload["assignees"] = assignees
|
||||
|
||||
if patch_payload:
|
||||
url = f"{BASE_URL}/repos/{repo}/issues/{issue}"
|
||||
res = client.patch(
|
||||
url,
|
||||
headers=get_headers(),
|
||||
json=patch_payload
|
||||
)
|
||||
|
||||
if res.status_code == 405:
|
||||
res = client.put(
|
||||
url,
|
||||
headers=get_headers(),
|
||||
json=patch_payload
|
||||
)
|
||||
res.raise_for_status()
|
||||
out["update"] = res.json() if res.text else {"status": "ok"}
|
||||
|
||||
if comment:
|
||||
url_c = f"{BASE_URL}/repos/{repo}/issues/{issue}/comments"
|
||||
res_c = client.post(
|
||||
url_c,
|
||||
headers=get_headers(),
|
||||
json={
|
||||
"body": comment
|
||||
}
|
||||
)
|
||||
res_c.raise_for_status()
|
||||
out["comment"] = res_c.json() if res_c.text else {
|
||||
"status": "commented"
|
||||
}
|
||||
|
||||
return out or {
|
||||
"status": "no-op"
|
||||
}
|
||||
5
api/pulls/__init__.py
Normal file
5
api/pulls/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from api.pulls.open import api_open_pr
|
||||
|
||||
__all__ = [
|
||||
"api_open_pr"
|
||||
]
|
||||
39
api/pulls/open.py
Normal file
39
api/pulls/open.py
Normal file
@@ -0,0 +1,39 @@
|
||||
import os
|
||||
from typing import Dict, Any
|
||||
from helpers import get_headers, build_client
|
||||
|
||||
BASE_URL = os.getenv(
|
||||
"GITPASHA_BASE_URL",
|
||||
"https://app.gitpasha.com/api/v1"
|
||||
).rstrip("/")
|
||||
|
||||
|
||||
def api_open_pr(
|
||||
repo: str,
|
||||
title: str,
|
||||
head: str,
|
||||
base: str,
|
||||
body: str = ""
|
||||
) -> Dict[str, Any]:
|
||||
username = os.getenv("GITPASHA__USERNAME", "")
|
||||
|
||||
if "/" not in repo:
|
||||
if not username:
|
||||
raise ValueError("GITPASHA__USERNAME not set in .env")
|
||||
repo = f"{username}/{repo}"
|
||||
|
||||
payload = {
|
||||
"title": title,
|
||||
"head": head,
|
||||
"base": base,
|
||||
"body": body
|
||||
}
|
||||
with build_client() as client:
|
||||
url = f"{BASE_URL}/repos/{repo}/pulls"
|
||||
res = client.post(
|
||||
url,
|
||||
headers=get_headers(),
|
||||
json=payload
|
||||
)
|
||||
res.raise_for_status()
|
||||
return res.json()
|
||||
9
api/repos/__init__.py
Normal file
9
api/repos/__init__.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from api.repos.create import api_create_repo
|
||||
from api.repos.update import api_update_repo
|
||||
from api.repos.delete import api_delete_repo
|
||||
|
||||
__all__ = [
|
||||
"api_create_repo",
|
||||
"api_update_repo",
|
||||
"api_delete_repo"
|
||||
]
|
||||
30
api/repos/create.py
Normal file
30
api/repos/create.py
Normal file
@@ -0,0 +1,30 @@
|
||||
import os
|
||||
from typing import Dict, Any
|
||||
import httpx
|
||||
from helpers import get_headers, build_client
|
||||
|
||||
BASE_URL = os.getenv(
|
||||
"GITPASHA_BASE_URL",
|
||||
"https://app.gitpasha.com/api/v1"
|
||||
).rstrip("/")
|
||||
|
||||
|
||||
def api_create_repo(
|
||||
name: str,
|
||||
description: str,
|
||||
private: bool = False
|
||||
) -> Dict[str, Any]:
|
||||
payload = {
|
||||
"name": name,
|
||||
"description": description,
|
||||
"private": private
|
||||
}
|
||||
with build_client() as client:
|
||||
res = client.post(
|
||||
f"{BASE_URL}/user/repos",
|
||||
headers=get_headers(),
|
||||
json=payload,
|
||||
)
|
||||
res.raise_for_status()
|
||||
data = res.json()
|
||||
return data
|
||||
33
api/repos/delete.py
Normal file
33
api/repos/delete.py
Normal file
@@ -0,0 +1,33 @@
|
||||
import os
|
||||
from typing import Dict, Any
|
||||
from helpers import get_headers, build_client
|
||||
|
||||
BASE_URL = os.getenv(
|
||||
"GITPASHA_BASE_URL",
|
||||
"https://app.gitpasha.com/api/v1"
|
||||
).rstrip("/")
|
||||
|
||||
|
||||
def api_delete_repo(repo: str) -> Dict[str, Any]:
|
||||
repo = repo.strip()
|
||||
username = os.getenv("GITPASHA__USERNAME", "")
|
||||
|
||||
if "/" not in repo:
|
||||
if not username:
|
||||
raise ValueError("GITPASHA__USERNAME not set in .env")
|
||||
repo = f"{username}/{repo}"
|
||||
|
||||
with build_client() as client:
|
||||
url = f"{BASE_URL}/repos/{repo}"
|
||||
res = client.delete(url, headers=get_headers())
|
||||
|
||||
try:
|
||||
response_data = res.json() if res.text else {}
|
||||
except Exception:
|
||||
response_data = {}
|
||||
|
||||
if res.status_code in (200, 202, 204):
|
||||
return {"status": "deleted", **response_data}
|
||||
else:
|
||||
res.raise_for_status()
|
||||
return response_data or {"status": "deleted"}
|
||||
43
api/repos/update.py
Normal file
43
api/repos/update.py
Normal file
@@ -0,0 +1,43 @@
|
||||
import os
|
||||
from typing import Dict, Any, Optional
|
||||
from helpers import get_headers, build_client
|
||||
|
||||
BASE_URL = os.getenv(
|
||||
"GITPASHA_BASE_URL",
|
||||
"https://app.gitpasha.com/api/v1"
|
||||
).rstrip("/")
|
||||
|
||||
|
||||
def api_update_repo(
|
||||
repo: str,
|
||||
name: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
private: Optional[bool] = None
|
||||
) -> Dict[str, Any]:
|
||||
username = os.getenv("GITPASHA__USERNAME", "")
|
||||
|
||||
if "/" not in repo:
|
||||
if not username:
|
||||
raise ValueError("GITPASHA__USERNAME not set in .env")
|
||||
repo = f"{username}/{repo}"
|
||||
|
||||
payload: Dict[str, Any] = {}
|
||||
if name is not None:
|
||||
payload["name"] = name
|
||||
if description is not None:
|
||||
payload["description"] = description
|
||||
if private is not None:
|
||||
payload["private"] = bool(private)
|
||||
if not payload:
|
||||
raise ValueError("No fields to update")
|
||||
|
||||
with build_client() as client:
|
||||
url = f"{BASE_URL}/repos/{repo}"
|
||||
res = client.patch(url, headers=get_headers(), json=payload)
|
||||
if res.status_code == 405:
|
||||
res = client.put(url, headers=get_headers(), json=payload)
|
||||
res.raise_for_status()
|
||||
try:
|
||||
return res.json()
|
||||
except Exception:
|
||||
return {"status": "ok"}
|
||||
المرجع في مشكلة جديدة
حظر مستخدم