Files
system-dev-template/scripts/github-publish-sanitize.py
T
Leo c25babf4bb feat: GitHub public mirror 管線(成品櫥窗,非工作現場)
leo 2026-07-21:「應該要給的是一個適合別人用的濃縮結果,不需要有過程。
以後我還是在私有的 template 工作,但 publish 到 GitHub 就把它當貼文。」

- publish-github.sh:移植自 arcrun-rag 既有管線(乾淨歷史、憑證走 header 不進 URL)
  +修一個真 bug:原版 sanitize 失敗不中止 → 會把未淨化樹 rsync 進 mirror 並推出去
- github-publish-exclude.txt:濾掉工作現場(system-dev/ .claude/ docs/ CLAUDE.md CHANGELOG.md)
  保留成品(README/scripts/skills/template)
- github-publish-sanitize.py:改寫來源網址 + 發佈前驗證,殘留失效來源即中止
  ① git.uncle6.me(private 且即將換 CF 版,別人抓不到)
  ② uncle6me-web(已 suspend 的舊 GitHub 帳號——README 安裝指令原本還指著它,
     別人照著跑會失敗,與 07-20 update.sh 同一顆雷)

公開樹實測:只剩 README/scripts/skills/template,安裝指令指向 youlinhsieh,零殘留。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 11:18:37 +08:00

96 lines
3.8 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
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
"""github-publish-sanitize.py — 對匯出樹做內容級改寫,讓公開版真的能被別人使用。
由 publish-github.sh 自動呼叫(步驟 3.5),參數=匯出樹的暫存目錄。
為什麼需要(leo 2026-07-21):
「我不想給它 Gitea 網址,因為我們已經計劃要把 gitea 改用 CF 版本了。」
install.sh / update.sh 內建的抓取來源指向我們的 **private Gitea**
- 別人抓不到(private)→ 裝不起來
- 且該網址即將換成 CF 版 → 公開出去的網址馬上失效
→ 公開版一律改指 GitHub raw。私有工作區維持 Gitea 不動,
兩邊不必手工維護兩份(改寫發生在發佈當下)。
"""
import pathlib
import re
import sys
GITEA_BASE = "https://git.uncle6.me/Leo/system-dev-template/raw/branch/main"
GITHUB_BASE = "https://raw.githubusercontent.com/youlinhsieh/system-dev-template/main"
# 純文字取代(來源網址)。放這裡的規則要「冪等」——重跑不會壞。
REPLACEMENTS = [
(GITEA_BASE, GITHUB_BASE),
# 保險:任何殘留的 Gitea 主機名(例如註解、文件裡的說明連結)
("https://git.uncle6.me/Leo/system-dev-template", "https://github.com/youlinhsieh/system-dev-template"),
# 🔴 舊 GitHub 帳號 uncle6me-web **已被 suspend**README 的安裝指令仍指向它
# → 別人照著跑會抓不到(2026-07-20 已在 update.sh 撞過同一顆雷)。
("raw.githubusercontent.com/uncle6me-web/", "raw.githubusercontent.com/youlinhsieh/"),
("github.com/uncle6me-web/", "github.com/youlinhsieh/"),
# 文件註解裡拿舊帳號當範例 → 對外改通用佔位符(別人看到我們的帳號名沒意義)
("(例:uncle6me-web", "(例:your-github-account"),
("(e.g. uncle6me-web)", "(e.g. your-github-account)"),
]
TEXT_SUFFIXES = {".sh", ".md", ".json", ".py", ".yaml", ".yml", ".txt"}
def main(root_arg: str) -> int:
root = pathlib.Path(root_arg)
if not root.is_dir():
print(f"❌ sanitize:找不到匯出樹 {root}", file=sys.stderr)
return 1
changed = []
for path in root.rglob("*"):
if not path.is_file() or path.suffix not in TEXT_SUFFIXES:
continue
try:
original = path.read_text(encoding="utf-8")
except (UnicodeDecodeError, OSError):
continue
text = original
for old, new in REPLACEMENTS:
text = text.replace(old, new)
if text != original:
path.write_text(text, encoding="utf-8")
changed.append(str(path.relative_to(root)))
if changed:
print(f"🧼 sanitize:改寫來源網址 → GitHub{len(changed)} 檔)")
for c in changed:
print(f" {c}")
else:
print("🧼 sanitize:無需改寫")
# 驗證:公開樹不得殘留「別人抓不到的來源」——漏了就是別人裝不起來。
# ① git.uncle6.me 我們的 private Gitea(且即將換 CF 版)
# ② uncle6me-web 已被 suspend 的舊 GitHub 帳號
BAD_HOSTS = ("git.uncle6.me", "uncle6me-web")
leaked = []
for path in root.rglob("*"):
if not path.is_file() or path.suffix not in TEXT_SUFFIXES:
continue
try:
content = path.read_text(encoding="utf-8")
if any(bad in content for bad in BAD_HOSTS):
leaked.append(str(path.relative_to(root)))
except (UnicodeDecodeError, OSError):
continue
if leaked:
print("❌ sanitize:公開樹仍殘留失效來源(Gitea/suspend 帳號),中止發佈:", file=sys.stderr)
for f in leaked:
print(f" {f}", file=sys.stderr)
return 1
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1] if len(sys.argv) > 1 else "."))