Skip to content

Commit

Permalink
refactor(install): Refactor GitHub App Installation Logic
Browse files Browse the repository at this point in the history
  • Loading branch information
xingwanying committed Dec 9, 2024
1 parent d1465b9 commit 57291dd
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 94 deletions.
130 changes: 79 additions & 51 deletions server/core/dao/repositoryConfigDAO.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from core.models.bot import RepoBindBotConfigVO
from core.models.repository import RepositoryConfig
from supabase.client import Client

from petercat_utils.db.client.supabase import get_client


Expand All @@ -26,65 +25,94 @@ def create(self, data: RepositoryConfig):
else:
return False, {"message": "GithubRepoConfig creation failed"}
except Exception as e:
print("Error: ", e)
return False, {"message": "GithubRepoConfig creation failed"}

def query_by_owners(self, orgs: list[str]):
response = (
self.client.table("github_repo_config")
.select("*")
.filter("owner_id", "in", f"({','.join(map(str, orgs))})")
.execute()
)
print(f"Error: {e}")
return False, {"message": f"GithubRepoConfig creation failed: {e}"}

return response.data
def create_batch(self, data_list: List[RepositoryConfig]):
try:
records_data = [data.model_dump(exclude=["id"]) for data in data_list]
repo_config = (
self.client.from_("github_repo_config").insert(records_data).execute()
)
if repo_config:
return True, {
"message": "GithubRepoConfig records created successfully"
}
else:
return False, {"message": "GithubRepoConfig batch creation failed"}
except Exception as e:
print(f"Error: {e}")
return False, {"message": f"GithubRepoConfig batch creation failed: {e}"}

def update_bot_to_repos(
self,
repos: List[RepoBindBotConfigVO],
) -> bool:
for repo in repos:
res = (
def query_by_owners(self, orgs: List[str]):
try:
response = (
self.client.table("github_repo_config")
.update({"robot_id": repo.robot_id})
.match({"repo_id": repo.repo_id})
.select("*")
.filter("owner_id", "in", f"({','.join(map(str, orgs))})")
.execute()
)
if not res:
raise ValueError("Failed to bind the bot.")
return response.data
except Exception as e:
print(f"Error: {e}")
return None

def get_by_repo_name(self, repo_name: str):
response = (
self.client.table("github_repo_config")
.select("*")
.eq("repo_name", repo_name)
.execute()
)
def update_bot_to_repos(self, repos: List[RepoBindBotConfigVO]) -> bool:
try:
for repo in repos:
res = (
self.client.table("github_repo_config")
.update({"robot_id": repo.robot_id})
.match({"repo_id": repo.repo_id})
.execute()
)
if not res:
raise ValueError("Failed to bind the bot.")
return True
except Exception as e:
print(f"Error: {e}")
return False

if not response.data or not response.data[0]:
def get_by_repo_name(self, repo_name: str):
try:
response = (
self.client.table("github_repo_config")
.select("*")
.eq("repo_name", repo_name)
.execute()
)
if not response.data or not response.data[0]:
return None
repo_config = response.data[0]
return RepositoryConfig(**repo_config)
except Exception as e:
print(f"Error: {e}")
return None
repo_config = response.data[0]

return RepositoryConfig(**repo_config)

def get_by_bot_id(self, bot_id: str):
response = (
self.client.table("github_repo_config")
.select("*")
.eq("robot_id", bot_id)
.execute()
)
if not response.data or not response.data[0]:
try:
response = (
self.client.table("github_repo_config")
.select("*")
.eq("robot_id", bot_id)
.execute()
)
if not response.data or not response.data[0]:
return None
return [RepositoryConfig(**repo) for repo in response.data]
except Exception as e:
print(f"Error: {e}")
return None
repo_configs = [RepositoryConfig(**repo) for repo in response.data]

return repo_configs

def delete_by_repo_ids(self, repo_ids: list):
response = (
self.client.table("github_repo_config")
.delete()
.in_("repo_id", repo_ids)
.execute()
)
return response
def delete_by_repo_ids(self, repo_ids: List[str]):
try:
response = (
self.client.table("github_repo_config")
.delete()
.in_("repo_id", repo_ids)
.execute()
)
return response
except Exception as e:
print(f"Error: {e}")
return None
23 changes: 22 additions & 1 deletion server/event_handler/intsall.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from typing import Any
from typing import Any, List
from github import Github, Auth
from github import GithubException
from core.dao.repositoryConfigDAO import RepositoryConfigDAO
from core.models.repository import RepositoryConfig
import time


class InstallEventHandler:
Expand All @@ -20,12 +22,31 @@ def delete_config(self):
repository_config = RepositoryConfigDAO()
repository_config.delete_by_repo_ids(repo_ids)

def add_config(self):
repositories = self.event["repositories"]
owner_id = self.event["installation"]["account"]["id"]
repository_config_dao = RepositoryConfigDAO()
repository_configs: List[RepositoryConfig] = []
for repo in repositories:
repository_config = RepositoryConfig(
owner_id=str(owner_id),
repo_name=repo["full_name"],
repo_id=str(repo["id"]),
robot_id="",
created_at=int(time.time()),
)
repository_configs.append(repository_config)
repository_config_dao.create_batch(repository_configs)

async def execute(self):
try:
action = self.event["action"]
if action == "deleted":
self.delete_config()
return {"success": True}
if action == "created":
self.add_config()
return {"success": True}
except GithubException as e:
print(f"处理 GitHub 请求时出错:{e}")
return {"success": False, "error": str(e)}
46 changes: 4 additions & 42 deletions server/github_app/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,48 +50,10 @@
# https://github.com/login/oauth/authorize?client_id=Iv1.c2e88b429e541264
@router.get("/app/installation/callback")
def github_app_callback(code: str, installation_id: str, setup_action: str):
authorization_dao = AuthorizationDAO()
repository_config_dao = RepositoryConfigDAO()
if setup_action == "install":
if authorization_dao.exists(installation_id=installation_id):
message = (f"Installation_id {installation_id} Exists",)
return RedirectResponse(
url=f"{WEB_URL}/github/installed/{message}", status_code=302
)
else:
jwt = get_jwt()
access_token = get_app_installations_access_token(
installation_id=installation_id, jwt=jwt
)
print(f"get_app_installations_access_token: {access_token}")
authorization = Authorization(
**access_token,
code=code,
installation_id=installation_id,
created_at=int(time.time()),
)
success, message = authorization_dao.create(authorization)
installed_repositories = get_installation_repositories(
access_token=access_token["token"]
)
for repo in installed_repositories["repositories"]:
repository_config = RepositoryConfig(
owner_id=str(repo["owner"]["id"]),
repo_name=repo["full_name"],
repo_id=str(repo["id"]),
robot_id="",
created_at=int(time.time()),
)
repository_config_dao.create(repository_config)

return RedirectResponse(
url=f"{WEB_URL}/github/installed?message={message}", status_code=302
)
# ignore others setup_action,such as deleted our app
return {
"success": False,
"message": f"Invalid setup_action value {setup_action},please delete the app first then re-install the app.",
}
return RedirectResponse(
url=f"{WEB_URL}/github/installed?installation_id={installation_id}&setup_action={setup_action}&code={code}",
status_code=302,
)


@router.post("/app/webhook")
Expand Down

0 comments on commit 57291dd

Please sign in to comment.