diff --git a/src/plugins/github/depends/__init__.py b/src/plugins/github/depends/__init__.py index 83f028ce..864c1520 100644 --- a/src/plugins/github/depends/__init__.py +++ b/src/plugins/github/depends/__init__.py @@ -106,10 +106,10 @@ def get_github_handler(bot: GitHubBot, repo_info: RepoInfo = Depends(get_repo_in return GithubHandler(bot=bot, repo_info=repo_info) -def get_type_by_labels( +def get_type_by_labels_name( labels: list[str] = Depends(get_name_by_labels), ) -> PublishType | None: - """通过标签获取类型""" + """通过标签的名称获取类型""" for type in PublishType: if type.value in labels: return type diff --git a/src/plugins/github/plugins/publish/__init__.py b/src/plugins/github/plugins/publish/__init__.py index 65673120..5d84fd36 100644 --- a/src/plugins/github/plugins/publish/__init__.py +++ b/src/plugins/github/plugins/publish/__init__.py @@ -28,7 +28,7 @@ from src.plugins.github.plugins.publish.render import render_comment from src.providers.validation.models import PublishType, ValidationDict -from .depends import get_type_by_labels +from .depends import get_type_by_labels_name from .utils import ( ensure_issue_content, ensure_issue_plugin_test_button, @@ -44,7 +44,7 @@ async def pr_close_rule( - publish_type: PublishType | None = Depends(get_type_by_labels), + publish_type: PublishType | None = Depends(get_type_by_labels_name), related_issue_number: int | None = Depends(get_related_issue_number), ) -> bool: if publish_type is None: @@ -68,7 +68,7 @@ async def handle_pr_close( event: PullRequestClosed, bot: GitHubBot, installation_id: int = Depends(get_installation_id), - publish_type: PublishType = Depends(get_type_by_labels), + publish_type: PublishType = Depends(get_type_by_labels_name), repo_info: RepoInfo = Depends(get_repo_info), related_issue_number: int = Depends(get_related_issue_number), ) -> None: @@ -108,7 +108,7 @@ async def handle_pr_close( async def check_rule( event: IssuesOpened | IssuesReopened | IssuesEdited | IssueCommentCreated, - publish_type: PublishType | None = Depends(get_type_by_labels), + publish_type: PublishType | None = Depends(get_type_by_labels_name), is_bot: bool = Depends(is_bot_triggered_workflow), ) -> bool: if is_bot: @@ -138,7 +138,7 @@ async def handle_publish_plugin_check( installation_id: int = Depends(get_installation_id), repo_info: RepoInfo = Depends(get_repo_info), issue_number: int = Depends(get_issue_number), - publish_type: Literal[PublishType.PLUGIN] = Depends(get_type_by_labels), + publish_type: Literal[PublishType.PLUGIN] = Depends(get_type_by_labels_name), ) -> None: async with bot.as_installation(installation_id): # 因为 Actions 会排队,触发事件相关的议题在 Actions 执行时可能已经被关闭 @@ -181,7 +181,7 @@ async def handle_adapter_publish_check( installation_id: int = Depends(get_installation_id), repo_info: RepoInfo = Depends(get_repo_info), issue_number: int = Depends(get_issue_number), - publish_type: Literal[PublishType.ADAPTER] = Depends(get_type_by_labels), + publish_type: Literal[PublishType.ADAPTER] = Depends(get_type_by_labels_name), ) -> None: async with bot.as_installation(installation_id): # 因为 Actions 会排队,触发事件相关的议题在 Actions 执行时可能已经被关闭 @@ -215,7 +215,7 @@ async def handle_bot_publish_check( installation_id: int = Depends(get_installation_id), repo_info: RepoInfo = Depends(get_repo_info), issue_number: int = Depends(get_issue_number), - publish_type: Literal[PublishType.BOT] = Depends(get_type_by_labels), + publish_type: Literal[PublishType.BOT] = Depends(get_type_by_labels_name), ) -> None: async with bot.as_installation(installation_id): # 因为 Actions 会排队,触发事件相关的议题在 Actions 执行时可能已经被关闭 @@ -272,7 +272,7 @@ async def handle_pull_request_and_update_issue( async def review_submiited_rule( event: PullRequestReviewSubmitted, - publish_type: PublishType | None = Depends(get_type_by_labels), + publish_type: PublishType | None = Depends(get_type_by_labels_name), ) -> bool: if publish_type is None: logger.info("拉取请求与发布无关,已跳过") diff --git a/src/plugins/github/plugins/publish/depends.py b/src/plugins/github/plugins/publish/depends.py index 4f05cf01..6bb7e1ec 100644 --- a/src/plugins/github/plugins/publish/depends.py +++ b/src/plugins/github/plugins/publish/depends.py @@ -5,7 +5,7 @@ from src.plugins.github.depends import ( get_issue_title, get_repo_info, - get_type_by_labels, + get_type_by_labels_name, ) from src.plugins.github.models import RepoInfo from src.plugins.github.plugins.publish import utils @@ -20,7 +20,7 @@ def get_type_by_title(title: str = Depends(get_issue_title)) -> PublishType | No async def get_pull_requests_by_label( bot: Bot, repo_info: RepoInfo = Depends(get_repo_info), - publish_type: PublishType = Depends(get_type_by_labels), + publish_type: PublishType = Depends(get_type_by_labels_name), ) -> list[PullRequestSimple]: pulls = ( await bot.rest.pulls.async_list(**repo_info.model_dump(), state="open") diff --git a/src/plugins/github/plugins/remove/__init__.py b/src/plugins/github/plugins/remove/__init__.py index 018eef90..8477ba44 100644 --- a/src/plugins/github/plugins/remove/__init__.py +++ b/src/plugins/github/plugins/remove/__init__.py @@ -18,7 +18,7 @@ get_issue_number, get_related_issue_number, get_repo_info, - get_type_by_labels, + get_type_by_labels_name, install_pre_commit_hooks, is_bot_triggered_workflow, ) @@ -119,7 +119,7 @@ async def handle_remove_check( installation_id: int = Depends(get_installation_id), repo_info: RepoInfo = Depends(get_repo_info), issue_number: int = Depends(get_issue_number), - publish_type: PublishType = Depends(get_type_by_labels), + publish_type: PublishType = Depends(get_type_by_labels_name), ): async with bot.as_installation(installation_id): issue = ( diff --git a/src/plugins/github/plugins/remove/utils.py b/src/plugins/github/plugins/remove/utils.py index a32e9b94..d4be34a9 100644 --- a/src/plugins/github/plugins/remove/utils.py +++ b/src/plugins/github/plugins/remove/utils.py @@ -1,5 +1,6 @@ from typing import TYPE_CHECKING, Any +from githubkit.exception import RequestFailed from nonebot import logger from pydantic_core import PydanticCustomError @@ -39,6 +40,7 @@ def update_file(type: PublishType, item: dict[str, Any]): raise ValueError("不支持的删除类型") data = load_json(path) + # 删除对应的数据项 data.remove(item) dump_json(path, data) logger.info(f"已更新 {path.name} 文件") @@ -58,9 +60,15 @@ async def process_pull_reqeusts( update_file(result.publish_type, result.item) handler.commit_and_push(message, branch_name) # 创建拉取请求 - await handler.create_pull_request( - plugin_config.input_config.base, title, branch_name, [REMOVE_LABEL] - ) + logger.info("开始创建拉取请求") + try: + await handler.create_pull_request( + plugin_config.input_config.base, title, branch_name, [REMOVE_LABEL, result.publish_type.value] + ) + except RequestFailed: + # 如果之前已经创建了拉取请求,则将其转换为草稿 + logger.info("该分支的拉取请求已创建,请前往查看") + await handler.update_pull_request_status(title, branch_name) async def resolve_conflict_pull_requests( @@ -81,6 +89,8 @@ async def resolve_conflict_pull_requests( if pull.draft: logger.info("拉取请求为草稿,跳过处理") continue + + # 根据标签获取发布类型 publish_type = get_type_by_labels(pull.labels) issue_handler = await handler.to_issue_handler(issue_number) diff --git a/src/plugins/github/plugins/remove/validation.py b/src/plugins/github/plugins/remove/validation.py index dbcb4d01..c1a567d9 100644 --- a/src/plugins/github/plugins/remove/validation.py +++ b/src/plugins/github/plugins/remove/validation.py @@ -26,15 +26,15 @@ class RemoveInfo(BaseModel): name: str -async def validate_author_info(issue: Issue, type: PublishType) -> RemoveInfo: +async def validate_author_info(issue: Issue, publish_type: PublishType) -> RemoveInfo: """ - 根据主页链接与作者信息找到对应的包的信息 + 通过议题获取作者 ID,然后验证待删除的数据项是否属于该作者 """ body = issue.body if issue.body else "" author_id = AuthorInfo.from_issue(issue).author_id - match type: + match publish_type: case PublishType.PLUGIN: raw_data = extract_issue_info_from_issue( { @@ -49,28 +49,17 @@ async def validate_author_info(issue: Issue, type: PublishType) -> RemoveInfo: raise PydanticCustomError( "info_not_found", "未填写数据项或填写信息有误" ) - plugin_data = { + data = { PYPI_KEY_TEMPLATE.format( project_link=plugin["project_link"], module_name=plugin["module_name"], ): plugin for plugin in load_json(plugin_config.input_config.plugin_path) } + key = PYPI_KEY_TEMPLATE.format( project_link=project_link, module_name=module_name ) - if key not in plugin_data: - raise PydanticCustomError("not_found", "没有包含对应信息的包") - - plugin = plugin_data[key] - if plugin.get("author_id") == author_id: - return RemoveInfo( - publish_type=PublishType.ADAPTER, - name=plugin.get("name") or plugin.get("project_link") or "", - item=plugin, - ) - else: - raise PydanticCustomError("author_info", "作者信息不匹配") case PublishType.BOT: raw_data = extract_issue_info_from_issue( { @@ -87,49 +76,38 @@ async def validate_author_info(issue: Issue, type: PublishType) -> RemoveInfo: "info_not_found", "未填写数据项或填写信息有误" ) - bot_data = { + data = { BOT_KEY_TEMPLATE.format(name=bot["name"], homepage=bot["homepage"]): bot for bot in load_json(plugin_config.input_config.bot_path) } + key = BOT_KEY_TEMPLATE.format(name=name, homepage=homepage) - if key not in bot_data: - raise PydanticCustomError("not_found", "没有包含对应信息的包") - - bot = bot_data[key] - if bot.get("author_id") == author_id: - return RemoveInfo( - publish_type=PublishType.BOT, - name=bot.get("name") or "", - item=bot, - ) - else: - raise PydanticCustomError("author_info", "作者信息不匹配") case PublishType.ADAPTER: - homepage = extract_issue_info_from_issue( + key = extract_issue_info_from_issue( {"homepage": REMOVE_HOMEPAGE_PATTERN}, issue.body or "" ).get("homepage") - if homepage is None: + if key is None: raise PydanticCustomError( "info_not_found", "未填写数据项或填写信息有误" ) - adapter_data = { + data = { adapter.get("homepage"): adapter for adapter in load_json(plugin_config.input_config.plugin_path) } - - if homepage not in adapter_data: - raise PydanticCustomError("not_found", "没有包含对应信息的包") - - adapter = adapter_data[homepage] - if adapter.get("author_id") == author_id: - return RemoveInfo( - publish_type=PublishType.ADAPTER, - name=adapter.get("name") or "", - item=adapter, - ) - else: - raise PydanticCustomError("author_info", "作者信息不匹配") case _: raise PydanticCustomError("not_support", "暂不支持的移除类型") + + if key not in data: + raise PydanticCustomError("not_found", "没有包含对应信息的包") + + remove_item = data[key] + if remove_item.get("author_id") != author_id: + raise PydanticCustomError("author_info", "作者信息不匹配") + + return RemoveInfo( + publish_type=publish_type, + name=remove_item.get("name") or "", + item=remove_item, + ) diff --git a/tests/github/remove/process/test_remove_check.py b/tests/github/remove/process/test_remove_check.py index 26f2922a..a5e3c151 100644 --- a/tests/github/remove/process/test_remove_check.py +++ b/tests/github/remove/process/test_remove_check.py @@ -111,7 +111,7 @@ async def test_process_remove_check( "owner": "he0119", "repo": "action-test", "issue_number": 2, - "labels": ["Remove"], + "labels": ["Remove", "Bot"], }, True, )