Skip to content

Commit 1cd5019

Browse files
authored
fix: 修复解决冲突验证失败时未能正常跳过的问题 (#266)
顺便调整了 remove 插件中的 update_file
1 parent 5a84de3 commit 1cd5019

File tree

5 files changed

+124
-44
lines changed

5 files changed

+124
-44
lines changed

src/plugins/github/plugins/publish/utils.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,6 @@ async def resolve_conflict_pull_requests(
9696
issue_handler = await handler.to_issue_handler(issue_number)
9797

9898
if publish_type:
99-
# 需要先获取远程分支,否则无法切换到对应分支
100-
run_shell_command(["git", "fetch", "origin"])
101-
# 因为当前分支为触发处理冲突的分支,所以需要切换到每个拉取请求对应的分支
102-
run_shell_command(["git", "checkout", pull.head.ref])
103-
10499
# 重新测试
105100
match publish_type:
106101
case PublishType.ADAPTER:
@@ -112,14 +107,19 @@ async def resolve_conflict_pull_requests(
112107
case _:
113108
raise ValueError("暂不支持的发布类型")
114109

115-
# 回到主分支
110+
# 如果信息验证失败,则跳过更新
111+
if not result.valid:
112+
logger.error("信息验证失败,已跳过")
113+
continue
114+
115+
# 每次切换前都要确保回到主分支
116116
run_shell_command(["git", "checkout", plugin_config.input_config.base])
117117
# 切换到对应分支
118118
run_shell_command(["git", "switch", "-C", pull.head.ref])
119119
# 更新文件
120120
update_file(result)
121-
message = commit_message(result.type, result.name, issue_number)
122121

122+
message = commit_message(result.type, result.name, issue_number)
123123
issue_handler.commit_and_push(message, pull.head.ref)
124124

125125
logger.info("拉取请求更新完毕")

src/plugins/github/plugins/remove/utils.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from githubkit.exception import RequestFailed
22
from nonebot import logger
3+
from pydantic_core import PydanticCustomError
34

45
from src.plugins.github import plugin_config
56
from src.plugins.github.depends.utils import (
@@ -16,11 +17,11 @@
1617
from .validation import RemoveInfo, load_publish_data, validate_author_info
1718

1819

19-
def update_file(type: PublishType, key: str):
20+
def update_file(result: RemoveInfo):
2021
"""删除对应的包储存在 registry 里的数据"""
2122
logger.info("开始更新文件")
2223

23-
match type:
24+
match result.publish_type:
2425
case PublishType.PLUGIN:
2526
path = plugin_config.input_config.plugin_path
2627
case PublishType.BOT:
@@ -30,9 +31,9 @@ def update_file(type: PublishType, key: str):
3031
case _:
3132
raise ValueError("不支持的删除类型")
3233

33-
data = load_publish_data(type)
34+
data = load_publish_data(result.publish_type)
3435
# 删除对应的数据项
35-
data.pop(key)
36+
data.pop(result.key)
3637
dump_json5(path, list(data.values()))
3738
logger.info(f"已更新 {path.name} 文件")
3839

@@ -52,7 +53,7 @@ async def process_pull_reqeusts(
5253
# 切换分支
5354
run_shell_command(["git", "switch", "-C", branch_name])
5455
# 更新文件并提交更改
55-
update_file(result.publish_type, result.key)
56+
update_file(result)
5657
store_handler.commit_and_push(message, branch_name, author=handler.author)
5758
# 创建拉取请求
5859
logger.info("开始创建拉取请求")
@@ -95,19 +96,22 @@ async def resolve_conflict_pull_requests(
9596
issue_handler = await handler.to_issue_handler(issue_number)
9697

9798
if publish_type:
98-
# 需要先获取远程分支,否则无法切换到对应分支
99-
run_shell_command(["git", "fetch", "origin"])
100-
# 当前分支未触发处理冲突的分支,切换到主分支后验证其它的删除请求
99+
# 验证作者信息
100+
try:
101+
result = await validate_author_info(issue_handler.issue, publish_type)
102+
except PydanticCustomError as e:
103+
logger.error(f"验证作者信息失败: {e}")
104+
continue
105+
106+
# 每次切换前都要确保回到主分支
101107
run_shell_command(["git", "checkout", plugin_config.input_config.base])
102-
# 再验证作者信息
103-
result = await validate_author_info(issue_handler.issue, publish_type)
104108
# 切换到对应分支
105109
run_shell_command(["git", "switch", "-C", pull.head.ref])
106110
# 更新文件
107-
update_file(publish_type, result.key)
111+
update_file(result)
112+
108113
# 生成提交信息并推送
109114
message = commit_message(COMMIT_MESSAGE_PREFIX, result.name, issue_number)
110-
111115
issue_handler.commit_and_push(message, pull.head.ref)
112116

113117
logger.info("拉取请求更新完毕")

tests/github/publish/utils/test_publish_resolve_conflict_pull_requests.py

Lines changed: 92 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,6 @@ async def test_resolve_conflict_pull_requests_adapter(
8080
# 测试 git 命令
8181
mock_subprocess_run.assert_has_calls(
8282
[
83-
mocker.call(["git", "fetch", "origin"], check=True, capture_output=True),
84-
mocker.call(
85-
["git", "checkout", "publish/issue1"], check=True, capture_output=True
86-
),
8783
mocker.call(["git", "checkout", "master"], check=True, capture_output=True),
8884
mocker.call(
8985
["git", "switch", "-C", "publish/issue1"],
@@ -213,10 +209,6 @@ async def test_resolve_conflict_pull_requests_bot(
213209
# 测试 git 命令
214210
mock_subprocess_run.assert_has_calls(
215211
[
216-
mocker.call(["git", "fetch", "origin"], check=True, capture_output=True),
217-
mocker.call(
218-
["git", "checkout", "publish/issue1"], check=True, capture_output=True
219-
),
220212
mocker.call(["git", "checkout", "master"], check=True, capture_output=True),
221213
mocker.call(
222214
["git", "switch", "-C", "publish/issue1"],
@@ -364,10 +356,6 @@ async def test_resolve_conflict_pull_requests_plugin(
364356
# 测试 git 命令
365357
mock_subprocess_run.assert_has_calls(
366358
[
367-
mocker.call(["git", "fetch", "origin"], check=True, capture_output=True),
368-
mocker.call(
369-
["git", "checkout", "publish/issue1"], check=True, capture_output=True
370-
),
371359
mocker.call(["git", "checkout", "master"], check=True, capture_output=True),
372360
mocker.call(
373361
["git", "switch", "-C", "publish/issue1"],
@@ -437,6 +425,98 @@ async def test_resolve_conflict_pull_requests_plugin(
437425
assert mocked_api["homepage"].called
438426

439427

428+
async def test_resolve_conflict_pull_requests_plugin_not_valid(
429+
app: App, mocker: MockerFixture, mocked_api: MockRouter, tmp_path: Path, mock_pull
430+
) -> None:
431+
"""测试插件信息不合法的情况"""
432+
from src.plugins.github import plugin_config
433+
from src.plugins.github.models import GithubHandler, RepoInfo
434+
from src.plugins.github.plugins.publish.utils import resolve_conflict_pull_requests
435+
from src.providers.utils import dump_json5
436+
437+
mock_subprocess_run = mocker.patch("subprocess.run")
438+
mock_result = mocker.MagicMock()
439+
mock_subprocess_run.side_effect = lambda *args, **kwargs: mock_result
440+
441+
mock_label = mocker.MagicMock()
442+
mock_label.name = "Plugin"
443+
444+
mock_issue_repo = mocker.MagicMock()
445+
mock_issue = MockIssue(
446+
number=1,
447+
body=MockBody(type="plugin").generate(),
448+
user=MockUser(login="he0119", id=1),
449+
).as_mock(mocker)
450+
mock_issue_repo.parsed_data = mock_issue
451+
452+
mock_pull.labels = [mock_label]
453+
mock_pull.title = "Plugin: 帮助"
454+
455+
mock_comment = mocker.MagicMock()
456+
mock_comment.body = "Plugin: test"
457+
mock_list_comments_resp = mocker.MagicMock()
458+
mock_list_comments_resp.parsed_data = [mock_comment]
459+
460+
mock_test_result = mocker.MagicMock()
461+
mock_test_result.load = False
462+
mock_test_result.metadata = None
463+
mock_docker = mocker.patch("src.providers.docker_test.DockerPluginTest.run")
464+
mock_docker.return_value = mock_test_result
465+
466+
dump_json5(
467+
tmp_path / "plugins.json5",
468+
[
469+
{
470+
"module_name": "nonebot_plugin_treehelp",
471+
"project_link": "nonebot-plugin-treehelp",
472+
"author_id": 1,
473+
"tags": [],
474+
"is_official": True,
475+
}
476+
],
477+
)
478+
479+
async with app.test_api() as ctx:
480+
adapter, bot = get_github_bot(ctx)
481+
482+
handler = GithubHandler(bot=bot, repo_info=RepoInfo(owner="owner", repo="repo"))
483+
484+
ctx.should_call_api(
485+
"rest.issues.async_get",
486+
snapshot({"owner": "owner", "repo": "repo", "issue_number": 1}),
487+
mock_issue_repo,
488+
)
489+
ctx.should_call_api(
490+
"rest.issues.async_list_comments",
491+
{"owner": "owner", "repo": "repo", "issue_number": 1},
492+
mock_list_comments_resp,
493+
)
494+
495+
await resolve_conflict_pull_requests(handler, [mock_pull])
496+
497+
# 测试 git 命令
498+
mock_subprocess_run.assert_not_called()
499+
500+
# 检查文件是否正确
501+
# 因为没有进行 git 操作,所有会有两个插件信息
502+
check_json_data(
503+
plugin_config.input_config.plugin_path,
504+
snapshot(
505+
[
506+
{
507+
"module_name": "nonebot_plugin_treehelp",
508+
"project_link": "nonebot-plugin-treehelp",
509+
"author_id": 1,
510+
"tags": [],
511+
"is_official": True,
512+
},
513+
]
514+
),
515+
)
516+
517+
assert not mocked_api["homepage"].called
518+
519+
440520
async def test_resolve_conflict_pull_requests_draft(
441521
app: App, mocker: MockerFixture, mocked_api: MockRouter, tmp_path: Path
442522
) -> None:

tests/github/remove/utils/test_remove_resolve_pull_requests.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ async def test_resolve_conflict_pull_requests_bot(
8787
# 测试 git 命令
8888
mock_subprocess_run.assert_has_calls(
8989
[
90-
mocker.call(["git", "fetch", "origin"], check=True, capture_output=True),
9190
mocker.call(["git", "checkout", "master"], check=True, capture_output=True),
9291
mocker.call(
9392
["git", "switch", "-C", "remove/issue1"],
@@ -196,7 +195,6 @@ async def test_resolve_conflict_pull_requests_plugin(
196195
# 测试 git 命令
197196
mock_subprocess_run.assert_has_calls(
198197
[
199-
mocker.call(["git", "fetch", "origin"], check=True, capture_output=True),
200198
mocker.call(["git", "checkout", "master"], check=True, capture_output=True),
201199
mocker.call(
202200
["git", "switch", "-C", "remove/issue1"],
@@ -248,8 +246,6 @@ async def test_resolve_conflict_pull_requests_plugin(
248246
async def test_resolve_conflict_pull_requests_not_found(
249247
app: App, mocker: MockerFixture, mocked_api: MockRouter, tmp_path: Path, mock_pull
250248
) -> None:
251-
from pydantic_core import PydanticCustomError
252-
253249
from src.plugins.github import plugin_config
254250
from src.plugins.github.models import GithubHandler, RepoInfo
255251
from src.plugins.github.plugins.remove.utils import resolve_conflict_pull_requests
@@ -290,16 +286,10 @@ async def test_resolve_conflict_pull_requests_not_found(
290286

291287
handler = GithubHandler(bot=bot, repo_info=RepoInfo(owner="owner", repo="repo"))
292288

293-
with pytest.raises(PydanticCustomError):
294-
await resolve_conflict_pull_requests(handler, [mock_pull])
289+
await resolve_conflict_pull_requests(handler, [mock_pull])
295290

296291
# 测试 git 命令
297-
mock_subprocess_run.assert_has_calls(
298-
[
299-
mocker.call(["git", "fetch", "origin"], check=True, capture_output=True),
300-
mocker.call(["git", "checkout", "master"], check=True, capture_output=True),
301-
] # type: ignore
302-
)
292+
mock_subprocess_run.assert_not_called()
303293

304294
check_json_data(
305295
plugin_config.input_config.plugin_path,

tests/github/remove/utils/test_update_file.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ async def test_update_file(
1212
) -> None:
1313
from src.plugins.github import plugin_config
1414
from src.plugins.github.plugins.remove.utils import update_file
15+
from src.plugins.github.plugins.remove.validation import RemoveInfo
1516
from src.providers.utils import dump_json5
1617
from src.providers.validation.models import PublishType
1718

@@ -37,7 +38,12 @@ async def test_update_file(
3738

3839
check_json_data(plugin_config.input_config.bot_path, data)
3940

40-
update_file(PublishType.BOT, "CoolQBot:https://github.com/he0119/CoolQBot")
41+
remove_info = RemoveInfo(
42+
publish_type=PublishType.BOT,
43+
key="CoolQBot:https://github.com/he0119/CoolQBot",
44+
name="CoolQBot",
45+
)
46+
update_file(remove_info)
4147

4248
check_json_data(
4349
plugin_config.input_config.bot_path,

0 commit comments

Comments
 (0)