Skip to content
This repository was archived by the owner on Apr 16, 2026. It is now read-only.

Commit cd1bf4e

Browse files
fix(server.py): 修复issue关闭时误触发action的问题
问题:当被提及的issue被关闭时,会触发GitHub通知,导致workflow被错误触发。 原因: 1. GitHub在issue关闭等事件时会发送通知,即使通知的reason是"mention" 2. 原代码缺少对通知类型的检测和时间戳验证 3. 没有区分"新的@mention"和"旧事件的后续通知" 修复: 1. 添加subject_type检查,确保只处理Issue/PullRequest/Commit/Discussion类型 2. 添加时间戳验证:如果触发节点创建时间比通知更新时间早超过1分钟 说明是旧事件的后续通知(如issue关闭),不应触发workflow 3. 修复注释编号重复问题 Fixes #83 Co-Authored-By: Claude (mimo-v2-flash) <noreply@anthropic.com>
1 parent f8dec89 commit cd1bf4e

1 file changed

Lines changed: 53 additions & 1 deletion

File tree

server.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,27 @@ async def handle_notification(client: httpx.AsyncClient, note: Dict):
745745
pass
746746
return
747747

748+
# 检查通知类型 - 只处理 issue 和 pull_request 类型
749+
# GitHub 通知的 subject.type 可以是: "Issue", "PullRequest", "Commit", "Discussion" 等
750+
# 但 issue 关闭等事件也会触发通知,我们需要检查 URL 中是否包含事件信息
751+
subject_type = note.get("subject", {}).get("type")
752+
logger.info(f"Notification subject type: {subject_type}")
753+
754+
# 检查 URL 中是否包含事件类型(如 /issues/123 可能是 issue 关闭事件)
755+
# 我们需要确保只处理真正包含 @mention 的内容,而不是所有相关事件
756+
# 例如:issue 被关闭时,如果之前被 @mention 过,也会触发通知
757+
# 但这种通知不应该触发 workflow,因为没有新的 @mention
758+
if subject_type and subject_type not in ["Issue", "PullRequest", "Commit", "Discussion"]:
759+
logger.info(f"Ignoring notification with unsupported subject type: {subject_type}")
760+
try:
761+
await client.patch(
762+
f"{REST_API}/notifications/threads/{thread_id}",
763+
headers={"Authorization": f"token {BOT_TOKEN}"}
764+
)
765+
except:
766+
pass
767+
return
768+
748769
# 1. 获取资源详情
749770
resource_data = await fetch_resource_details(client, raw_url)
750771
if not resource_data:
@@ -882,6 +903,37 @@ async def handle_notification(client: httpx.AsyncClient, note: Dict):
882903
pass
883904
return
884905

906+
# 5. 验证触发节点的时间戳 - 防止处理旧事件
907+
# 检查触发节点的创建时间是否在通知的更新时间之前(说明是旧的 @mention)
908+
# 这可以防止 issue 关闭等事件触发 workflow(这些事件会发送通知,但没有新的 @mention)
909+
notification_updated_at = note.get("updated_at")
910+
if notification_updated_at and trigger_node.created_at:
911+
try:
912+
# 解析时间戳(ISO 8601 格式)
913+
note_time = datetime.fromisoformat(notification_updated_at.replace("Z", "+00:00"))
914+
trigger_time = datetime.fromisoformat(trigger_node.created_at.replace("Z", "+00:00"))
915+
916+
# 如果触发节点的创建时间比通知更新时间早很多(超过 1 分钟)
917+
# 说明这不是新的 @mention,而是旧事件的后续通知(如 issue 关闭)
918+
time_diff = (note_time - trigger_time).total_seconds()
919+
if time_diff > 60: # 超过 1 分钟
920+
logger.warning(f"Trigger node is too old (created {time_diff:.0f}s before notification update). This might be an event notification (e.g., issue closed) rather than a new @mention.")
921+
logger.warning(f"Notification updated_at: {notification_updated_at}, Trigger created_at: {trigger_node.created_at}")
922+
# 标记为已读但不触发 workflow
923+
try:
924+
await client.patch(
925+
f"{REST_API}/notifications/threads/{thread_id}",
926+
headers={"Authorization": f"token {BOT_TOKEN}"}
927+
)
928+
except:
929+
pass
930+
return
931+
else:
932+
logger.info(f"Trigger node time check passed (time diff: {time_diff:.0f}s)")
933+
except Exception as e:
934+
logger.warning(f"Could not parse timestamps for validation: {e}")
935+
# 继续处理,但记录警告
936+
885937
# 验证触发消息是否存在
886938
if not trigger_node.body or not trigger_node.body.strip():
887939
logger.error(f"Trigger node {trigger_node.id} has empty body. Cannot proceed with workflow.")
@@ -899,7 +951,7 @@ async def handle_notification(client: httpx.AsyncClient, note: Dict):
899951
pass
900952
return
901953

902-
# 5. 构建完整上下文(使用修复后的build_rich_context)
954+
# 6. 构建完整上下文(使用修复后的build_rich_context)
903955
context = build_rich_context(resource_data, timeline_items, trigger_node, raw_url, thread_id)
904956

905957
# 6. 获取diff内容(根据触发类型决定)

0 commit comments

Comments
 (0)