Files
mcn-short-video/.workbuddy/skills/nuwa-skill-main/.github/scripts/community_check.py
T

141 lines
5.5 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""COMMUNITY.md 收录PR的半自动检查。
机器检查(本脚本):
1. PR只改动 COMMUNITY.md(动了SKILL.md等核心文件直接判❌)
2. 新增行里的GitHub仓库真实存在且公开
3. 若目标仓库含SKILL.md(人物/主题skill类)→ 额外要求:
- FIDELITY.md 存在且总分≥70(B级)
- SKILL.md 含「诚实边界」章节
- 有 references/ 调研底稿目录
若不含SKILL.md(合集/工具类)→ 仅存在性检查,标注请人工确认类别
4. 结果贴成PR评论
人工检查(维护者):伦理红线 + 内容质量抽查 + 合并。
本地测试:python3 community_check.py --check-repo owner/repo
"""
import json
import os
import re
import sys
import urllib.request
API = "https://api.github.com"
def gh(path, token, raw=False):
req = urllib.request.Request(API + path)
if token:
req.add_header("Authorization", f"Bearer {token}")
if raw:
req.add_header("Accept", "application/vnd.github.raw+json")
try:
with urllib.request.urlopen(req, timeout=15) as r:
data = r.read().decode("utf-8", "replace")
return data if raw else json.loads(data)
except Exception:
return None
def check_target_repo(slug, token):
"""检查被收录的仓库,返回 (是否通过, 检查项列表)。"""
items = []
repo = gh(f"/repos/{slug}", token)
if not repo:
return False, [("❌", f"`{slug}` 仓库不存在或不可访问")]
items.append(("✅", f"[`{slug}`](https://github.com/{slug}) 存在(★{repo.get('stargazers_count', 0)})"))
skill_md = gh(f"/repos/{slug}/contents/SKILL.md", token, raw=True)
if skill_md is None:
items.append(("ℹ️", "无根目录SKILL.md → 按「合集/工具类」处理,请人工确认类别与内容"))
return True, items
items.append(("✅", "含 SKILL.md(按skill类审核)"))
if "诚实边界" in skill_md or "Honest" in skill_md or "honest-limits" in skill_md.lower():
items.append(("✅", "SKILL.md 含诚实边界章节"))
else:
items.append(("❌", "SKILL.md 缺「诚实边界」章节(收录门槛之一)"))
refs = gh(f"/repos/{slug}/contents/references", token)
if isinstance(refs, list) and refs:
items.append(("✅", "含 references/ 调研底稿"))
else:
items.append(("❌", "缺 references/ 调研底稿(skill需自包含可溯源)"))
fidelity = gh(f"/repos/{slug}/contents/FIDELITY.md", token, raw=True)
if fidelity is None:
items.append(("❌", "缺 FIDELITY.md 保真度评分卡(见 references/fidelity-scorecard.md)"))
else:
m = re.search(r"总分[::]\s*(\d+)\s*/\s*100", fidelity)
if not m:
items.append(("❌", "FIDELITY.md 存在但未解析到「总分:NN/100」"))
elif int(m.group(1)) >= 70:
items.append(("✅", f"保真度 {m.group(1)}/100 ≥ 70(B级门槛)"))
else:
items.append(("❌", f"保真度 {m.group(1)}/100 未达B级门槛(70)"))
ok = all(mark != "❌" for mark, _ in items)
return ok, items
def main():
if len(sys.argv) == 3 and sys.argv[1] == "--check-repo":
ok, items = check_target_repo(sys.argv[2], os.environ.get("GITHUB_TOKEN", ""))
for mark, text in items:
print(mark, text)
sys.exit(0 if ok else 1)
token = os.environ["GITHUB_TOKEN"]
repo = os.environ["GITHUB_REPOSITORY"]
pr = os.environ["PR_NUMBER"]
files = gh(f"/repos/{repo}/pulls/{pr}/files?per_page=100", token) or []
names = [f["filename"] for f in files]
lines = ["## 🤖 社区收录检查\n"]
all_ok = True
core_touched = [n for n in names if n != "COMMUNITY.md"]
if core_touched:
all_ok = False
lines.append(f"❌ PR改动了 COMMUNITY.md 以外的文件:`{'`, `'.join(core_touched[:10])}`")
if any(n == "SKILL.md" for n in core_touched):
lines.append("  ⚠️ SKILL.md 是核心资产,不接受外部PR改动(见 CONTRIBUTING.md),请从PR中移除")
else:
lines.append("✅ 只改动 COMMUNITY.md")
added = []
for f in files:
if f["filename"] == "COMMUNITY.md":
for ln in (f.get("patch") or "").splitlines():
if ln.startswith("+") and not ln.startswith("+++"):
added += re.findall(r"github\.com/([\w.-]+/[\w.-]+)", ln)
added = list(dict.fromkeys(s.rstrip(")/") for s in added))
if not added:
all_ok = False
lines.append("❌ 未在新增行中检测到GitHub仓库链接")
for slug in added[:5]:
ok, items = check_target_repo(slug, token)
all_ok = all_ok and ok
lines.append(f"\n**{slug}**")
lines += [f"- {mark} {text}" for mark, text in items]
lines.append("\n---")
lines.append(("✅ **机器检查通过**。" if all_ok else "❌ **机器检查未通过**,请按上述项修改后推送更新(会自动重跑)。"))
lines.append("最终合并前维护者还会人工确认:伦理红线(CONTRIBUTING.md)+ 内容质量抽查。")
body = "\n".join(lines)
req = urllib.request.Request(
f"{API}/repos/{repo}/issues/{pr}/comments",
data=json.dumps({"body": body}).encode(),
headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
method="POST",
)
urllib.request.urlopen(req, timeout=15)
sys.exit(0 if all_ok else 1)
if __name__ == "__main__":
main()