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 = """[]({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://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