py修改
Some checks failed
API接口参数变更检测 / api-param-check (push) Has been cancelled

This commit is contained in:
2026-06-04 16:57:08 +08:00
parent 2d7bba4b91
commit 48dc5ac8e4
2 changed files with 101 additions and 39 deletions

View File

@@ -86,6 +86,8 @@ class EndpointChangeReport:
parameter_changes: List[ParameterChange] = field(default_factory=list)
is_new_endpoint: bool = False
is_removed_endpoint: bool = False
is_renamed_endpoint: bool = False
old_uri: Optional[str] = None
@property
def has_changes(self) -> bool:
@@ -93,6 +95,7 @@ class EndpointChangeReport:
return (
self.is_new_endpoint
or self.is_removed_endpoint
or self.is_renamed_endpoint
or len(self.parameter_changes) > 0
)
@@ -215,26 +218,75 @@ def compare_endpoints(
"""
对比新旧两个版本的全部 Controller 端点,生成变更报告列表。
:param old_endpoints: 旧版本 { endpoint_key: ApiEndpoint }
:param new_endpoints: 新版本 { endpoint_key: ApiEndpoint }
:return: 有变更的接口报告列表
支持 URI 重命名检测(路径变更)。
"""
reports: List[EndpointChangeReport] = []
all_keys = set(old_endpoints.keys()) | set(new_endpoints.keys())
old_keys = set(old_endpoints.keys())
new_keys = set(new_endpoints.keys())
for key in sorted(all_keys):
old_ep = old_endpoints.get(key)
new_ep = new_endpoints.get(key)
removed_keys = old_keys - new_keys
added_keys = new_keys - old_keys
common_keys = old_keys & new_keys
if old_ep is None and new_ep is not None:
# 全新接口
# 1. URI 重命名检测:在 removed + added 中找 method+controller+method_name 相同的配对
unmatched_removed: List[Tuple[str, ApiEndpoint]] = []
unmatched_added: List[Tuple[str, ApiEndpoint]] = []
for key in removed_keys:
unmatched_removed.append((key, old_endpoints[key]))
for key in added_keys:
unmatched_added.append((key, new_endpoints[key]))
matched_removed: Set[str] = set()
matched_added: Set[str] = set()
for r_key, r_ep in unmatched_removed:
for a_key, a_ep in unmatched_added:
if a_key in matched_added:
continue
# 匹配条件method 相同 + controller 相同 + method_name 相同
if (
r_ep.http_method == a_ep.http_method
and r_ep.controller_class == a_ep.controller_class
and r_ep.method_name == a_ep.method_name
):
reports.append(
EndpointChangeReport(
uri=new_ep.uri,
http_method=new_ep.http_method,
controller_class=new_ep.controller_class,
method_name=new_ep.method_name,
uri=a_ep.uri,
http_method=a_ep.http_method,
controller_class=a_ep.controller_class,
method_name=a_ep.method_name,
is_renamed_endpoint=True,
old_uri=r_ep.uri,
)
)
matched_removed.add(r_key)
matched_added.add(a_key)
break
# 2. 剩余未匹配的 removed → 删除接口
for key, ep in unmatched_removed:
if key not in matched_removed:
reports.append(
EndpointChangeReport(
uri=ep.uri,
http_method=ep.http_method,
controller_class=ep.controller_class,
method_name=ep.method_name,
is_removed_endpoint=True,
)
)
# 3. 剩余未匹配的 added → 新增接口
for key, ep in unmatched_added:
if key not in matched_added:
reports.append(
EndpointChangeReport(
uri=ep.uri,
http_method=ep.http_method,
controller_class=ep.controller_class,
method_name=ep.method_name,
is_new_endpoint=True,
parameter_changes=[
ParameterChange(
@@ -243,26 +295,15 @@ def compare_endpoints(
param_type=p.type,
required=p.required,
)
for p in new_ep.parameters
for p in ep.parameters
],
)
)
continue
if new_ep is None and old_ep is not None:
# 接口被删除
reports.append(
EndpointChangeReport(
uri=old_ep.uri,
http_method=old_ep.http_method,
controller_class=old_ep.controller_class,
method_name=old_ep.method_name,
is_removed_endpoint=True,
)
)
continue
# 同 URI 对比参数
# 4. 共同 URI对比参数变更
for key in common_keys:
old_ep = old_endpoints[key]
new_ep = new_endpoints[key]
param_changes = compare_parameters(old_ep.parameters, new_ep.parameters)
if param_changes:
reports.append(

View File

@@ -47,7 +47,6 @@ def _format_endpoint_block(report: EndpointChangeReport) -> str:
detail_lines.append("### <font color=\"warning\">参数变更明细</font>")
if report.parameter_changes:
# 简化:使用列表格式匹配模板
for change in report.parameter_changes:
md = change.to_markdown_line(plain=report.is_new_endpoint)
detail_lines.append(md)
@@ -72,18 +71,40 @@ def build_markdown_notification(
:param llm_summary: LLM 兼容性摘要(可选,简短)
:return: Markdown 文本
"""
parts = [
parts: List[str] = []
# 分组:路径变更、参数变更、新增、删除
renamed_reports = [r for r in reports if r.is_renamed_endpoint]
new_reports = [r for r in reports if r.is_new_endpoint]
changed_reports = [
r for r in reports
if not r.is_new_endpoint and not r.is_removed_endpoint and not r.is_renamed_endpoint
]
removed_reports = [r for r in reports if r.is_removed_endpoint]
# 路径变更优先使用 model1.md 模板
for report in renamed_reports:
old_uri = report.old_uri or "-"
new_uri = report.uri or "已删除"
path_md = build_path_change_markdown(
old_uri=old_uri,
new_uri=new_uri,
change_type="修改路径",
push_user=push_user,
push_time=push_time,
file_name=report.controller_class,
)
parts.append(path_md)
parts.append("")
if new_reports or changed_reports or removed_reports:
parts.extend([
"# API参数变更通知",
f"- **变更类型:** 修改参数",
f"- **修改人:** {push_user}",
f"- **修改时间:** {push_time}",
"",
]
# 新增 Controller全部为新接口与变更接口分组
new_reports = [r for r in reports if r.is_new_endpoint]
changed_reports = [r for r in reports if not r.is_new_endpoint and not r.is_removed_endpoint]
removed_reports = [r for r in reports if r.is_removed_endpoint]
])
for report in new_reports:
parts.append(_format_endpoint_block(report))