From 51f6c74497cb3b9d7d95bcf0f69e8105320a405b Mon Sep 17 00:00:00 2001 From: BigOrangeQWQ <2284086963@qq.com> Date: Mon, 26 May 2025 17:45:24 +0800 Subject: [PATCH 01/13] =?UTF-8?q?feat:=20=E5=9C=A8=20Noneflow=20=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E6=B5=81=E8=AF=84=E8=AE=BA=E5=A4=84=E5=A2=9E=E8=AE=BE?= =?UTF-8?q?=20Noneflow=20=E8=BF=90=E8=A1=8C=E5=8E=86=E5=8F=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/github/handlers/github.py | 33 +++++---- src/plugins/github/handlers/issue.py | 20 +++++- src/plugins/github/plugins/config/__init__.py | 2 +- .../github/plugins/publish/__init__.py | 12 +++- .../github/plugins/publish/constants.py | 7 ++ src/plugins/github/plugins/publish/render.py | 15 +++- .../publish/templates/comment.md.jinja | 11 +++ src/plugins/github/plugins/publish/utils.py | 18 ++++- src/plugins/github/plugins/remove/__init__.py | 4 +- tests/conftest.py | 2 +- .../config/process/test_config_check.py | 4 ++ .../github/handlers/test_github_handler.py | 7 +- .../github/handlers/test_issue_handler.py | 2 +- .../process/test_publish_check_plugin.py | 16 +++++ .../publish/render/test_publish_render.py | 8 +++ .../render/test_publish_render_data.py | 20 ++++++ .../render/test_publish_render_error.py | 54 +++++++++++++-- .../publish/utils/test_comment_issue.py | 6 +- .../publish/utils/test_history_workflow.py | 69 +++++++++++++++++++ .../docker_test/test_docker_plugin_test.py | 18 ++--- 20 files changed, 281 insertions(+), 47 deletions(-) create mode 100644 tests/plugins/github/publish/utils/test_history_workflow.py diff --git a/src/plugins/github/handlers/github.py b/src/plugins/github/handlers/github.py index f0a97be5..c3800f01 100644 --- a/src/plugins/github/handlers/github.py +++ b/src/plugins/github/handlers/github.py @@ -3,6 +3,7 @@ from githubkit.rest import PullRequestSimple from githubkit.typing import Missing from githubkit.utils import UNSET +from githubkit.versions.latest.models import IssueComment from nonebot import logger from nonebot.adapters.github import Bot from pydantic import ConfigDict @@ -69,22 +70,30 @@ async def update_comment(self, comment_id: int, comment: str): **self.repo_info.model_dump(), comment_id=comment_id, body=comment ) - async def comment_issue(self, comment: str, issue_number: int): - """发布评论,若之前已评论过,则会进行复用""" - logger.info("开始发布评论") - - # 重复利用评论 - # 如果发现之前评论过,直接修改之前的评论 - comments = await self.list_comments(issue_number=issue_number) - reusable_comment = next( + async def get_self_comment(self, issue_number: int): + """获取自己的评论""" + comments: list[IssueComment] = await self.list_comments(issue_number=issue_number) + return next( filter(lambda x: NONEFLOW_MARKER in (x.body if x.body else ""), comments), None, ) - if reusable_comment: - logger.info(f"发现已有评论 {reusable_comment.id},正在修改") - if reusable_comment.body != comment: - await self.update_comment(reusable_comment.id, comment) + async def resuable_comment_issue( + self, comment: str, issue_number: int + ) -> IssueComment | None: + """复用评论,若之前已评论过,则会进行复用""" + logger.info("查询已有评论") + self_comment = await self.get_self_comment(issue_number=issue_number) + await self.comment_issue(comment, issue_number, self_comment) + + async def comment_issue(self, comment: str, issue_number: int, self_comment: IssueComment | None = None): + """发布评论""" + logger.info("开始发布评论") + + if self_comment: + logger.info(f"发现已有评论 {self_comment.id},正在修改") + if self_comment.body != comment: + await self.update_comment(self_comment.id, comment) logger.info("评论修改完成") else: logger.info("评论内容无变化,跳过修改") diff --git a/src/plugins/github/handlers/issue.py b/src/plugins/github/handlers/issue.py index ef1dd03d..d949a9e7 100644 --- a/src/plugins/github/handlers/issue.py +++ b/src/plugins/github/handlers/issue.py @@ -105,12 +105,28 @@ async def list_comments(self, issue_number: int | None = None): return await super().list_comments(issue_number) - async def comment_issue(self, comment: str, issue_number: int | None = None): + async def get_self_comment(self, issue_number: int | None = None): + """获取自己的评论""" + if issue_number is None: + issue_number = self.issue_number + + await super().get_self_comment(issue_number) + + async def comment_issue(self, comment: str, issue_number: int | None = None, self_comment = None): + """发布评论""" + if issue_number is None: + issue_number = self.issue_number + + await super().comment_issue(comment, issue_number, self_comment) + + async def resuable_comment_issue(self, comment: str, issue_number: int | None = None): """发布评论,若之前已评论过,则会进行复用""" if issue_number is None: issue_number = self.issue_number - await super().comment_issue(comment, issue_number) + self_comment = await self.get_self_comment(issue_number) + await self.comment_issue(comment, issue_number, self_comment) + def commit_and_push( self, diff --git a/src/plugins/github/plugins/config/__init__.py b/src/plugins/github/plugins/config/__init__.py index f71c8297..081d74a6 100644 --- a/src/plugins/github/plugins/config/__init__.py +++ b/src/plugins/github/plugins/config/__init__.py @@ -81,7 +81,7 @@ async def handle_remove_check( comment = await render_comment(result, True) # 对议题评论 - await handler.comment_issue(comment) + await handler.resuable_comment_issue(comment) branch_name = f"{BRANCH_NAME_PREFIX}{handler.issue_number}" diff --git a/src/plugins/github/plugins/publish/__init__.py b/src/plugins/github/plugins/publish/__init__.py index 7702e7a1..d864fa7c 100644 --- a/src/plugins/github/plugins/publish/__init__.py +++ b/src/plugins/github/plugins/publish/__init__.py @@ -1,3 +1,4 @@ +from datetime import datetime from typing import Literal from nonebot import logger, on_type @@ -39,6 +40,7 @@ ensure_issue_content, ensure_issue_plugin_test_button, ensure_issue_plugin_test_button_in_progress, + get_history_workflow_from_comment, process_pull_request, trigger_registry_update, ) @@ -153,11 +155,17 @@ async def handle_pull_request_and_update_issue( installation_id: int = Depends(get_installation_id), ) -> None: async with bot.as_installation(installation_id): + + self_comment = await handler.get_self_comment(handler.issue_number) + history: list[tuple[bool, str, datetime]] = [] + if self_comment and self_comment.body: + history = await get_history_workflow_from_comment(self_comment.body) + # 渲染评论信息 - comment = await render_comment(validation, True) + comment = await render_comment(validation, True, history) # 对议题评论 - await handler.comment_issue(comment) + await handler.comment_issue(comment, issue_number=None, self_comment=self_comment) # 设置拉取请求与议题的标题 # 限制标题长度,过长的标题不好看 diff --git a/src/plugins/github/plugins/publish/constants.py b/src/plugins/github/plugins/publish/constants.py index 7e00a5f6..c8b57bb1 100644 --- a/src/plugins/github/plugins/publish/constants.py +++ b/src/plugins/github/plugins/publish/constants.py @@ -46,6 +46,13 @@ ADAPTER_MODULE_NAME_PATTERN = re.compile(ISSUE_PATTERN.format("适配器 import 包名")) ADAPTER_HOMEPAGE_PATTERN = re.compile(ISSUE_PATTERN.format("适配器项目仓库/主页链接")) + +WORKFLOW_HISTORY_PATTERN = re.compile( + r'
  • (⚠️|✅)\s*([^<]+?CST)
  • ' +) + +WORKFLOW_HISTORY_TEMPLATE = """
  • {status} {time}
  • """ + # 评论卡片模板 COMMENT_CARD_TEMPLATE = """[![{name}](https://img.shields.io/badge/{head}-{content}-{color}?style=for-the-badge)]({url})""" diff --git a/src/plugins/github/plugins/publish/render.py b/src/plugins/github/plugins/publish/render.py index c16b5310..a68c85a9 100644 --- a/src/plugins/github/plugins/publish/render.py +++ b/src/plugins/github/plugins/publish/render.py @@ -48,6 +48,10 @@ def format_time(time: str) -> str: dt = dt.astimezone(tz=TIME_ZONE) return dt.strftime("%Y-%m-%d %H:%M:%S %Z") +def format_datetime(dt: datetime) -> str: + """格式化 datetime 对象为字符串""" + dt = dt.astimezone(tz=TIME_ZONE) + return dt.strftime("%Y-%m-%d %H:%M:%S %Z") env = jinja2.Environment( loader=jinja2.FileSystemLoader(Path(__file__).parent / "templates"), @@ -63,9 +67,10 @@ def format_time(time: str) -> str: env.filters["loc_to_name"] = loc_to_name env.filters["key_to_name"] = key_to_name env.filters["format_time"] = format_time +env.filters["format_datetime"] = format_datetime -async def render_comment(result: ValidationDict, reuse: bool = False) -> str: +async def render_comment(result: ValidationDict, reuse: bool = False, history: list[tuple[bool, str, datetime]] = list()) -> str: """将验证结果转换为评论内容""" title = f"{result.type}: {result.name}" @@ -119,6 +124,13 @@ async def render_comment(result: ValidationDict, reuse: bool = False) -> str: url=action_url, ) ) + history.append( + ( + result.valid, + action_url, + datetime.now(tz=TIME_ZONE), + ) + ) template = env.get_template("comment.md.jinja") return await template.render_async( @@ -127,6 +139,7 @@ async def render_comment(result: ValidationDict, reuse: bool = False) -> str: title=title, valid=result.valid, data=data, + history=history, errors=result.errors, skip_test=result.skip_test, ) diff --git a/src/plugins/github/plugins/publish/templates/comment.md.jinja b/src/plugins/github/plugins/publish/templates/comment.md.jinja index a020e943..acb68b0e 100644 --- a/src/plugins/github/plugins/publish/templates/comment.md.jinja +++ b/src/plugins/github/plugins/publish/templates/comment.md.jinja @@ -31,6 +31,17 @@ {% endif %} +{%- if history %} +
    +历史测试 +
    
    +{%- for status, action_url, time in history%}
    +
  • {{"✅" if status else "⚠️"}} {{time|format_datetime}}
  • +{%- endfor %} +
    +
    +{% endif %} + --- 💡 如需修改信息,请直接修改 issue,机器人会自动更新检查结果。 diff --git a/src/plugins/github/plugins/publish/utils.py b/src/plugins/github/plugins/publish/utils.py index 9166fdce..0d550364 100644 --- a/src/plugins/github/plugins/publish/utils.py +++ b/src/plugins/github/plugins/publish/utils.py @@ -1,4 +1,6 @@ + import re +from datetime import datetime from githubkit.exception import RequestFailed from nonebot import logger @@ -13,6 +15,7 @@ from src.plugins.github.handlers import GithubHandler, IssueHandler from src.plugins.github.typing import PullRequestList from src.plugins.github.utils import commit_message as _commit_message +from src.providers.constants import TIME_ZONE from src.providers.models import RegistryUpdatePayload, to_store from src.providers.utils import dump_json5, load_json_from_file from src.providers.validation import PublishType, ValidationDict @@ -25,6 +28,7 @@ PLUGIN_TEST_BUTTON_STRING, PLUGIN_TEST_PATTERN, PLUGIN_TEST_STRING, + WORKFLOW_HISTORY_PATTERN, ) from .validation import ( validate_adapter_info_from_issue, @@ -187,7 +191,6 @@ async def ensure_issue_plugin_test_button(handler: IssueHandler): await handler.update_issue_body(new_content) - async def ensure_issue_plugin_test_button_in_progress(handler: IssueHandler): """确保议题内容中包含插件测试进行中的提示""" issue_body = handler.issue.body or "" @@ -277,3 +280,16 @@ async def trigger_registry_update(handler: IssueHandler, publish_type: PublishTy repo=plugin_config.input_config.registry_repository, ) logger.info("已触发商店列表更新") + +async def get_history_workflow_from_comment( + comment: str, +) -> list[tuple[bool, str, datetime]]: + """获取历史工作流""" + return [ + ( + status == "✅", + action_url, + datetime.strptime(time, "%Y-%m-%d %H:%M:%S CST").astimezone(TIME_ZONE), + ) + for status, action_url, time in WORKFLOW_HISTORY_PATTERN.findall(comment) + ] diff --git a/src/plugins/github/plugins/remove/__init__.py b/src/plugins/github/plugins/remove/__init__.py index d41a162c..5de03881 100644 --- a/src/plugins/github/plugins/remove/__init__.py +++ b/src/plugins/github/plugins/remove/__init__.py @@ -86,7 +86,7 @@ async def handle_remove_check( result = await validate_author_info(handler.issue, publish_type) except PydanticCustomError as err: logger.error(f"信息验证失败: {err}") - await handler.comment_issue(await render_error(err)) + await handler.resuable_comment_issue(await render_error(err)) await remove_check_matcher.finish() title = f"{result.publish_type}: Remove {result.name or 'Unknown'}"[ @@ -113,7 +113,7 @@ async def handle_remove_check( result, f"{plugin_config.input_config.store_repository}#{pull_number}", ) - await handler.comment_issue(comment) + await handler.resuable_comment_issue(comment) async def review_submitted_rule( diff --git a/tests/conftest.py b/tests/conftest.py index f08b68ac..cd187b06 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -230,7 +230,7 @@ def datetime_modules_loc() -> list[str]: return find_datetime_loc(PROJECT_SOURCE_PATH) -@pytest.fixture +@pytest.fixture(autouse=True) def mock_datetime(mocker: MockerFixture, datetime_modules_loc: list[str]): """ 将所有模块中的 datetime.now() 方法返回值固定 diff --git a/tests/plugins/github/config/process/test_config_check.py b/tests/plugins/github/config/process/test_config_check.py index 0bd437a7..5e6308d9 100644 --- a/tests/plugins/github/config/process/test_config_check.py +++ b/tests/plugins/github/config/process/test_config_check.py @@ -146,6 +146,10 @@ async def test_process_config_check( 详情
  • ✅ 项目 主页 返回状态码 200。
  • ✅ 项目 nonebot-plugin-treehelp 已发布至 PyPI。
  • ✅ 标签: test-#ffffff。
  • ✅ 插件类型: application。
  • ✅ 插件支持的适配器: nonebot.adapters.onebot.v11。
  • ✅ 插件 加载测试 通过。
  • ✅ 版本号: 1.0.0。
  • ✅ 发布时间:2024-07-13 12:41:40 CST。
  • +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • +
    --- diff --git a/tests/plugins/github/handlers/test_github_handler.py b/tests/plugins/github/handlers/test_github_handler.py index 03bfddf4..94f4d85c 100644 --- a/tests/plugins/github/handlers/test_github_handler.py +++ b/tests/plugins/github/handlers/test_github_handler.py @@ -239,8 +239,7 @@ async def test_comment_issue(app: App, mocker: MockerFixture) -> None: } ), ) - await github_handler.comment_issue("new comment", 76) - + await github_handler.resuable_comment_issue("new comment", 76) async def test_comment_issue_reuse(app: App, mocker: MockerFixture) -> None: """测试发布评论,复用的情况""" @@ -281,7 +280,7 @@ async def test_comment_issue_reuse(app: App, mocker: MockerFixture) -> None: } ), ) - await github_handler.comment_issue("new comment", 76) + await github_handler.resuable_comment_issue("new comment", 76) async def test_comment_issue_reuse_no_change(app: App, mocker: MockerFixture) -> None: @@ -316,7 +315,7 @@ async def test_comment_issue_reuse_no_change(app: App, mocker: MockerFixture) -> } ), ) - await github_handler.comment_issue("comment\n", 76) + await github_handler.resuable_comment_issue("comment\n", 76) async def test_get_pull_requests_by_label(app: App, mocker: MockerFixture) -> None: diff --git a/tests/plugins/github/handlers/test_issue_handler.py b/tests/plugins/github/handlers/test_issue_handler.py index 41d40413..c1ce311f 100644 --- a/tests/plugins/github/handlers/test_issue_handler.py +++ b/tests/plugins/github/handlers/test_issue_handler.py @@ -279,7 +279,7 @@ async def test_comment_issue(app: App, mocker: MockerFixture) -> None: } ), ) - await issue_handler.comment_issue("new comment") + await issue_handler.resuable_comment_issue("new comment") async def test_should_skip_test(app: App, mocker: MockerFixture) -> None: diff --git a/tests/plugins/github/publish/process/test_publish_check_plugin.py b/tests/plugins/github/publish/process/test_publish_check_plugin.py index e81f9d4b..14c04041 100644 --- a/tests/plugins/github/publish/process/test_publish_check_plugin.py +++ b/tests/plugins/github/publish/process/test_publish_check_plugin.py @@ -201,6 +201,10 @@ async def test_plugin_process_publish_check( 详情
  • ✅ 项目 主页 返回状态码 200。
  • ✅ 项目 project_link 已发布至 PyPI。
  • ✅ 标签: test-#ffffff。
  • ✅ 插件类型: application。
  • ✅ 插件支持的适配器: 所有。
  • ✅ 插件 加载测试 通过。
  • ✅ 版本号: 1.0.0。
  • ✅ 发布时间:2023-09-01 08:00:00 CST。
  • +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • +
    --- @@ -463,6 +467,10 @@ async def test_plugin_process_publish_check_re_run( 详情
  • ✅ 项目 主页 返回状态码 200。
  • ✅ 项目 project_link 已发布至 PyPI。
  • ✅ 标签: test-#ffffff。
  • ✅ 插件类型: application。
  • ✅ 插件支持的适配器: 所有。
  • ✅ 插件 加载测试 通过。
  • ✅ 版本号: 1.0.0。
  • ✅ 发布时间:2023-09-01 08:00:00 CST。
  • +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • +
    --- @@ -710,6 +718,10 @@ async def test_plugin_process_publish_check_missing_metadata( 详情
  • ✅ 项目 project_link 已发布至 PyPI。
  • ✅ 标签: test-#ffffff。
  • ✅ 插件 加载测试 通过。
  • ✅ 版本号: 1.0.0。
  • ✅ 发布时间:2023-09-01 08:00:00 CST。
  • +
    +历史测试 +
  • ⚠️ 2023-08-23 09:22:14 CST
  • +
    --- @@ -965,6 +977,10 @@ async def test_skip_plugin_check( 详情
  • ✅ 项目 project_link 已发布至 PyPI。
  • ✅ 标签: test-#ffffff。
  • ✅ 插件 加载测试 已跳过。
  • ✅ 版本号: 0.0.1。
  • ✅ 发布时间:2023-09-01 08:00:00 CST。
  • +
    +历史测试 +
  • ⚠️ 2023-08-23 09:22:14 CST
  • +
    --- diff --git a/tests/plugins/github/publish/render/test_publish_render.py b/tests/plugins/github/publish/render/test_publish_render.py index d2861800..fb2ff54e 100644 --- a/tests/plugins/github/publish/render/test_publish_render.py +++ b/tests/plugins/github/publish/render/test_publish_render.py @@ -25,6 +25,10 @@ async def test_render_empty(app: App): **✅ 所有测试通过,一切准备就绪!** +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • +
    --- @@ -59,6 +63,10 @@ async def test_render_reuse(app: App): **✅ 所有测试通过,一切准备就绪!** +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • +
    --- diff --git a/tests/plugins/github/publish/render/test_publish_render_data.py b/tests/plugins/github/publish/render/test_publish_render_data.py index 97e02ec8..dc8a774d 100644 --- a/tests/plugins/github/publish/render/test_publish_render_data.py +++ b/tests/plugins/github/publish/render/test_publish_render_data.py @@ -43,6 +43,10 @@ async def test_render_data_bot(app: App): 详情
  • ✅ 项目 主页 返回状态码 200。
  • +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • +
    --- @@ -91,6 +95,10 @@ async def test_render_data_bot(app: App): 详情
  • ✅ 项目 主页 返回状态码 200。
  • ✅ 标签: StarRail-#5a8ccc, 星穹铁道-#6faec6。
  • +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • +
    --- @@ -146,6 +154,10 @@ async def test_render_data_adapter(app: App): 详情
  • ✅ 项目 主页 返回状态码 200。
  • ✅ 项目 nonebot-adapter-villa 已发布至 PyPI。
  • ✅ 标签: 米哈游-#e10909。
  • ✅ 版本号: 1.4.2。
  • ✅ 发布时间:2023-12-21 14:57:44 CST。
  • +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • +
    --- @@ -205,6 +217,10 @@ async def test_render_data_plugin(app: App, mocker: MockFixture): 详情
  • ✅ 项目 主页 返回状态码 200。
  • ✅ 项目 nonebot-plugin-treehelp 已发布至 PyPI。
  • ✅ 标签: render-#ffffff。
  • ✅ 插件类型: application。
  • ✅ 插件支持的适配器: 所有。
  • ✅ 插件 加载测试 通过。
  • ✅ 版本号: 0.5.0。
  • ✅ 发布时间:2024-07-13 12:41:40 CST。
  • +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • +
    --- @@ -258,6 +274,10 @@ async def test_render_data_plugin_supported_adapters(app: App, mocker: MockFixtu 详情
  • ✅ 插件支持的适配器: nonebot.adapters.onebot.v11, nonebot.adapters.none。
  • ✅ 插件 加载测试 通过。
  • +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • +
    --- diff --git a/tests/plugins/github/publish/render/test_publish_render_error.py b/tests/plugins/github/publish/render/test_publish_render_error.py index 6603238e..45f3c2f3 100644 --- a/tests/plugins/github/publish/render/test_publish_render_error.py +++ b/tests/plugins/github/publish/render/test_publish_render_error.py @@ -58,6 +58,10 @@ async def test_render_error_bot(app: App):
  • ⚠️ 名称: 字符过多。
    请确保其不超过 50 个字符。
  • ⚠️ 项目 主页 返回状态码 404。
    请确保你的项目主页可访问。
  • ⚠️ 第 2 个标签名称过长。
    请确保标签名称不超过 10 个字符。
  • ⚠️ 第 2 个标签颜色错误。
    请确保标签颜色符合十六进制颜色码规则。
  • +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • +
    --- @@ -145,6 +149,10 @@ async def test_render_error_adapter(app: App): 详情
  • ✅ 项目 nonebot-adapter-villa 已发布至 PyPI。
  • +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • +
    --- @@ -158,7 +166,7 @@ async def test_render_error_adapter(app: App): ) -async def test_render_error_plugin(app: App, mocker: MockFixture): +async def test_render_error_plugin(app: App, mocker: MockFixture, mock_datetime): """插件数据""" from src.plugins.github.plugins.publish.render import render_comment from src.providers.validation import PublishType, ValidationDict @@ -241,6 +249,10 @@ async def test_render_error_plugin(app: App, mocker: MockFixture): 详情
  • ✅ 项目 主页 返回状态码 200。
  • ✅ 插件 加载测试 通过。
  • +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • +
    --- @@ -310,6 +322,10 @@ async def test_render_error_plugin_load_test(app: App): 详情
  • ✅ 项目 主页 返回状态码 200。
  • +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • +
    --- @@ -323,7 +339,9 @@ async def test_render_error_plugin_load_test(app: App): ) -async def test_render_error_plugin_metadata(app: App, mocker: MockFixture): +async def test_render_error_plugin_metadata( + app: App, mocker: MockFixture, mock_datetime +): """插件加载成功,但缺少元数据的情况""" from src.plugins.github.plugins.publish.render import render_comment from src.providers.validation import PublishType, ValidationDict @@ -369,6 +387,10 @@ async def test_render_error_plugin_metadata(app: App, mocker: MockFixture): 详情
  • ✅ 插件 加载测试 通过。
  • +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • +
    --- @@ -382,7 +404,7 @@ async def test_render_error_plugin_metadata(app: App, mocker: MockFixture): ) -async def test_render_error_tags_invalid(app: App, mocker: MockFixture): +async def test_render_error_tags_invalid(app: App, mocker: MockFixture, mock_datetime): """标签不合法的情况""" from src.plugins.github.plugins.publish.render import render_comment from src.providers.validation import PublishType, ValidationDict @@ -439,6 +461,10 @@ async def test_render_error_tags_invalid(app: App, mocker: MockFixture): 详情
  • ✅ 插件 加载测试 通过。
  • +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • +
    --- @@ -452,7 +478,7 @@ async def test_render_error_tags_invalid(app: App, mocker: MockFixture): ) -async def test_render_type_error(app: App, mocker: MockFixture): +async def test_render_type_error(app: App, mocker: MockFixture, mock_datetime): """插件类型与适配器错误""" from src.plugins.github.plugins.publish.render import render_comment from src.providers.validation import PublishType, ValidationDict @@ -510,6 +536,10 @@ async def test_render_type_error(app: App, mocker: MockFixture): 详情
  • ✅ 插件 加载测试 通过。
  • +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • +
    --- @@ -523,7 +553,7 @@ async def test_render_type_error(app: App, mocker: MockFixture): ) -async def test_render_unknown_error(app: App, mocker: MockFixture): +async def test_render_unknown_error(app: App, mocker: MockFixture, mock_datetime): """未知错误""" from src.plugins.github.plugins.publish.render import render_comment from src.providers.validation import PublishType, ValidationDict @@ -568,6 +598,10 @@ async def test_render_unknown_error(app: App, mocker: MockFixture): 详情
  • ✅ 插件 加载测试 通过。
  • +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • +
    --- @@ -581,7 +615,11 @@ async def test_render_unknown_error(app: App, mocker: MockFixture): ) -async def test_render_http_error(app: App, mocker: MockFixture): +async def test_render_http_error( + app: App, + mocker: MockFixture, + mock_datetime, +): """网络请求报错""" from src.plugins.github.plugins.publish.render import render_comment from src.providers.validation import PublishType, ValidationDict @@ -637,6 +675,10 @@ async def test_render_http_error(app: App, mocker: MockFixture): 详情
  • ✅ 插件 加载测试 通过。
  • +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • +
    --- diff --git a/tests/plugins/github/publish/utils/test_comment_issue.py b/tests/plugins/github/publish/utils/test_comment_issue.py index 98c1e34b..24d71a41 100644 --- a/tests/plugins/github/publish/utils/test_comment_issue.py +++ b/tests/plugins/github/publish/utils/test_comment_issue.py @@ -36,7 +36,7 @@ async def test_comment_issue(app: App, mocker: MockerFixture): handler = GithubHandler(bot=bot, repo_info=RepoInfo(owner="owner", repo="repo")) - await handler.comment_issue(render_comment, 1) + await handler.resuable_comment_issue(render_comment, 1) async def test_comment_issue_reuse(app: App, mocker: MockerFixture): @@ -73,7 +73,7 @@ async def test_comment_issue_reuse(app: App, mocker: MockerFixture): handler = GithubHandler(bot=bot, repo_info=RepoInfo(owner="owner", repo="repo")) - await handler.comment_issue(render_comment, 1) + await handler.resuable_comment_issue(render_comment, 1) async def test_comment_issue_reuse_same(app: App, mocker: MockerFixture): @@ -101,4 +101,4 @@ async def test_comment_issue_reuse_same(app: App, mocker: MockerFixture): handler = GithubHandler(bot=bot, repo_info=RepoInfo(owner="owner", repo="repo")) - await handler.comment_issue(render_comment, 1) + await handler.resuable_comment_issue(render_comment, 1) diff --git a/tests/plugins/github/publish/utils/test_history_workflow.py b/tests/plugins/github/publish/utils/test_history_workflow.py new file mode 100644 index 00000000..c8e45e74 --- /dev/null +++ b/tests/plugins/github/publish/utils/test_history_workflow.py @@ -0,0 +1,69 @@ +import datetime +import zoneinfo +from inline_snapshot import snapshot +from nonebug import App + + +async def test_history_workflow(app: App, mock_datetime): + from src.plugins.github.plugins.publish.utils import ( + get_history_workflow_from_comment, + ) + + CONTENT = """ +# 📃 商店发布检查结果 + +> Plugin: nonebot-plugin-emojilike-automonkey + +**✅ 所有测试通过,一切准备就绪!** + + +
    +详情 +
  • ✅ 项目 主页 返回状态码 200。
  • ✅ 项目 nonebot-plugin-emojilike-automonkey 已发布至 PyPI。
  • ✅ 标签: emoji-#6677ff。
  • ✅ 插件类型: application。
  • ✅ 插件支持的适配器: nonebot.adapters.onebot.v11。
  • ✅ 插件 加载测试 通过。
  • ✅ 版本号: 0.0.12。
  • ✅ 发布时间:2025-03-28 02:03:18 CST。
  • +
    + +
    +历史测试 +
    
    +
  • ⚠️ 2025-03-28 02:21:18 CST
  • 2025-03-28 02:21:18 CST
  • 2025-03-28 02:22:18 CST
  • ⚠️ 2025-03-28 02:22:18 CST
  • +
    +
    + +--- + +💡 如需修改信息,请直接修改 issue,机器人会自动更新检查结果。 +💡 当插件加载测试失败时,请发布新版本后勾选插件测试勾选框重新运行插件测试。 + +♻️ 评论已更新至最新检查结果 + +💪 Powered by [NoneFlow](https://github.com/nonebot/noneflow) + +""" + history = [ + (valid, url, time.strftime("%Y-%m-%d %H:%M:%S %Z")) + for valid, url, time in await get_history_workflow_from_comment(CONTENT) + ] + assert history == snapshot( + [ + ( + False, + "https://github.com/nonebot/nonebot2/actions/runs/14156878699", + "2025-03-28 02:21:18 CST", + ), + ( + True, + "https://github.com/nonebot/nonebot2/actions/runs/14156878699", + "2025-03-28 02:21:18 CST", + ), + ( + True, + "https://github.com/nonebot/nonebot2/actions/runs/14156878699", + "2025-03-28 02:22:18 CST", + ), + ( + False, + "https://github.com/nonebot/nonebot2/actions/runs/14156878699", + "2025-03-28 02:22:18 CST", + ), + ] + ) diff --git a/tests/providers/docker_test/test_docker_plugin_test.py b/tests/providers/docker_test/test_docker_plugin_test.py index 3a195d37..73b68dd2 100644 --- a/tests/providers/docker_test/test_docker_plugin_test.py +++ b/tests/providers/docker_test/test_docker_plugin_test.py @@ -31,7 +31,6 @@ async def test_docker_plugin_test(mocked_api: MockRouter, mocker: MockerFixture) assert result == snapshot( DockerTestResult( load=True, - metadata=None, output="test", run=True, test_env="python==3.12", @@ -75,7 +74,6 @@ async def test_docker_plugin_test_exception( DockerTestResult( run=False, load=False, - metadata=None, output="Docker failed", ) ) @@ -130,7 +128,6 @@ async def test_docker_plugin_test_metadata_some_fields_empty( assert result == snapshot( DockerTestResult( - config="", load=True, metadata={ "name": "name", @@ -196,15 +193,14 @@ async def test_docker_plugin_test_metadata_some_fields_invalid( assert result == snapshot( DockerTestResult( - config="", load=True, - metadata=Metadata( - name="name", - desc="desc", - homepage=12, # type: ignore - type=True, # type: ignore - supported_adapters={}, # type: ignore - ), + metadata={ + "name": "name", + "desc": "desc", + "homepage": 12, + "type": True, + "supported_adapters": {}, + }, output="test", run=True, test_env="python==3.12", From 335807f0f4c9bcf973ab50b8f6f50072bf0b8851 Mon Sep 17 00:00:00 2001 From: BigOrangeQWQ <2284086963@qq.com> Date: Mon, 26 May 2025 17:53:23 +0800 Subject: [PATCH 02/13] =?UTF-8?q?test:=20=E6=9B=B4=E6=96=B0=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E5=BF=AB=E7=85=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/github/plugins/publish/render.py | 4 +++- .../publish/render/test_publish_render.py | 8 ------- .../render/test_publish_render_data.py | 16 ++----------- .../render/test_publish_render_error.py | 24 +++++-------------- 4 files changed, 11 insertions(+), 41 deletions(-) diff --git a/src/plugins/github/plugins/publish/render.py b/src/plugins/github/plugins/publish/render.py index a68c85a9..e22fc235 100644 --- a/src/plugins/github/plugins/publish/render.py +++ b/src/plugins/github/plugins/publish/render.py @@ -70,11 +70,13 @@ def format_datetime(dt: datetime) -> str: env.filters["format_datetime"] = format_datetime -async def render_comment(result: ValidationDict, reuse: bool = False, history: list[tuple[bool, str, datetime]] = list()) -> str: +async def render_comment(result: ValidationDict, reuse: bool = False, history: list[tuple[bool, str, datetime]] | None = None) -> str: """将验证结果转换为评论内容""" title = f"{result.type}: {result.name}" valid_data = result.valid_data.copy() + + history = history or [] if result.type == PublishType.PLUGIN: # https://github.com/he0119/action-test/actions/runs/4469672520 diff --git a/tests/plugins/github/publish/render/test_publish_render.py b/tests/plugins/github/publish/render/test_publish_render.py index fb2ff54e..d2861800 100644 --- a/tests/plugins/github/publish/render/test_publish_render.py +++ b/tests/plugins/github/publish/render/test_publish_render.py @@ -25,10 +25,6 @@ async def test_render_empty(app: App): **✅ 所有测试通过,一切准备就绪!** -
    -历史测试 -
  • 2023-08-23 09:22:14 CST
  • -
    --- @@ -63,10 +59,6 @@ async def test_render_reuse(app: App): **✅ 所有测试通过,一切准备就绪!** -
    -历史测试 -
  • 2023-08-23 09:22:14 CST
  • -
    --- diff --git a/tests/plugins/github/publish/render/test_publish_render_data.py b/tests/plugins/github/publish/render/test_publish_render_data.py index dc8a774d..edd981ce 100644 --- a/tests/plugins/github/publish/render/test_publish_render_data.py +++ b/tests/plugins/github/publish/render/test_publish_render_data.py @@ -43,10 +43,6 @@ async def test_render_data_bot(app: App): 详情
  • ✅ 项目 主页 返回状态码 200。
  • -
    -历史测试 -
  • 2023-08-23 09:22:14 CST
  • -
    --- @@ -95,10 +91,6 @@ async def test_render_data_bot(app: App): 详情
  • ✅ 项目 主页 返回状态码 200。
  • ✅ 标签: StarRail-#5a8ccc, 星穹铁道-#6faec6。
  • -
    -历史测试 -
  • 2023-08-23 09:22:14 CST
  • -
    --- @@ -154,10 +146,6 @@ async def test_render_data_adapter(app: App): 详情
  • ✅ 项目 主页 返回状态码 200。
  • ✅ 项目 nonebot-adapter-villa 已发布至 PyPI。
  • ✅ 标签: 米哈游-#e10909。
  • ✅ 版本号: 1.4.2。
  • ✅ 发布时间:2023-12-21 14:57:44 CST。
  • -
    -历史测试 -
  • 2023-08-23 09:22:14 CST
  • -
    --- @@ -219,7 +207,7 @@ async def test_render_data_plugin(app: App, mocker: MockFixture):
    历史测试 -
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • +
  • 2023-08-23 09:22:14 CST
  • --- @@ -276,7 +264,7 @@ async def test_render_data_plugin_supported_adapters(app: App, mocker: MockFixtu
    历史测试 -
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • +
  • 2023-08-23 09:22:14 CST
  • --- diff --git a/tests/plugins/github/publish/render/test_publish_render_error.py b/tests/plugins/github/publish/render/test_publish_render_error.py index 45f3c2f3..dcb2db20 100644 --- a/tests/plugins/github/publish/render/test_publish_render_error.py +++ b/tests/plugins/github/publish/render/test_publish_render_error.py @@ -58,10 +58,6 @@ async def test_render_error_bot(app: App):
  • ⚠️ 名称: 字符过多。
    请确保其不超过 50 个字符。
  • ⚠️ 项目 主页 返回状态码 404。
    请确保你的项目主页可访问。
  • ⚠️ 第 2 个标签名称过长。
    请确保标签名称不超过 10 个字符。
  • ⚠️ 第 2 个标签颜色错误。
    请确保标签颜色符合十六进制颜色码规则。
  • -
    -历史测试 -
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • -
    --- @@ -149,10 +145,6 @@ async def test_render_error_adapter(app: App): 详情
  • ✅ 项目 nonebot-adapter-villa 已发布至 PyPI。
  • -
    -历史测试 -
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • -
    --- @@ -251,7 +243,7 @@ async def test_render_error_plugin(app: App, mocker: MockFixture, mock_datetime)
    历史测试 -
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • +
  • ⚠️ 2023-08-23 09:22:14 CST
  • --- @@ -322,10 +314,6 @@ async def test_render_error_plugin_load_test(app: App): 详情
  • ✅ 项目 主页 返回状态码 200。
  • -
    -历史测试 -
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • -
    --- @@ -389,7 +377,7 @@ async def test_render_error_plugin_metadata(
    历史测试 -
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • +
  • ⚠️ 2023-08-23 09:22:14 CST
  • --- @@ -463,7 +451,7 @@ async def test_render_error_tags_invalid(app: App, mocker: MockFixture, mock_dat
    历史测试 -
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • +
  • ⚠️ 2023-08-23 09:22:14 CST
  • --- @@ -538,7 +526,7 @@ async def test_render_type_error(app: App, mocker: MockFixture, mock_datetime):
    历史测试 -
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • +
  • ⚠️ 2023-08-23 09:22:14 CST
  • --- @@ -600,7 +588,7 @@ async def test_render_unknown_error(app: App, mocker: MockFixture, mock_datetime
    历史测试 -
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • +
  • ⚠️ 2023-08-23 09:22:14 CST
  • --- @@ -677,7 +665,7 @@ async def test_render_http_error(
    历史测试 -
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • ⚠️ 2023-08-23 09:22:14 CST
  • +
  • ⚠️ 2023-08-23 09:22:14 CST
  • --- From ec41e719d8d5f08a7409f6af299f726076d4737e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 26 May 2025 09:54:58 +0000 Subject: [PATCH 03/13] style: auto fix by pre-commit hooks --- src/plugins/github/handlers/github.py | 8 ++++++-- src/plugins/github/handlers/issue.py | 9 ++++++--- src/plugins/github/plugins/publish/__init__.py | 7 ++++--- src/plugins/github/plugins/publish/render.py | 10 ++++++++-- src/plugins/github/plugins/publish/utils.py | 3 ++- tests/plugins/github/handlers/test_github_handler.py | 1 + .../github/publish/utils/test_history_workflow.py | 2 -- tests/providers/docker_test/test_docker_plugin_test.py | 2 +- 8 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/plugins/github/handlers/github.py b/src/plugins/github/handlers/github.py index c3800f01..bca6ed7c 100644 --- a/src/plugins/github/handlers/github.py +++ b/src/plugins/github/handlers/github.py @@ -72,7 +72,9 @@ async def update_comment(self, comment_id: int, comment: str): async def get_self_comment(self, issue_number: int): """获取自己的评论""" - comments: list[IssueComment] = await self.list_comments(issue_number=issue_number) + comments: list[IssueComment] = await self.list_comments( + issue_number=issue_number + ) return next( filter(lambda x: NONEFLOW_MARKER in (x.body if x.body else ""), comments), None, @@ -86,7 +88,9 @@ async def resuable_comment_issue( self_comment = await self.get_self_comment(issue_number=issue_number) await self.comment_issue(comment, issue_number, self_comment) - async def comment_issue(self, comment: str, issue_number: int, self_comment: IssueComment | None = None): + async def comment_issue( + self, comment: str, issue_number: int, self_comment: IssueComment | None = None + ): """发布评论""" logger.info("开始发布评论") diff --git a/src/plugins/github/handlers/issue.py b/src/plugins/github/handlers/issue.py index d949a9e7..6724eae8 100644 --- a/src/plugins/github/handlers/issue.py +++ b/src/plugins/github/handlers/issue.py @@ -112,14 +112,18 @@ async def get_self_comment(self, issue_number: int | None = None): await super().get_self_comment(issue_number) - async def comment_issue(self, comment: str, issue_number: int | None = None, self_comment = None): + async def comment_issue( + self, comment: str, issue_number: int | None = None, self_comment=None + ): """发布评论""" if issue_number is None: issue_number = self.issue_number await super().comment_issue(comment, issue_number, self_comment) - async def resuable_comment_issue(self, comment: str, issue_number: int | None = None): + async def resuable_comment_issue( + self, comment: str, issue_number: int | None = None + ): """发布评论,若之前已评论过,则会进行复用""" if issue_number is None: issue_number = self.issue_number @@ -127,7 +131,6 @@ async def resuable_comment_issue(self, comment: str, issue_number: int | None = self_comment = await self.get_self_comment(issue_number) await self.comment_issue(comment, issue_number, self_comment) - def commit_and_push( self, message: str, diff --git a/src/plugins/github/plugins/publish/__init__.py b/src/plugins/github/plugins/publish/__init__.py index d864fa7c..6ed065ee 100644 --- a/src/plugins/github/plugins/publish/__init__.py +++ b/src/plugins/github/plugins/publish/__init__.py @@ -155,17 +155,18 @@ async def handle_pull_request_and_update_issue( installation_id: int = Depends(get_installation_id), ) -> None: async with bot.as_installation(installation_id): - self_comment = await handler.get_self_comment(handler.issue_number) history: list[tuple[bool, str, datetime]] = [] if self_comment and self_comment.body: history = await get_history_workflow_from_comment(self_comment.body) # 渲染评论信息 - comment = await render_comment(validation, True, history) + comment = await render_comment(validation, True, history) # 对议题评论 - await handler.comment_issue(comment, issue_number=None, self_comment=self_comment) + await handler.comment_issue( + comment, issue_number=None, self_comment=self_comment + ) # 设置拉取请求与议题的标题 # 限制标题长度,过长的标题不好看 diff --git a/src/plugins/github/plugins/publish/render.py b/src/plugins/github/plugins/publish/render.py index e22fc235..aa6e94d5 100644 --- a/src/plugins/github/plugins/publish/render.py +++ b/src/plugins/github/plugins/publish/render.py @@ -48,11 +48,13 @@ def format_time(time: str) -> str: dt = dt.astimezone(tz=TIME_ZONE) return dt.strftime("%Y-%m-%d %H:%M:%S %Z") + def format_datetime(dt: datetime) -> str: """格式化 datetime 对象为字符串""" dt = dt.astimezone(tz=TIME_ZONE) return dt.strftime("%Y-%m-%d %H:%M:%S %Z") + env = jinja2.Environment( loader=jinja2.FileSystemLoader(Path(__file__).parent / "templates"), enable_async=True, @@ -70,12 +72,16 @@ def format_datetime(dt: datetime) -> str: env.filters["format_datetime"] = format_datetime -async def render_comment(result: ValidationDict, reuse: bool = False, history: list[tuple[bool, str, datetime]] | None = None) -> str: +async def render_comment( + result: ValidationDict, + reuse: bool = False, + history: list[tuple[bool, str, datetime]] | None = None, +) -> str: """将验证结果转换为评论内容""" title = f"{result.type}: {result.name}" valid_data = result.valid_data.copy() - + history = history or [] if result.type == PublishType.PLUGIN: diff --git a/src/plugins/github/plugins/publish/utils.py b/src/plugins/github/plugins/publish/utils.py index 0d550364..90556846 100644 --- a/src/plugins/github/plugins/publish/utils.py +++ b/src/plugins/github/plugins/publish/utils.py @@ -1,4 +1,3 @@ - import re from datetime import datetime @@ -191,6 +190,7 @@ async def ensure_issue_plugin_test_button(handler: IssueHandler): await handler.update_issue_body(new_content) + async def ensure_issue_plugin_test_button_in_progress(handler: IssueHandler): """确保议题内容中包含插件测试进行中的提示""" issue_body = handler.issue.body or "" @@ -281,6 +281,7 @@ async def trigger_registry_update(handler: IssueHandler, publish_type: PublishTy ) logger.info("已触发商店列表更新") + async def get_history_workflow_from_comment( comment: str, ) -> list[tuple[bool, str, datetime]]: diff --git a/tests/plugins/github/handlers/test_github_handler.py b/tests/plugins/github/handlers/test_github_handler.py index 94f4d85c..0f7e1708 100644 --- a/tests/plugins/github/handlers/test_github_handler.py +++ b/tests/plugins/github/handlers/test_github_handler.py @@ -241,6 +241,7 @@ async def test_comment_issue(app: App, mocker: MockerFixture) -> None: ) await github_handler.resuable_comment_issue("new comment", 76) + async def test_comment_issue_reuse(app: App, mocker: MockerFixture) -> None: """测试发布评论,复用的情况""" from src.plugins.github.handlers.github import GithubHandler diff --git a/tests/plugins/github/publish/utils/test_history_workflow.py b/tests/plugins/github/publish/utils/test_history_workflow.py index c8e45e74..f0ac9afc 100644 --- a/tests/plugins/github/publish/utils/test_history_workflow.py +++ b/tests/plugins/github/publish/utils/test_history_workflow.py @@ -1,5 +1,3 @@ -import datetime -import zoneinfo from inline_snapshot import snapshot from nonebug import App diff --git a/tests/providers/docker_test/test_docker_plugin_test.py b/tests/providers/docker_test/test_docker_plugin_test.py index 73b68dd2..ca356d54 100644 --- a/tests/providers/docker_test/test_docker_plugin_test.py +++ b/tests/providers/docker_test/test_docker_plugin_test.py @@ -163,7 +163,7 @@ async def test_docker_plugin_test_metadata_some_fields_invalid( mocked_api: MockRouter, mocker: MockerFixture ): """测试 metadata 的部分字段不符合规范""" - from src.providers.docker_test import DockerPluginTest, DockerTestResult, Metadata + from src.providers.docker_test import DockerPluginTest, DockerTestResult mocked_run = mocker.Mock() mocked_run.return_value = json.dumps( From 6b0f46a84411677fac359e6f078ec6ac7f031ec1 Mon Sep 17 00:00:00 2001 From: BigOrangeQWQ <2284086963@qq.com> Date: Mon, 26 May 2025 17:59:51 +0800 Subject: [PATCH 04/13] =?UTF-8?q?test:=20=E6=9B=B4=E6=96=B0=20test=5Fhisto?= =?UTF-8?q?ry=5Fworkflow=20=E7=9A=84=E6=97=B6=E5=8C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/plugins/github/publish/utils/test_history_workflow.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/plugins/github/publish/utils/test_history_workflow.py b/tests/plugins/github/publish/utils/test_history_workflow.py index f0ac9afc..2f9e987c 100644 --- a/tests/plugins/github/publish/utils/test_history_workflow.py +++ b/tests/plugins/github/publish/utils/test_history_workflow.py @@ -6,6 +6,8 @@ async def test_history_workflow(app: App, mock_datetime): from src.plugins.github.plugins.publish.utils import ( get_history_workflow_from_comment, ) + from src.providers.constants import TIME_ZONE + CONTENT = """ # 📃 商店发布检查结果 @@ -38,7 +40,7 @@ async def test_history_workflow(app: App, mock_datetime): """ history = [ - (valid, url, time.strftime("%Y-%m-%d %H:%M:%S %Z")) + (valid, url, time.astimezone(TIME_ZONE).strftime("%Y-%m-%d %H:%M:%S %Z")) for valid, url, time in await get_history_workflow_from_comment(CONTENT) ] assert history == snapshot( From b3971565246a4e83cc4c39bb1b52aac7e7cf5a60 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 26 May 2025 10:03:08 +0000 Subject: [PATCH 05/13] style: auto fix by pre-commit hooks --- tests/plugins/github/publish/utils/test_history_workflow.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/plugins/github/publish/utils/test_history_workflow.py b/tests/plugins/github/publish/utils/test_history_workflow.py index 2f9e987c..a0995eff 100644 --- a/tests/plugins/github/publish/utils/test_history_workflow.py +++ b/tests/plugins/github/publish/utils/test_history_workflow.py @@ -8,7 +8,6 @@ async def test_history_workflow(app: App, mock_datetime): ) from src.providers.constants import TIME_ZONE - CONTENT = """ # 📃 商店发布检查结果 From e94a4f2d30114ab94a653fcf49110e46d89ce23e Mon Sep 17 00:00:00 2001 From: uy/sun Date: Tue, 27 May 2025 01:05:06 +0800 Subject: [PATCH 06/13] =?UTF-8?q?fix:=20CST=20=E7=9A=84=E6=97=B6=E5=8C=BA?= =?UTF-8?q?=E5=BA=94=E8=AF=A5=E5=9B=BA=E5=AE=9A=E4=B8=BA=20Asia/Shanghai?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/github/plugins/publish/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/github/plugins/publish/utils.py b/src/plugins/github/plugins/publish/utils.py index 90556846..37a8adaf 100644 --- a/src/plugins/github/plugins/publish/utils.py +++ b/src/plugins/github/plugins/publish/utils.py @@ -290,7 +290,7 @@ async def get_history_workflow_from_comment( ( status == "✅", action_url, - datetime.strptime(time, "%Y-%m-%d %H:%M:%S CST").astimezone(TIME_ZONE), + datetime.strptime(time, "%Y-%m-%d %H:%M:%S CST").replace(tzinfo=TIME_ZONE), ) for status, action_url, time in WORKFLOW_HISTORY_PATTERN.findall(comment) ] From 4bcb732ea557476f71f810e34b31ae4fd66773aa Mon Sep 17 00:00:00 2001 From: uy/sun Date: Tue, 27 May 2025 01:08:40 +0800 Subject: [PATCH 07/13] =?UTF-8?q?style:=20=E5=B0=86=20datetime=20=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=E7=A7=BB=E8=87=B3=20TYPE=5FCHECKING=20=E5=9D=97?= =?UTF-8?q?=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/github/plugins/publish/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/github/plugins/publish/__init__.py b/src/plugins/github/plugins/publish/__init__.py index 6ed065ee..1d130739 100644 --- a/src/plugins/github/plugins/publish/__init__.py +++ b/src/plugins/github/plugins/publish/__init__.py @@ -1,5 +1,4 @@ -from datetime import datetime -from typing import Literal +from typing import TYPE_CHECKING, Literal from nonebot import logger, on_type from nonebot.adapters.github import ( @@ -50,6 +49,9 @@ validate_plugin_info_from_issue, ) +if TYPE_CHECKING: + from datetime import datetime + async def check_rule( event: IssuesOpened | IssuesReopened | IssuesEdited | IssueCommentCreated, From 0db753154a157bc54d0b37fd4ff2411d30f54e4f Mon Sep 17 00:00:00 2001 From: uy/sun Date: Tue, 27 May 2025 10:19:13 +0800 Subject: [PATCH 08/13] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20get=5Fself=5F?= =?UTF-8?q?comment=20=E6=B2=A1=E6=9C=89=E8=BF=94=E5=9B=9E=E5=80=BC?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C=E5=B9=B6=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/github/handlers/issue.py | 2 +- .../github/handlers/test_github_handler.py | 174 ++++++++++++++++++ .../github/handlers/test_issue_handler.py | 161 ++++++++++++++++ 3 files changed, 336 insertions(+), 1 deletion(-) diff --git a/src/plugins/github/handlers/issue.py b/src/plugins/github/handlers/issue.py index 6724eae8..aa224b2a 100644 --- a/src/plugins/github/handlers/issue.py +++ b/src/plugins/github/handlers/issue.py @@ -110,7 +110,7 @@ async def get_self_comment(self, issue_number: int | None = None): if issue_number is None: issue_number = self.issue_number - await super().get_self_comment(issue_number) + return await super().get_self_comment(issue_number) async def comment_issue( self, comment: str, issue_number: int | None = None, self_comment=None diff --git a/tests/plugins/github/handlers/test_github_handler.py b/tests/plugins/github/handlers/test_github_handler.py index 0f7e1708..cea0010e 100644 --- a/tests/plugins/github/handlers/test_github_handler.py +++ b/tests/plugins/github/handlers/test_github_handler.py @@ -973,3 +973,177 @@ async def test_to_issue_handler(app: App, mocker: MockerFixture) -> None: issue_handler = await github_handler.to_issue_handler(123) assert isinstance(issue_handler, IssueHandler) assert issue_handler.issue == mock_issue + + +async def test_get_self_comment(app: App, mocker: MockerFixture) -> None: + """测试获取自己的评论""" + from src.plugins.github.handlers.github import GithubHandler + from src.plugins.github.models import RepoInfo + + mock_comment_bot = mocker.MagicMock() + mock_comment_bot.body = "bot comment\n" + mock_comment_bot.id = 123 + + mock_comment_user = mocker.MagicMock() + mock_comment_user.body = "user comment" + mock_comment_user.id = 456 + + mock_comments_resp = mocker.MagicMock() + mock_comments_resp.parsed_data = [mock_comment_user, mock_comment_bot] + + async with app.test_api() as ctx: + _, bot = get_github_bot(ctx) + + github_handler = GithubHandler( + bot=bot, + repo_info=RepoInfo(owner="owner", repo="repo"), + ) + + should_call_apis( + ctx, + [ + GitHubApi( + api="rest.issues.async_list_comments", result=mock_comments_resp + ), + ], + snapshot( + { + 0: { + "owner": "owner", + "repo": "repo", + "issue_number": 76, + }, + } + ), + ) + comment = await github_handler.get_self_comment(76) + assert comment == mock_comment_bot + + +async def test_get_self_comment_not_found(app: App, mocker: MockerFixture) -> None: + """测试获取自己的评论,未找到的情况""" + from src.plugins.github.handlers.github import GithubHandler + from src.plugins.github.models import RepoInfo + + mock_comment_user = mocker.MagicMock() + mock_comment_user.body = "user comment" + mock_comment_user.id = 456 + + mock_comments_resp = mocker.MagicMock() + mock_comments_resp.parsed_data = [mock_comment_user] + + async with app.test_api() as ctx: + _, bot = get_github_bot(ctx) + + github_handler = GithubHandler( + bot=bot, + repo_info=RepoInfo(owner="owner", repo="repo"), + ) + + should_call_apis( + ctx, + [ + GitHubApi( + api="rest.issues.async_list_comments", result=mock_comments_resp + ), + ], + snapshot( + { + 0: { + "owner": "owner", + "repo": "repo", + "issue_number": 76, + }, + } + ), + ) + comment = await github_handler.get_self_comment(76) + assert comment is None + + +async def test_comment_issue_new(app: App, mocker: MockerFixture) -> None: + """测试发布评论,新建评论的情况""" + from src.plugins.github.handlers.github import GithubHandler + from src.plugins.github.models import RepoInfo + + async with app.test_api() as ctx: + _, bot = get_github_bot(ctx) + + github_handler = GithubHandler( + bot=bot, + repo_info=RepoInfo(owner="owner", repo="repo"), + ) + + should_call_apis( + ctx, + [ + GitHubApi(api="rest.issues.async_create_comment", result=True), + ], + snapshot( + { + 0: { + "owner": "owner", + "repo": "repo", + "issue_number": 76, + "body": "new comment", + }, + } + ), + ) + await github_handler.comment_issue("new comment", 76) + + +async def test_comment_issue_update(app: App, mocker: MockerFixture) -> None: + """测试发布评论,更新已有评论的情况""" + from src.plugins.github.handlers.github import GithubHandler + from src.plugins.github.models import RepoInfo + + mock_comment = mocker.MagicMock() + mock_comment.body = "old comment\n" + mock_comment.id = 123 + + async with app.test_api() as ctx: + _, bot = get_github_bot(ctx) + + github_handler = GithubHandler( + bot=bot, + repo_info=RepoInfo(owner="owner", repo="repo"), + ) + + should_call_apis( + ctx, + [ + GitHubApi(api="rest.issues.async_update_comment", result=True), + ], + snapshot( + { + 0: { + "owner": "owner", + "repo": "repo", + "comment_id": 123, + "body": "new comment", + }, + } + ), + ) + await github_handler.comment_issue("new comment", 76, mock_comment) + + +async def test_comment_issue_no_change(app: App, mocker: MockerFixture) -> None: + """测试发布评论,评论内容无变化的情况""" + from src.plugins.github.handlers.github import GithubHandler + from src.plugins.github.models import RepoInfo + + mock_comment = mocker.MagicMock() + mock_comment.body = "same comment" + mock_comment.id = 123 + + async with app.test_api() as ctx: + _, bot = get_github_bot(ctx) + + github_handler = GithubHandler( + bot=bot, + repo_info=RepoInfo(owner="owner", repo="repo"), + ) + + await github_handler.comment_issue("same comment", 76, mock_comment) diff --git a/tests/plugins/github/handlers/test_issue_handler.py b/tests/plugins/github/handlers/test_issue_handler.py index c1ce311f..82d114a4 100644 --- a/tests/plugins/github/handlers/test_issue_handler.py +++ b/tests/plugins/github/handlers/test_issue_handler.py @@ -443,3 +443,164 @@ async def test_commit_and_push(app: App, mocker: MockerFixture) -> None: call(["git", "push", "origin", "main", "-f"]), ], ) + + +async def test_get_self_comment(app: App, mocker: MockerFixture) -> None: + """测试获取自己的评论""" + from src.plugins.github.handlers.issue import IssueHandler + from src.plugins.github.models import RepoInfo + + mock_comment_bot = mocker.MagicMock() + mock_comment_bot.body = "bot comment\n" + mock_comment_bot.id = 123 + + mock_comment_user = mocker.MagicMock() + mock_comment_user.body = "user comment" + mock_comment_user.id = 456 + + mock_comments_resp = mocker.MagicMock() + mock_comments_resp.parsed_data = [mock_comment_user, mock_comment_bot] + + mock_issue = mocker.MagicMock(spec=Issue) + mock_issue.number = 76 + + async with app.test_api() as ctx: + _, bot = get_github_bot(ctx) + + issue_handler = IssueHandler( + bot=bot, + repo_info=RepoInfo(owner="owner", repo="repo"), + issue=mock_issue, + ) + + should_call_apis( + ctx, + [ + GitHubApi( + api="rest.issues.async_list_comments", result=mock_comments_resp + ), + ], + snapshot( + { + 0: {"owner": "owner", "repo": "repo", "issue_number": 76}, + } + ), + ) + comment = await issue_handler.get_self_comment(76) + assert comment == mock_comment_bot + + +async def test_get_self_comment_not_found(app: App, mocker: MockerFixture) -> None: + """测试获取自己的评论,未找到的情况""" + from src.plugins.github.handlers.issue import IssueHandler + from src.plugins.github.models import RepoInfo + + mock_comment_user = mocker.MagicMock() + mock_comment_user.id = 123 + mock_comment_user.body = "bot comment" + mock_comments_resp = mocker.MagicMock() + mock_comments_resp.parsed_data = [mock_comment_user] + + mock_issue = mocker.MagicMock(spec=Issue) + mock_issue.number = 76 + + async with app.test_api() as ctx: + _, bot = get_github_bot(ctx) + + issue_handler = IssueHandler( + bot=bot, + repo_info=RepoInfo(owner="owner", repo="repo"), + issue=mock_issue, + ) + + should_call_apis( + ctx, + [ + GitHubApi( + api="rest.issues.async_list_comments", result=mock_comments_resp + ), + ], + snapshot( + { + 0: {"owner": "owner", "repo": "repo", "issue_number": 76}, + } + ), + ) + comment = await issue_handler.get_self_comment(76) + assert comment is None + + +async def test_comment_issue_new(app: App, mocker: MockerFixture) -> None: + """测试发布新评论""" + from src.plugins.github.handlers.issue import IssueHandler + from src.plugins.github.models import RepoInfo + + mock_issue = mocker.MagicMock(spec=Issue) + mock_issue.number = 76 + + async with app.test_api() as ctx: + _, bot = get_github_bot(ctx) + + issue_handler = IssueHandler( + bot=bot, + repo_info=RepoInfo(owner="owner", repo="repo"), + issue=mock_issue, + ) + + should_call_apis( + ctx, + [ + GitHubApi(api="rest.issues.async_create_comment", result=True), + ], + snapshot( + { + 0: { + "owner": "owner", + "repo": "repo", + "issue_number": 76, + "body": "test comment", + }, + } + ), + ) + await issue_handler.comment_issue("test comment") + + +async def test_comment_issue_update_existing(app: App, mocker: MockerFixture) -> None: + """测试更新已存在的评论""" + from src.plugins.github.handlers.issue import IssueHandler + from src.plugins.github.models import RepoInfo + + mock_comment = mocker.MagicMock() + mock_comment.id = 123 + mock_comment.body = "old comment" + + mock_issue = mocker.MagicMock(spec=Issue) + mock_issue.number = 76 + + async with app.test_api() as ctx: + _, bot = get_github_bot(ctx) + + issue_handler = IssueHandler( + bot=bot, + repo_info=RepoInfo(owner="owner", repo="repo"), + issue=mock_issue, + ) + + should_call_apis( + ctx, + [ + GitHubApi(api="rest.issues.async_update_comment", result=True), + ], + snapshot( + { + 0: { + "owner": "owner", + "repo": "repo", + "comment_id": 123, + "body": "updated comment", + }, + } + ), + ) + await issue_handler.comment_issue("updated comment", self_comment=mock_comment) From cf17244c32555b34e433146bab0b0eb1cd6bc7b4 Mon Sep 17 00:00:00 2001 From: uy/sun Date: Tue, 27 May 2025 10:49:25 +0800 Subject: [PATCH 09/13] =?UTF-8?q?refactor:=20=E7=AE=80=E5=8D=95=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E5=86=99=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/github/plugins/publish/__init__.py | 5 ++--- tests/providers/docker_test/test_docker_plugin_test.py | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/plugins/github/plugins/publish/__init__.py b/src/plugins/github/plugins/publish/__init__.py index 1d130739..f56300ae 100644 --- a/src/plugins/github/plugins/publish/__init__.py +++ b/src/plugins/github/plugins/publish/__init__.py @@ -158,6 +158,7 @@ async def handle_pull_request_and_update_issue( ) -> None: async with bot.as_installation(installation_id): self_comment = await handler.get_self_comment(handler.issue_number) + history: list[tuple[bool, str, datetime]] = [] if self_comment and self_comment.body: history = await get_history_workflow_from_comment(self_comment.body) @@ -166,9 +167,7 @@ async def handle_pull_request_and_update_issue( comment = await render_comment(validation, True, history) # 对议题评论 - await handler.comment_issue( - comment, issue_number=None, self_comment=self_comment - ) + await handler.comment_issue(comment, self_comment=self_comment) # 设置拉取请求与议题的标题 # 限制标题长度,过长的标题不好看 diff --git a/tests/providers/docker_test/test_docker_plugin_test.py b/tests/providers/docker_test/test_docker_plugin_test.py index ca356d54..f4b2944a 100644 --- a/tests/providers/docker_test/test_docker_plugin_test.py +++ b/tests/providers/docker_test/test_docker_plugin_test.py @@ -200,7 +200,7 @@ async def test_docker_plugin_test_metadata_some_fields_invalid( "homepage": 12, "type": True, "supported_adapters": {}, - }, + }, # type: ignore output="test", run=True, test_env="python==3.12", From a4fc7636559bb69d9d6d028d7e8dda38380f639c Mon Sep 17 00:00:00 2001 From: uy/sun Date: Tue, 27 May 2025 11:12:08 +0800 Subject: [PATCH 10/13] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=8E=86?= =?UTF-8?q?=E5=8F=B2=E8=AE=B0=E5=BD=95=E6=8E=92=E5=BA=8F=E5=92=8C=E6=95=B0?= =?UTF-8?q?=E9=87=8F=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/github/plugins/publish/render.py | 5 + .../publish/render/test_publish_render.py | 111 +++++++++++++++++- 2 files changed, 115 insertions(+), 1 deletion(-) diff --git a/src/plugins/github/plugins/publish/render.py b/src/plugins/github/plugins/publish/render.py index aa6e94d5..58fb8638 100644 --- a/src/plugins/github/plugins/publish/render.py +++ b/src/plugins/github/plugins/publish/render.py @@ -140,6 +140,11 @@ async def render_comment( ) ) + # 测试历史应该时间倒序排列 + history.sort(key=lambda x: x[2], reverse=True) + # 限制最多显示 10 条历史 + history = history[:10] + template = env.get_template("comment.md.jinja") return await template.render_async( card=" ".join(card), diff --git a/tests/plugins/github/publish/render/test_publish_render.py b/tests/plugins/github/publish/render/test_publish_render.py index d2861800..ff82c282 100644 --- a/tests/plugins/github/publish/render/test_publish_render.py +++ b/tests/plugins/github/publish/render/test_publish_render.py @@ -1,7 +1,9 @@ +from datetime import datetime + from inline_snapshot import snapshot from nonebug import App -from tests.providers.validation.utils import generate_bot_data +from tests.providers.validation.utils import generate_bot_data, generate_plugin_data async def test_render_empty(app: App): @@ -71,3 +73,110 @@ async def test_render_reuse(app: App): """ ) + + +async def test_render_history(app: App): + """测试历史记录渲染,包括排序和数量限制""" + + from src.plugins.github.plugins.publish.render import render_comment + from src.providers.constants import TIME_ZONE + from src.providers.validation import ( + PluginPublishInfo, + PublishType, + ValidationDict, + ) + + # 创建多个历史记录用于测试排序和数量限制 + history = [ + ( + False, + "https://github.com/nonebot/nonebot2/actions/runs/14156878700", + datetime(2020, 10, 2, 12, 0, 18, tzinfo=TIME_ZONE), + ), + ( + True, + "https://github.com/nonebot/nonebot2/actions/runs/14156878699", + datetime(2020, 10, 1, 12, 0, 18, tzinfo=TIME_ZONE), + ), + ( + True, + "https://github.com/nonebot/nonebot2/actions/runs/14156878701", + datetime(2020, 10, 3, 12, 0, 18, tzinfo=TIME_ZONE), + ), + ( + True, + "https://github.com/nonebot/nonebot2/actions/runs/14156878702", + datetime(2020, 10, 4, 12, 0, 18, tzinfo=TIME_ZONE), + ), + ( + False, + "https://github.com/nonebot/nonebot2/actions/runs/14156878703", + datetime(2020, 10, 5, 12, 0, 18, tzinfo=TIME_ZONE), + ), + ( + True, + "https://github.com/nonebot/nonebot2/actions/runs/14156878704", + datetime(2020, 10, 6, 12, 0, 18, tzinfo=TIME_ZONE), + ), + ( + False, + "https://github.com/nonebot/nonebot2/actions/runs/14156878705", + datetime(2020, 10, 7, 12, 0, 18, tzinfo=TIME_ZONE), + ), + ( + True, + "https://github.com/nonebot/nonebot2/actions/runs/14156878706", + datetime(2020, 10, 8, 12, 0, 18, tzinfo=TIME_ZONE), + ), + ( + False, + "https://github.com/nonebot/nonebot2/actions/runs/14156878707", + datetime(2020, 10, 9, 12, 0, 18, tzinfo=TIME_ZONE), + ), + ( + True, + "https://github.com/nonebot/nonebot2/actions/runs/14156878708", + datetime(2020, 10, 10, 12, 0, 18, tzinfo=TIME_ZONE), + ), + ] + + result = ValidationDict( + type=PublishType.PLUGIN, + raw_data={ + "name": "name", + "load": True, + }, + info=PluginPublishInfo.model_construct(**generate_plugin_data()), + ) + + comment = await render_comment(result, history=history) + assert comment == snapshot( + """\ +# 📃 商店发布检查结果 + +> Plugin: name + +[![测试结果](https://img.shields.io/badge/RESULT-OK-green?style=for-the-badge)](https://github.com/owner/repo/actions/runs/123456) + +**✅ 所有测试通过,一切准备就绪!** + + +
    +详情 +
  • ✅ 插件 加载测试 通过。
  • +
    +
    +历史测试 +
  • 2023-08-23 09:22:14 CST
  • 2020-10-10 12:00:18 CST
  • ⚠️ 2020-10-09 12:00:18 CST
  • 2020-10-08 12:00:18 CST
  • ⚠️ 2020-10-07 12:00:18 CST
  • 2020-10-06 12:00:18 CST
  • ⚠️ 2020-10-05 12:00:18 CST
  • 2020-10-04 12:00:18 CST
  • 2020-10-03 12:00:18 CST
  • ⚠️ 2020-10-02 12:00:18 CST
  • +
    + +--- + +💡 如需修改信息,请直接修改 issue,机器人会自动更新检查结果。 +💡 当插件加载测试失败时,请发布新版本后勾选插件测试勾选框重新运行插件测试。 + + +💪 Powered by [NoneFlow](https://github.com/nonebot/noneflow) + +""" + ) From ce17b5e6b58e3e100fb9ae4eb3b194c6f95b658a Mon Sep 17 00:00:00 2001 From: uy/sun Date: Tue, 27 May 2025 11:16:40 +0800 Subject: [PATCH 11/13] =?UTF-8?q?test:=20=E7=A7=BB=E9=99=A4=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E5=87=BD=E6=95=B0=E4=B8=AD=E7=9A=84=20mock=5Fdatetime?= =?UTF-8?q?=20=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../github/config/process/test_config_check.py | 1 - .../config/utils/test_config_update_file.py | 6 +----- .../render/test_publish_render_error.py | 18 ++++++------------ .../publish/utils/test_history_workflow.py | 2 +- .../providers/store_test/test_step_summary.py | 5 +---- .../store_test/test_validate_plugin.py | 12 +++++------- 6 files changed, 14 insertions(+), 30 deletions(-) diff --git a/tests/plugins/github/config/process/test_config_check.py b/tests/plugins/github/config/process/test_config_check.py index 5e6308d9..f8f37d9c 100644 --- a/tests/plugins/github/config/process/test_config_check.py +++ b/tests/plugins/github/config/process/test_config_check.py @@ -28,7 +28,6 @@ async def test_process_config_check( tmp_path: Path, mock_installation, mock_results: dict[str, Path], - mock_datetime, ) -> None: """测试发布检查不通过""" from src.providers.docker_test import Metadata diff --git a/tests/plugins/github/config/utils/test_config_update_file.py b/tests/plugins/github/config/utils/test_config_update_file.py index ce4b56bc..70deb84c 100644 --- a/tests/plugins/github/config/utils/test_config_update_file.py +++ b/tests/plugins/github/config/utils/test_config_update_file.py @@ -9,11 +9,7 @@ async def test_update_file( - app: App, - mocker: MockerFixture, - tmp_path: Path, - mock_results: dict[str, Path], - mock_datetime, + app: App, mocker: MockerFixture, tmp_path: Path, mock_results: dict[str, Path] ) -> None: from src.plugins.github.plugins.config.utils import update_file from src.providers.validation.models import ( diff --git a/tests/plugins/github/publish/render/test_publish_render_error.py b/tests/plugins/github/publish/render/test_publish_render_error.py index dcb2db20..90fc6429 100644 --- a/tests/plugins/github/publish/render/test_publish_render_error.py +++ b/tests/plugins/github/publish/render/test_publish_render_error.py @@ -158,7 +158,7 @@ async def test_render_error_adapter(app: App): ) -async def test_render_error_plugin(app: App, mocker: MockFixture, mock_datetime): +async def test_render_error_plugin(app: App, mocker: MockFixture): """插件数据""" from src.plugins.github.plugins.publish.render import render_comment from src.providers.validation import PublishType, ValidationDict @@ -327,9 +327,7 @@ async def test_render_error_plugin_load_test(app: App): ) -async def test_render_error_plugin_metadata( - app: App, mocker: MockFixture, mock_datetime -): +async def test_render_error_plugin_metadata(app: App, mocker: MockFixture): """插件加载成功,但缺少元数据的情况""" from src.plugins.github.plugins.publish.render import render_comment from src.providers.validation import PublishType, ValidationDict @@ -392,7 +390,7 @@ async def test_render_error_plugin_metadata( ) -async def test_render_error_tags_invalid(app: App, mocker: MockFixture, mock_datetime): +async def test_render_error_tags_invalid(app: App, mocker: MockFixture): """标签不合法的情况""" from src.plugins.github.plugins.publish.render import render_comment from src.providers.validation import PublishType, ValidationDict @@ -466,7 +464,7 @@ async def test_render_error_tags_invalid(app: App, mocker: MockFixture, mock_dat ) -async def test_render_type_error(app: App, mocker: MockFixture, mock_datetime): +async def test_render_type_error(app: App, mocker: MockFixture): """插件类型与适配器错误""" from src.plugins.github.plugins.publish.render import render_comment from src.providers.validation import PublishType, ValidationDict @@ -541,7 +539,7 @@ async def test_render_type_error(app: App, mocker: MockFixture, mock_datetime): ) -async def test_render_unknown_error(app: App, mocker: MockFixture, mock_datetime): +async def test_render_unknown_error(app: App, mocker: MockFixture): """未知错误""" from src.plugins.github.plugins.publish.render import render_comment from src.providers.validation import PublishType, ValidationDict @@ -603,11 +601,7 @@ async def test_render_unknown_error(app: App, mocker: MockFixture, mock_datetime ) -async def test_render_http_error( - app: App, - mocker: MockFixture, - mock_datetime, -): +async def test_render_http_error(app: App, mocker: MockFixture): """网络请求报错""" from src.plugins.github.plugins.publish.render import render_comment from src.providers.validation import PublishType, ValidationDict diff --git a/tests/plugins/github/publish/utils/test_history_workflow.py b/tests/plugins/github/publish/utils/test_history_workflow.py index a0995eff..e6a6c12b 100644 --- a/tests/plugins/github/publish/utils/test_history_workflow.py +++ b/tests/plugins/github/publish/utils/test_history_workflow.py @@ -2,7 +2,7 @@ from nonebug import App -async def test_history_workflow(app: App, mock_datetime): +async def test_history_workflow(app: App): from src.plugins.github.plugins.publish.utils import ( get_history_workflow_from_comment, ) diff --git a/tests/providers/store_test/test_step_summary.py b/tests/providers/store_test/test_step_summary.py index 1a72c6c5..f4e4dfb5 100644 --- a/tests/providers/store_test/test_step_summary.py +++ b/tests/providers/store_test/test_step_summary.py @@ -6,10 +6,7 @@ async def test_step_summary( - mocked_store_data: dict[str, Path], - mocked_api: MockRouter, - mocker: MockerFixture, - mock_datetime, + mocked_store_data: dict[str, Path], mocked_api: MockRouter, mocker: MockerFixture ) -> None: """验证插件信息""" from src.providers.models import StoreTestResult diff --git a/tests/providers/store_test/test_validate_plugin.py b/tests/providers/store_test/test_validate_plugin.py index 2c40c5d1..1a66a15d 100644 --- a/tests/providers/store_test/test_validate_plugin.py +++ b/tests/providers/store_test/test_validate_plugin.py @@ -22,9 +22,7 @@ def mock_docker_result(path: Path, mocker: MockerFixture): return mock_plugin_test -async def test_validate_plugin( - mocked_api: MockRouter, mocker: MockerFixture, mock_datetime -) -> None: +async def test_validate_plugin(mocked_api: MockRouter, mocker: MockerFixture) -> None: """验证插件信息""" from src.providers.models import RegistryPlugin, StorePlugin, StoreTestResult from src.providers.store_test.validation import validate_plugin @@ -90,7 +88,7 @@ async def test_validate_plugin( async def test_validate_plugin_with_previous( - mocked_api: MockRouter, mocker: MockerFixture, mock_datetime + mocked_api: MockRouter, mocker: MockerFixture ) -> None: """插件验证通过,但提供了之前插件信息的情况 @@ -181,7 +179,7 @@ async def test_validate_plugin_with_previous( async def test_validate_plugin_skip_test( - mocked_api: MockRouter, mocker: MockerFixture, mock_datetime + mocked_api: MockRouter, mocker: MockerFixture ) -> None: """跳过插件测试的情况 @@ -251,7 +249,7 @@ async def test_validate_plugin_skip_test( async def test_validate_plugin_skip_test_plugin_test_failed( - mocked_api: MockRouter, mocker: MockerFixture, mock_datetime + mocked_api: MockRouter, mocker: MockerFixture ) -> None: """跳过插件测试的情况 @@ -360,7 +358,7 @@ async def test_validate_plugin_skip_test_plugin_test_failed( async def test_validate_plugin_failed_with_previous( - mocked_api: MockRouter, mocker: MockerFixture, mock_datetime + mocked_api: MockRouter, mocker: MockerFixture ) -> None: """插件验证失败,但提供了之前插件信息的情况 From bc2af4e6d0c33784ccb7572c6b729acfa145c489 Mon Sep 17 00:00:00 2001 From: uy/sun Date: Tue, 27 May 2025 11:26:14 +0800 Subject: [PATCH 12/13] =?UTF-8?q?test:=20=E7=A7=BB=E9=99=A4=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E4=B8=AD=20get=5Fself=5Fcomment=20=E7=A1=AC=E7=BC=96?= =?UTF-8?q?=E7=A0=81=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/plugins/github/handlers/test_issue_handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/plugins/github/handlers/test_issue_handler.py b/tests/plugins/github/handlers/test_issue_handler.py index 82d114a4..0183a36c 100644 --- a/tests/plugins/github/handlers/test_issue_handler.py +++ b/tests/plugins/github/handlers/test_issue_handler.py @@ -486,7 +486,7 @@ async def test_get_self_comment(app: App, mocker: MockerFixture) -> None: } ), ) - comment = await issue_handler.get_self_comment(76) + comment = await issue_handler.get_self_comment() assert comment == mock_comment_bot @@ -526,7 +526,7 @@ async def test_get_self_comment_not_found(app: App, mocker: MockerFixture) -> No } ), ) - comment = await issue_handler.get_self_comment(76) + comment = await issue_handler.get_self_comment() assert comment is None From 08e3f4afc8e2670d913feb60f741c6d36d5415bc Mon Sep 17 00:00:00 2001 From: uy/sun Date: Tue, 27 May 2025 15:49:50 +0800 Subject: [PATCH 13/13] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7045a3c..46c7a364 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] +### Added + +- 在 Noneflow 工作流评论处增设 Noneflow 运行历史 + ## [4.3.1] - 2025-05-10 ### Fixed