diff --git a/.gitea/checker/comparator.py b/.gitea/checker/comparator.py
index 95bda87..eeaf1ac 100644
--- a/.gitea/checker/comparator.py
+++ b/.gitea/checker/comparator.py
@@ -89,6 +89,8 @@ class EndpointChangeReport:
is_removed_endpoint: bool = False
is_renamed_endpoint: bool = False
old_uri: Optional[str] = None
+ is_method_changed: bool = False
+ old_http_method: Optional[str] = None
@property
def has_changes(self) -> bool:
@@ -97,6 +99,7 @@ class EndpointChangeReport:
self.is_new_endpoint
or self.is_removed_endpoint
or self.is_renamed_endpoint
+ or self.is_method_changed
or len(self.parameter_changes) > 0
)
@@ -219,7 +222,11 @@ def compare_endpoints(
"""
对比新旧两个版本的全部 Controller 端点,生成变更报告列表。
- 支持 URI 重命名检测(路径变更)。
+ 支持以下变更类型检测:
+ - HTTP 方法变更(GET → POST 等)
+ - URI 路径变更(路径重命名)
+ - 新增 / 删除接口
+ - 参数变更
"""
reports: List[EndpointChangeReport] = []
@@ -230,7 +237,7 @@ def compare_endpoints(
added_keys = new_keys - old_keys
common_keys = old_keys & new_keys
- # 1. URI 重命名检测:在 removed + added 中找 method+controller+method_name 相同的配对
+ # 收集未匹配的 removed / added
unmatched_removed: List[Tuple[str, ApiEndpoint]] = []
unmatched_added: List[Tuple[str, ApiEndpoint]] = []
@@ -242,15 +249,44 @@ def compare_endpoints(
matched_removed: Set[str] = set()
matched_added: Set[str] = set()
+ # 1. HTTP 方法变更检测(uri + controller + method_name 相同,但 method 不同)
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.uri == a_ep.uri
+ and r_ep.controller_class == a_ep.controller_class
+ and r_ep.method_name == a_ep.method_name
+ and r_ep.http_method != a_ep.http_method
+ ):
+ reports.append(
+ EndpointChangeReport(
+ uri=a_ep.uri,
+ http_method=a_ep.http_method,
+ controller_class=a_ep.controller_class,
+ method_name=a_ep.method_name,
+ source_file=a_ep.source_file,
+ is_method_changed=True,
+ old_http_method=r_ep.http_method,
+ )
+ )
+ matched_removed.add(r_key)
+ matched_added.add(a_key)
+ break
+
+ # 2. URI 路径变更检测(method + controller + method_name 相同,但 uri 不同)
+ for r_key, r_ep in unmatched_removed:
+ if r_key in matched_removed:
+ continue
+ for a_key, a_ep in unmatched_added:
+ if a_key in matched_added:
+ continue
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
+ and r_ep.uri != a_ep.uri
):
reports.append(
EndpointChangeReport(
@@ -267,7 +303,7 @@ def compare_endpoints(
matched_added.add(a_key)
break
- # 2. 剩余未匹配的 removed → 删除接口
+ # 3. 剩余未匹配的 removed → 删除接口
for key, ep in unmatched_removed:
if key not in matched_removed:
reports.append(
@@ -281,7 +317,7 @@ def compare_endpoints(
)
)
- # 3. 剩余未匹配的 added → 新增接口
+ # 4. 剩余未匹配的 added → 新增接口
for key, ep in unmatched_added:
if key not in matched_added:
reports.append(
@@ -304,7 +340,7 @@ def compare_endpoints(
)
)
- # 4. 共同 URI:对比参数变更
+ # 5. 共同 URI:对比参数变更
for key in common_keys:
old_ep = old_endpoints[key]
new_ep = new_endpoints[key]
diff --git a/.gitea/checker/notifier.py b/.gitea/checker/notifier.py
index 3764cc6..e1d3471 100644
--- a/.gitea/checker/notifier.py
+++ b/.gitea/checker/notifier.py
@@ -75,12 +75,16 @@ def build_markdown_notification(
"""
parts: List[str] = []
- # 所有 API 级变更(新增、修改路径、删除、参数变更)统一走 model1.md 路径变更通知
+ # 所有 API 级变更(新增、修改路径、修改请求方式、删除、参数变更)统一走 model1.md 路径变更通知
+ method_changed_reports = [r for r in reports if r.is_method_changed]
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
+ if not r.is_new_endpoint
+ and not r.is_removed_endpoint
+ and not r.is_renamed_endpoint
+ and not r.is_method_changed
]
removed_reports = [r for r in reports if r.is_removed_endpoint]
@@ -97,7 +101,22 @@ def build_markdown_notification(
parts.append(path_md)
parts.append("")
- # 2. 修改路径 → 走 API路径变更通知
+ # 2. 修改请求方式 → 走 API路径变更通知
+ for report in method_changed_reports:
+ path_md = build_path_change_markdown(
+ old_uri=report.uri,
+ new_uri=report.uri,
+ change_type="修改请求方式",
+ push_user=push_user,
+ push_time=push_time,
+ file_name=report.source_file or report.controller_class,
+ old_method=report.old_http_method,
+ new_method=report.http_method,
+ )
+ parts.append(path_md)
+ parts.append("")
+
+ # 3. 修改路径 → 走 API路径变更通知
for report in renamed_reports:
path_md = build_path_change_markdown(
old_uri=report.old_uri or "-",
@@ -110,7 +129,7 @@ def build_markdown_notification(
parts.append(path_md)
parts.append("")
- # 3. 删除接口 → 走 API路径变更通知
+ # 4. 删除接口 → 走 API路径变更通知
for report in removed_reports:
path_md = build_path_change_markdown(
old_uri=report.uri,
@@ -259,14 +278,19 @@ def build_path_change_markdown(
push_user: str,
push_time: str,
file_name: str,
+ old_method: Optional[str] = None,
+ new_method: Optional[str] = None,
) -> str:
"""构建 API路径变更通知,完全匹配 model1.md 模板,并加强视觉区分。
+ 支持的 change_type:
+ - 新增接口 / 删除接口 / 修改路径 / 修改请求方式
+
改进点:
- 标题使用【】风格
- 头部信息缩进 + 颜色高亮
- URI 详情使用列表(更直观)
- - 根据变更类型动态强调「原/新路径」
+ - 「修改请求方式」额外展示方法变更
"""
# 变更类型高亮
type_highlight = f"**{change_type}**"
@@ -281,6 +305,15 @@ def build_path_change_markdown(
elif change_type == "删除接口":
old_display = f"**`{old_uri}`** ← **已删除**"
new_display = "`已删除`"
+ elif change_type == "修改请求方式":
+ # 方法变更场景:展示原方法 → 新方法
+ old_m = old_method or "?"
+ new_m = new_method or "?"
+ old_display = f"**`{old_uri}` **[{old_m}]**"
+ new_display = (
+ f"**`{new_uri}` "
+ f"**[{old_m} → {new_m}]** ← **请求方式变更**"
+ )
else: # 修改路径
old_display = f"~~`{old_uri}`~~ ← **旧路径**"
new_display = f"**`{new_uri}`** ← **新路径**"