diff --git a/CHANGELOG.md b/CHANGELOG.md index 91cd8de8..ac870936 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/lang/zh-CN/ ## [Unreleased] +### Fixed + +- 从议题中获取的插件信息 + ## [3.2.1] - 2024-01-29 ### Fixed diff --git a/src/plugins/publish/__init__.py b/src/plugins/publish/__init__.py index b38206ee..de64f339 100644 --- a/src/plugins/publish/__init__.py +++ b/src/plugins/publish/__init__.py @@ -1,5 +1,3 @@ -import asyncio - from nonebot import logger, on_type from nonebot.adapters.github import ( GitHubBot, @@ -122,8 +120,6 @@ async def handle_pr_close( # 如果商店更新则触发 registry 更新 if event.payload.pull_request.merged: - # GitHub 的缓存一般 2 分钟左右会刷新 - await asyncio.sleep(120) await trigger_registry_update(bot, repo_info, publish_type, issue) else: logger.info("拉取请求未合并,跳过触发商店列表更新") diff --git a/src/plugins/publish/utils.py b/src/plugins/publish/utils.py index 03e85bee..e09dec3a 100644 --- a/src/plugins/publish/utils.py +++ b/src/plugins/publish/utils.py @@ -1,3 +1,4 @@ +import asyncio import json import re import subprocess @@ -530,27 +531,33 @@ async def trigger_registry_update( "data": json.dumps(result["data"]), } else: - with plugin_config.input_config.plugin_path.open() as f: - plugins = json.load(f) + # 从议题中获取的插件信息 + # 这样如果在 json 更新后再次运行也不会获取到不属于该插件的信息 + body = issue.body if issue.body else "" + module_name = PLUGIN_MODULE_NAME_PATTERN.search(body) + project_link = PROJECT_LINK_PATTERN.search(body) + config = PLUGIN_CONFIG_PATTERN.search(body) - if not plugins: - logger.error("插件列表为空,跳过触发商店列表更新") + if not module_name or not project_link: + logger.error("无法从议题中获取插件信息,跳过触发商店列表更新") return - plugin = plugins[-1] - project_link = plugin["project_link"] - module_name = plugin["module_name"] - config = PLUGIN_CONFIG_PATTERN.search(issue.body) if issue.body else "" + module_name = module_name.group(1) + project_link = project_link.group(1) + config = config.group(1) if config else "" client_payload = { "type": publish_type.value, "key": f"{project_link}:{module_name}", - "config": config.group(1) if config else "", + "config": config, } else: client_payload = {"type": publish_type.value} owner, repo = plugin_config.input_config.registry_repository.split("/") + # GitHub 的缓存一般 2 分钟左右会刷新 + logger.info("准备触发商店列表更新,等待 2 分钟") + await asyncio.sleep(120) # 触发商店列表更新 await bot.rest.repos.async_create_dispatch_event( repo=repo, diff --git a/tests/publish/process/test_pull_request.py b/tests/publish/process/test_pull_request.py index aaa3ff02..231fa175 100644 --- a/tests/publish/process/test_pull_request.py +++ b/tests/publish/process/test_pull_request.py @@ -22,7 +22,7 @@ async def test_process_pull_request(app: App, mocker: MockerFixture) -> None: mock_issue = mocker.MagicMock() mock_issue.state = "open" - mock_issue.body = "### 插件配置项\n\n```dotenv\nlog_level=DEBUG\n```" + mock_issue.body = "### PyPI 项目名\n\nproject_link1\n\n### 插件 import 包名\n\nmodule_name1\n\n### 插件配置项\n\n```dotenv\nlog_level=DEBUG\n```" mock_issue.number = 80 mock_issues_resp = mocker.MagicMock() @@ -119,7 +119,14 @@ async def test_process_pull_request(app: App, mocker: MockerFixture) -> None: any_order=True, ) - mock_sleep.assert_awaited_once_with(120) + # NOTE: 不知道为什么会调用两次 + # 那个 0 不知道哪里来的。 + mock_sleep.assert_has_awaits( + [ + mocker.call(120), + mocker.call(0), + ] # type: ignore + ) async def test_process_pull_request_not_merged(app: App, mocker: MockerFixture) -> None: diff --git a/tests/publish/utils/test_trigger_registry_update.py b/tests/publish/utils/test_trigger_registry_update.py index 7e9b2b66..2b94e016 100644 --- a/tests/publish/utils/test_trigger_registry_update.py +++ b/tests/publish/utils/test_trigger_registry_update.py @@ -1,4 +1,3 @@ -import json from typing import cast from nonebot import get_adapter @@ -19,9 +18,12 @@ async def test_trigger_registry_update(app: App, mocker: MockerFixture): from src.plugins.publish.utils import trigger_registry_update from src.utils.validation import PublishType + mock_sleep = mocker.patch("asyncio.sleep") + mock_sleep.return_value = None + mock_issue = mocker.MagicMock() mock_issue.state = "open" - mock_issue.body = "### 插件配置项\n\n```dotenv\nlog_level=DEBUG\n```" + mock_issue.body = "### PyPI 项目名\n\nproject_link1\n\n### 插件 import 包名\n\nmodule_name1\n\n### 插件配置项\n\n```dotenv\nlog_level=DEBUG\n```" mock_issue.number = 1 mock_comment = mocker.MagicMock() @@ -66,6 +68,8 @@ async def test_trigger_registry_update(app: App, mocker: MockerFixture): mock_issue, ) + mock_sleep.assert_awaited_once_with(120) + async def test_trigger_registry_update_skip_test( app: App, mocker: MockerFixture, mocked_api: MockRouter @@ -75,6 +79,9 @@ async def test_trigger_registry_update_skip_test( from src.plugins.publish.utils import trigger_registry_update from src.utils.validation import PublishType + mock_sleep = mocker.patch("asyncio.sleep") + mock_sleep.return_value = None + mock_issue = mocker.MagicMock() mock_issue.state = "open" mock_issue.body = generate_issue_body_plugin_skip_test() @@ -125,6 +132,8 @@ async def test_trigger_registry_update_skip_test( mock_issue, ) + mock_sleep.assert_awaited_once_with(120) + async def test_trigger_registry_update_bot(app: App, mocker: MockerFixture): """机器人发布的情况""" @@ -132,6 +141,9 @@ async def test_trigger_registry_update_bot(app: App, mocker: MockerFixture): from src.plugins.publish.utils import trigger_registry_update from src.utils.validation import PublishType + mock_sleep = mocker.patch("asyncio.sleep") + mock_sleep.return_value = None + mock_issue = mocker.MagicMock() mock_issue.state = "open" mock_issue.body = generate_issue_body_bot() @@ -164,12 +176,13 @@ async def test_trigger_registry_update_bot(app: App, mocker: MockerFixture): mock_issue, ) + mock_sleep.assert_awaited_once_with(120) -async def test_trigger_registry_update_plugins_file_empty( + +async def test_trigger_registry_update_plugins_issue_body_info_missing( app: App, mocker: MockerFixture ): - """如果插件列表为空,应该不会触发更新""" - from src.plugins.publish.config import plugin_config + """如果议题信息不全,应该不会触发更新""" from src.plugins.publish.models import RepoInfo from src.plugins.publish.utils import trigger_registry_update from src.utils.validation import PublishType @@ -185,9 +198,6 @@ async def test_trigger_registry_update_plugins_file_empty( mock_list_comments_resp = mocker.MagicMock() mock_list_comments_resp.parsed_data = [mock_comment] - with plugin_config.input_config.plugin_path.open("w") as f: - json.dump([], f) - async with app.test_api() as ctx: adapter = get_adapter(Adapter) bot = ctx.create_bot(