feat: issues & archive
This commit is contained in:
parent
a0e9c6808a
commit
0adc5a54cd
|
@ -29,8 +29,8 @@ pytest -svv
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- [ ] retreive the hw/project releases for all students
|
- [ ] retreive the hw/project releases for all students
|
||||||
- [ ] open "bulk issues" to report something wrong
|
- [x] open "bulk issues" to report something wrong
|
||||||
- [x] collect all the public keys
|
- [x] collect all the public keys
|
||||||
- [x] import groups (create teams)
|
- [x] import groups (create teams)
|
||||||
- [x] create repos
|
- [x] create repos
|
||||||
- [ ] archive all repos of a course
|
- [x] archive all repos of a course
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
from joint_teapot.canvas import Canvas as Canvas
|
from joint_teapot.canvas import Canvas as Canvas
|
||||||
from joint_teapot.git import Git as Git
|
from joint_teapot.git import Git as Git
|
||||||
from joint_teapot.gitea import Gitea as Gitea
|
from joint_teapot.gitea import Gitea as Gitea
|
||||||
|
from joint_teapot.teapot import Teapot as Teapot
|
||||||
|
|
|
@ -1,13 +1 @@
|
||||||
from joint_teapot import Canvas, Gitea
|
|
||||||
|
|
||||||
__version__ = "0.0.0"
|
__version__ = "0.0.0"
|
||||||
|
|
||||||
|
|
||||||
class Teapot:
|
|
||||||
def __init__(self) -> None:
|
|
||||||
self.canvas = Canvas()
|
|
||||||
self.gitea = Gitea()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
teapot = Teapot()
|
|
||||||
|
|
|
@ -22,6 +22,9 @@ class Settings(BaseSettings):
|
||||||
gitea_access_token: str = ""
|
gitea_access_token: str = ""
|
||||||
org_name: str = ""
|
org_name: str = ""
|
||||||
|
|
||||||
|
# git
|
||||||
|
repos_dir: str = ""
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
env_file = ".env"
|
env_file = ".env"
|
||||||
env_file_encoding = "utf-8"
|
env_file_encoding = "utf-8"
|
||||||
|
|
|
@ -6,24 +6,30 @@ from joint_teapot.config import settings
|
||||||
|
|
||||||
|
|
||||||
class Git:
|
class Git:
|
||||||
def __init__(self, org_name: str = settings.org_name, repos_dir: str = ""):
|
def __init__(
|
||||||
|
self, org_name: str = settings.org_name, repos_dir: str = settings.repos_dir
|
||||||
|
):
|
||||||
self.org_name = org_name
|
self.org_name = org_name
|
||||||
if not os.path.isdir(repos_dir):
|
if not os.path.isdir(repos_dir):
|
||||||
raise Exception(f"{repos_dir} does not exist! Create it first.")
|
raise Exception(f"{repos_dir} does not exist! Create it first.")
|
||||||
self.repos_dir = repos_dir
|
self.repos_dir = repos_dir
|
||||||
|
|
||||||
def __get_repo(self, repo_name: str) -> git.Repo:
|
def clone_repo(self, repo_name: str) -> git.Repo:
|
||||||
repo_dir = os.path.join(self.repos_dir, repo_name)
|
repo_dir = os.path.join(self.repos_dir, repo_name)
|
||||||
if os.path.exists(repo_dir):
|
|
||||||
return git.Repo(repo_dir)
|
|
||||||
return git.Repo.clone_from(
|
return git.Repo.clone_from(
|
||||||
f"https://focs.ji.sjtu.edu.cn/git/{self.org_name}/{repo_name}",
|
f"https://focs.ji.sjtu.edu.cn/git/{self.org_name}/{repo_name}",
|
||||||
repo_dir,
|
repo_dir,
|
||||||
branch="master",
|
branch="master",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_repo(self, repo_name: str) -> git.Repo:
|
||||||
|
repo_dir = os.path.join(self.repos_dir, repo_name)
|
||||||
|
if os.path.exists(repo_dir):
|
||||||
|
return git.Repo(repo_dir)
|
||||||
|
return self.clone_repo(repo_dir)
|
||||||
|
|
||||||
def repo_clean_and_checkout(self, repo_name: str, checkout_dest: str) -> str:
|
def repo_clean_and_checkout(self, repo_name: str, checkout_dest: str) -> str:
|
||||||
repo = self.__get_repo(repo_name)
|
repo = self.get_repo(repo_name)
|
||||||
repo.git.fetch("--tags", "--all", "-f")
|
repo.git.fetch("--tags", "--all", "-f")
|
||||||
repo.git.reset("--hard", f"origin/master")
|
repo.git.reset("--hard", f"origin/master")
|
||||||
repo.git.clean("-d", "-f", "-x")
|
repo.git.clean("-d", "-f", "-x")
|
||||||
|
|
|
@ -140,7 +140,7 @@ class Gitea:
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
self.organization_api.org_add_team_repository(
|
self.organization_api.org_add_team_repository(
|
||||||
team["id"], self.org_name, repo["name"]
|
team["id"], self.org_name, repo_name
|
||||||
)
|
)
|
||||||
membership: GroupMembership
|
membership: GroupMembership
|
||||||
for membership in group.get_memberships():
|
for membership in group.get_memberships():
|
||||||
|
@ -149,12 +149,14 @@ class Gitea:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
f"student with user_id {membership.user_id} not found"
|
f"student with user_id {membership.user_id} not found"
|
||||||
)
|
)
|
||||||
self.organization_api.org_add_team_member(
|
username = self.__get_username_by_canvas_student(student)
|
||||||
team["id"], self.__get_username_by_canvas_student(student)
|
self.organization_api.org_add_team_member(team["id"])
|
||||||
|
self.repository_api.repo_add_collaborator(
|
||||||
|
self.org_name, repo_name, username
|
||||||
)
|
)
|
||||||
return repo_names
|
return repo_names
|
||||||
|
|
||||||
def get_public_key_of_students(
|
def get_public_key_of_canvas_students(
|
||||||
self, students: PaginatedList
|
self, students: PaginatedList
|
||||||
) -> List[List[Dict[str, Any]]]:
|
) -> List[List[Dict[str, Any]]]:
|
||||||
return [
|
return [
|
||||||
|
@ -162,6 +164,38 @@ class Gitea:
|
||||||
for student in students
|
for student in students
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def get_repos_releases(self, repo_names: List[str]) -> List[List[Dict[str, Any]]]:
|
||||||
|
return [
|
||||||
|
self.repository_api.repo_list_releases(self.org_name, repo_name)
|
||||||
|
for repo_name in repo_names
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_all_repo_names(self) -> List[str]:
|
||||||
|
return [
|
||||||
|
data["name"] for data in self.organization_api.org_list_repos(self.org_name)
|
||||||
|
]
|
||||||
|
|
||||||
|
def create_issue(
|
||||||
|
self,
|
||||||
|
repo_name: str,
|
||||||
|
title: str,
|
||||||
|
body: str,
|
||||||
|
assign_every_collaborators: bool = True,
|
||||||
|
) -> None:
|
||||||
|
assignees = []
|
||||||
|
if assign_every_collaborators:
|
||||||
|
assignees = [
|
||||||
|
item["username"]
|
||||||
|
for item in self.repository_api.repo_list_collaborators(
|
||||||
|
self.org_name, repo_name
|
||||||
|
)
|
||||||
|
]
|
||||||
|
self.issue_api.issue_create_issue(
|
||||||
|
self.org_name,
|
||||||
|
repo_name,
|
||||||
|
body={"title": title, "body": body, "assignees": assignees},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
gitea = Gitea()
|
gitea = Gitea()
|
||||||
|
|
39
joint_teapot/teapot.py
Normal file
39
joint_teapot/teapot.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
|
from joint_teapot import Canvas, Git, Gitea
|
||||||
|
|
||||||
|
|
||||||
|
class Teapot:
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.canvas = Canvas()
|
||||||
|
self.gitea = Gitea()
|
||||||
|
self.git = Git()
|
||||||
|
|
||||||
|
def create_personal_repos_for_all_canvas_students(self) -> List[str]:
|
||||||
|
return self.gitea.create_personal_repos_for_canvas_students(
|
||||||
|
self.canvas.students
|
||||||
|
)
|
||||||
|
|
||||||
|
def create_teams_and_repos_by_canvas_groups(self) -> List[str]:
|
||||||
|
return self.gitea.create_teams_and_repos_by_canvas_groups(
|
||||||
|
self.canvas.students, self.canvas.groups
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_public_key_of_all_canvas_students(self) -> List[List[Dict[str, Any]]]:
|
||||||
|
return self.gitea.get_public_key_of_canvas_students(self.canvas.students)
|
||||||
|
|
||||||
|
def archieve_all_repos(self) -> List[str]:
|
||||||
|
return [
|
||||||
|
self.git.repo_clean_and_checkout(repo_name, "master")
|
||||||
|
for repo_name in self.gitea.get_all_repo_names()
|
||||||
|
]
|
||||||
|
|
||||||
|
def create_issue_for_repos(
|
||||||
|
self, repo_names: List[str], title: str, body: str
|
||||||
|
) -> None:
|
||||||
|
for repo_name in repo_names:
|
||||||
|
self.gitea.create_issue(repo_name, title, body)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
teapot = Teapot()
|
Loading…
Reference in New Issue
Block a user