Skip to content

Commit 2fcbfc3

Browse files
committed
bugfix: fix task type issue
1 parent 249c99e commit 2fcbfc3

13 files changed

+1598
-31
lines changed

debug/analyze_issues_type.py

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#!/usr/bin/env python3
2+
"""
3+
分析实际 issues 的 type 字段值
4+
5+
这个脚本会:
6+
1. 搜索你组织的所有 issues
7+
2. 统计不同 type 值的分布
8+
3. 显示每个 type 的示例 issues
9+
"""
10+
11+
import os
12+
import sys
13+
from pathlib import Path
14+
from collections import Counter
15+
16+
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
17+
18+
from libs.github_client import search_issues, get_issue_type
19+
20+
21+
def main():
22+
token = os.environ.get("GH_TOKEN", "").strip()
23+
if not token:
24+
print("错误: 请设置环境变量 GH_TOKEN")
25+
return
26+
27+
org = "mcpp-community"
28+
print(f"分析组织: {org}")
29+
print("=" * 60)
30+
31+
# 搜索所有打开的 issues
32+
query = f"org:{org} is:issue is:open"
33+
print(f"搜索: {query}\n")
34+
35+
try:
36+
issues = search_issues(token, query, per_page=100)
37+
print(f"找到 {len(issues)} 个打开的 issues\n")
38+
39+
if not issues:
40+
print("没有找到 issues")
41+
return
42+
43+
# 统计 type 字段的原始值
44+
type_raw_values = Counter()
45+
type_detected_values = Counter()
46+
type_examples = {}
47+
48+
for issue in issues:
49+
# 原始 type 字段值
50+
raw_type = issue.get("type")
51+
type_raw_values[str(raw_type)] += 1
52+
53+
# 使用 get_issue_type 检测的值
54+
detected_type = get_issue_type(issue)
55+
if not detected_type:
56+
detected_type = "(empty)"
57+
type_detected_values[detected_type] += 1
58+
59+
# 保存示例
60+
if detected_type not in type_examples:
61+
type_examples[detected_type] = []
62+
if len(type_examples[detected_type]) < 3:
63+
type_examples[detected_type].append({
64+
"number": issue['number'],
65+
"title": issue['title'],
66+
"repo": issue.get('repository_url', '').split('/')[-1],
67+
"raw_type": raw_type,
68+
"labels": [l['name'] for l in issue.get('labels', [])]
69+
})
70+
71+
# 显示统计结果
72+
print("=" * 60)
73+
print("1. 原始 type 字段值分布:")
74+
print("=" * 60)
75+
for type_val, count in type_raw_values.most_common():
76+
print(f" {type_val}: {count} 个")
77+
78+
print("\n" + "=" * 60)
79+
print("2. get_issue_type() 检测结果分布:")
80+
print("=" * 60)
81+
for type_val, count in type_detected_values.most_common():
82+
print(f" {type_val}: {count} 个")
83+
84+
print("\n" + "=" * 60)
85+
print("3. 每种 Type 的示例 issues:")
86+
print("=" * 60)
87+
for type_val in sorted(type_examples.keys()):
88+
examples = type_examples[type_val]
89+
print(f"\nType: {type_val} ({type_detected_values[type_val]} 个)")
90+
print("-" * 60)
91+
for ex in examples:
92+
print(f" [{ex['repo']}] #{ex['number']}: {ex['title']}")
93+
print(f" 原始 type: {ex['raw_type']}")
94+
if ex['labels']:
95+
print(f" 标签: {', '.join(ex['labels'])}")
96+
else:
97+
print(f" 标签: (无)")
98+
99+
# 诊断建议
100+
print("\n" + "=" * 60)
101+
print("诊断和建议:")
102+
print("=" * 60)
103+
104+
task_count = type_detected_values.get("Task", 0)
105+
if task_count == 0:
106+
print("\n❌ 没有找到任何 Type=Task 的 issues")
107+
print("\n可能的原因:")
108+
print(" 1. Issues 的 type 字段都是 null(未设置)")
109+
print(" 2. Issues 没有 'Task' 标签")
110+
print("\n解决方案:")
111+
print(" 方案 A: 在 GitHub 组织设置中启用 Issue Types 功能,并为 issues 设置 Type")
112+
print(" 方案 B: 为 issues 添加 'Task' 标签")
113+
print(" 方案 C: 使用其他标签格式(如 'Type: Task')")
114+
else:
115+
print(f"\n✓ 找到 {task_count} 个 Type=Task 的 issues")
116+
117+
null_count = type_detected_values.get("(empty)", 0)
118+
if null_count > 0:
119+
print(f"\n⚠️ 有 {null_count} 个 issues 没有 Type 信息")
120+
print(" 建议为这些 issues 添加 Type 或标签")
121+
122+
except Exception as e:
123+
print(f"错误: {e}")
124+
import traceback
125+
traceback.print_exc()
126+
127+
128+
if __name__ == "__main__":
129+
main()

debug/check_public_api.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#!/usr/bin/env python3
2+
"""
3+
检查公开 GitHub API 的响应结构(不需要 token)
4+
"""
5+
6+
import json
7+
import urllib.request
8+
import urllib.error
9+
10+
11+
def fetch_public_api(url):
12+
"""获取公开 API"""
13+
headers = {
14+
"Accept": "application/vnd.github+json",
15+
"User-Agent": "mcpp-bot-debug",
16+
}
17+
req = urllib.request.Request(url, headers=headers)
18+
try:
19+
with urllib.request.urlopen(req) as resp:
20+
raw = resp.read().decode("utf-8")
21+
return json.loads(raw)
22+
except urllib.error.HTTPError as e:
23+
print(f"HTTP Error {e.code}: {e.reason}")
24+
return None
25+
26+
27+
def main():
28+
# 检查 mcpp-community/OpenOrg 的公开 issues
29+
repo = "mcpp-community/OpenOrg"
30+
31+
print("=" * 60)
32+
print(f"检查公开仓库: {repo}")
33+
print("=" * 60)
34+
35+
# 1. Search API
36+
print("\n1. 使用 Search API:")
37+
print("-" * 60)
38+
search_url = f"https://api.github.com/search/issues?q=repo:{repo}+is:issue+is:open&per_page=3"
39+
search_result = fetch_public_api(search_url)
40+
41+
if search_result and "items" in search_result:
42+
issues = search_result["items"]
43+
print(f"找到 {len(issues)} 个 issues\n")
44+
45+
if issues:
46+
issue = issues[0]
47+
print(f"Issue #{issue['number']}: {issue['title']}")
48+
print(f"\nSearch API 返回的字段:")
49+
for key in sorted(issue.keys()):
50+
value = issue[key]
51+
if key in ["issue_type", "type", "issueType"]:
52+
print(f" ✓ {key}: {value}")
53+
else:
54+
print(f" - {key}")
55+
56+
# 检查 issue_type
57+
if "issue_type" in issue:
58+
print(f"\n✓✓✓ issue_type 字段存在: {issue['issue_type']}")
59+
else:
60+
print(f"\n✗✗✗ issue_type 字段不存在(Search API)")
61+
62+
# 保存 issue_number 用于下一步
63+
issue_number = issue['number']
64+
65+
# 2. Issues API (单个 issue)
66+
print("\n" + "=" * 60)
67+
print("2. 使用 Issues API (单个 issue):")
68+
print("-" * 60)
69+
issue_url = f"https://api.github.com/repos/{repo}/issues/{issue_number}"
70+
full_issue = fetch_public_api(issue_url)
71+
72+
if full_issue:
73+
print(f"Issue #{full_issue['number']}: {full_issue['title']}")
74+
print(f"\nIssues API 返回的字段:")
75+
for key in sorted(full_issue.keys()):
76+
value = full_issue[key]
77+
if key in ["issue_type", "type", "issueType"]:
78+
print(f" ✓ {key}: {value}")
79+
else:
80+
print(f" - {key}")
81+
82+
# 检查 issue_type
83+
if "issue_type" in full_issue:
84+
print(f"\n✓✓✓ issue_type 字段存在: {full_issue['issue_type']}")
85+
else:
86+
print(f"\n✗✗✗ issue_type 字段不存在(Issues API)")
87+
88+
# 检查 labels 中是否有 Type 信息
89+
print("\n" + "-" * 60)
90+
print("Labels 标签:")
91+
labels = full_issue.get("labels", [])
92+
if labels:
93+
for label in labels:
94+
print(f" - {label['name']}")
95+
else:
96+
print(" (无标签)")
97+
98+
# 显示部分 JSON
99+
print("\n" + "-" * 60)
100+
print("完整 JSON 结构(前 80 行):")
101+
full_json = json.dumps(full_issue, indent=2, ensure_ascii=False)
102+
lines = full_json.split('\n')
103+
for line in lines[:80]:
104+
print(line)
105+
if len(lines) > 80:
106+
print(f"... (还有 {len(lines) - 80} 行)")
107+
108+
print("\n" + "=" * 60)
109+
print("总结:")
110+
print("=" * 60)
111+
print("如果 issue_type 字段不存在,可能的原因:")
112+
print(" 1. GitHub 的 Issue Types 功能需要在组织设置中启用")
113+
print(" 2. 该功能可能还在 Beta 阶段,需要特殊权限")
114+
print(" 3. REST API 可能不支持,需要使用 GraphQL API")
115+
print(" 4. 需要使用不同的 Accept header")
116+
print("\n如果使用 Labels 方式,请确保 issues 有以下标签之一:")
117+
print(" - Task, Bug, Feature")
118+
print(" - Type: Task, Type: Bug, Type: Feature")
119+
print(" - type/task, type/bug, type/feature")
120+
121+
122+
if __name__ == "__main__":
123+
main()

debug/check_real_api_response.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#!/usr/bin/env python3
2+
"""
3+
检查真实的 GitHub API 响应
4+
5+
这个脚本会:
6+
1. 使用 Search API 搜索 issues
7+
2. 使用 Issues API 获取单个 issue 的完整信息
8+
3. 对比两者的差异,特别是 issue_type 字段
9+
"""
10+
11+
import os
12+
import sys
13+
import json
14+
from pathlib import Path
15+
16+
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
17+
18+
from libs.github_client import gh, search_issues
19+
20+
21+
def main():
22+
token = os.environ.get("GH_TOKEN", "").strip()
23+
if not token:
24+
print("错误: 请设置环境变量 GH_TOKEN")
25+
print("\n使用方法:")
26+
print(" export GH_TOKEN=your_github_token")
27+
print(" python debug/check_real_api_response.py")
28+
return
29+
30+
repo = "mcpp-community/OpenOrg"
31+
print(f"检查仓库: {repo}")
32+
print("=" * 60)
33+
34+
# 1. 使用 Search API
35+
print("\n1. Search API 结果:")
36+
print("-" * 60)
37+
query = f"repo:{repo} is:issue is:open"
38+
try:
39+
issues = search_issues(token, query, per_page=3)
40+
print(f"找到 {len(issues)} 个 issues")
41+
42+
if issues:
43+
issue = issues[0]
44+
print(f"\nIssue #{issue['number']}: {issue['title']}")
45+
print(f"\n字段列表:")
46+
for key in sorted(issue.keys()):
47+
print(f" - {key}")
48+
49+
# 检查 issue_type
50+
if "issue_type" in issue:
51+
print(f"\n✓ issue_type 字段存在: {issue['issue_type']}")
52+
else:
53+
print(f"\n✗ issue_type 字段不存在")
54+
55+
except Exception as e:
56+
print(f"Search API 失败: {e}")
57+
import traceback
58+
traceback.print_exc()
59+
60+
# 2. 使用 Issues API 获取单个 issue
61+
print("\n" + "=" * 60)
62+
print("2. Issues API 结果 (单个 issue):")
63+
print("-" * 60)
64+
65+
if issues:
66+
issue_number = issues[0]['number']
67+
print(f"获取 Issue #{issue_number} 的完整信息...")
68+
69+
try:
70+
code, full_issue = gh("GET", f"repos/{repo}/issues/{issue_number}", token)
71+
if code == 200 and full_issue:
72+
print(f"\n字段列表:")
73+
for key in sorted(full_issue.keys()):
74+
print(f" - {key}")
75+
76+
# 检查 issue_type
77+
if "issue_type" in full_issue:
78+
print(f"\n✓ issue_type 字段存在: {full_issue['issue_type']}")
79+
else:
80+
print(f"\n✗ issue_type 字段不存在")
81+
82+
# 显示完整的 JSON(前100行)
83+
print(f"\n完整 JSON (前100行):")
84+
full_json = json.dumps(full_issue, indent=2, ensure_ascii=False)
85+
lines = full_json.split('\n')
86+
for line in lines[:100]:
87+
print(line)
88+
if len(lines) > 100:
89+
print(f"\n... (还有 {len(lines) - 100} 行)")
90+
91+
else:
92+
print(f"获取失败: HTTP {code}")
93+
94+
except Exception as e:
95+
print(f"Issues API 失败: {e}")
96+
import traceback
97+
traceback.print_exc()
98+
99+
print("\n" + "=" * 60)
100+
print("提示:")
101+
print(" - 如果两个 API 都没有 issue_type 字段,可能需要:")
102+
print(" 1. 在组织设置中启用 Issue Types 功能")
103+
print(" 2. 使用特殊的 Accept header")
104+
print(" 3. 使用 GraphQL API")
105+
print("=" * 60)
106+
107+
108+
if __name__ == "__main__":
109+
main()

0 commit comments

Comments
 (0)