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>
This commit is contained in:
Executable
+87
@@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env bash
|
||||
# publish-github.sh — 產生過濾後的公開樹,維護 GitHub public mirror(乾淨歷史)
|
||||
#
|
||||
# 模型(D22 拍板):Gitea = 私有真相源(全量,含內部 wiki/SDD)
|
||||
# GitHub = 公開櫥窗(過濾樹 + 每次發版一個 release commit,不帶內部歷史)
|
||||
# 流量紅線(D20):push 前需 leo 親跑 github-arm.sh 解保險;低頻手動、單 repo、不掛 Actions。
|
||||
#
|
||||
# 用法:
|
||||
# scripts/publish-github.sh # 只建/更新本機 mirror(.github-public/),不 push
|
||||
# scripts/publish-github.sh --push # 另加 push(需 env GITHUB_REMOTE=https://github.com/<帳號>/<repo>.git)
|
||||
#
|
||||
# 排除清單:scripts/github-publish-exclude.txt(一行一個路徑,相對 repo 根;# 開頭為註解)
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
||||
EXCLUDE_FILE="$REPO_ROOT/scripts/github-publish-exclude.txt"
|
||||
MIRROR_DIR="${MIRROR_DIR:-$REPO_ROOT/.github-public}"
|
||||
GITHUB_REMOTE="${GITHUB_REMOTE:-}"
|
||||
|
||||
TMP_EXPORT="$(mktemp -d)"
|
||||
trap 'rm -rf "$TMP_EXPORT"' EXIT
|
||||
|
||||
# 1) 只匯出 HEAD 的 tracked 檔(.env / credentials 等 untracked 永不混入)
|
||||
git -C "$REPO_ROOT" archive HEAD | tar -x -C "$TMP_EXPORT"
|
||||
|
||||
# 2) LFS 檔用實體內容取代 pointer(公開端不吃 LFS)
|
||||
if command -v git-lfs >/dev/null 2>&1; then
|
||||
git -C "$REPO_ROOT" lfs ls-files --name-only 2>/dev/null | while IFS= read -r f; do
|
||||
if [ -n "$f" ] && [ -f "$REPO_ROOT/$f" ]; then
|
||||
mkdir -p "$TMP_EXPORT/$(dirname "$f")"
|
||||
cp "$REPO_ROOT/$f" "$TMP_EXPORT/$f"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# 2.5) 公開端不吃 LFS:刪掉 .gitattributes,否則 mirror commit 時 git-lfs 會把
|
||||
# 實體檔又轉回 pointer 上傳(GitHub README 圖就破了——2026-07-18 實撞)
|
||||
rm -f "$TMP_EXPORT/.gitattributes"
|
||||
|
||||
# 3) 套排除清單
|
||||
while IFS= read -r p; do
|
||||
case "$p" in ''|\#*) continue ;; esac
|
||||
rm -rf "${TMP_EXPORT:?}/$p"
|
||||
done < "$EXCLUDE_FILE"
|
||||
|
||||
# 3.5) repo 自備的遮蔽腳本(可選):對匯出樹做內容級遮蔽(如指南去帳密)
|
||||
if [ -f "$REPO_ROOT/scripts/github-publish-sanitize.py" ]; then
|
||||
# sanitize 失敗=公開樹仍含「別人抓不到的來源」或未遮蔽內容。
|
||||
# 必須中止:原版沒擋 → 會把未淨化的樹 rsync 進 mirror,下次 --push 就送出去了。
|
||||
if ! python3 "$REPO_ROOT/scripts/github-publish-sanitize.py" "$TMP_EXPORT"; then
|
||||
echo "❌ sanitize 未通過 → 中止發佈(mirror 未被更動)" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# 4) 同步進常駐 mirror(mirror 自己的 .git = 公開端乾淨歷史)
|
||||
mkdir -p "$MIRROR_DIR"
|
||||
[ -d "$MIRROR_DIR/.git" ] || git -C "$MIRROR_DIR" init -q -b main
|
||||
rsync -a --delete --exclude='.git' "$TMP_EXPORT/" "$MIRROR_DIR/"
|
||||
|
||||
cd "$MIRROR_DIR"
|
||||
git add -A
|
||||
if git diff --cached --quiet && git rev-parse -q --verify HEAD >/dev/null; then
|
||||
echo "ℹ️ 無變更,mirror 已是最新"
|
||||
else
|
||||
git -c user.name="Arcrun Release" -c user.email="release@arcrun.dev" \
|
||||
commit -q -m "release: snapshot $(git -C "$REPO_ROOT" rev-parse --short HEAD) ($(git -C "$REPO_ROOT" log -1 --format=%cd --date=short))"
|
||||
echo "✅ mirror 已更新:$(git log --oneline -1)"
|
||||
fi
|
||||
echo "📁 mirror:${MIRROR_DIR}($(git rev-list --count HEAD) 個公開 commit)"
|
||||
|
||||
if [ "${1:-}" = "--push" ]; then
|
||||
if [ -z "$GITHUB_REMOTE" ]; then
|
||||
echo "❌ 缺 GITHUB_REMOTE(例:https://github.com/<帳號>/<repo>.git)" >&2
|
||||
exit 1
|
||||
fi
|
||||
git remote remove github 2>/dev/null || true
|
||||
git remote add github "$GITHUB_REMOTE"
|
||||
# 憑證不進 URL/指令行:有 GITHUB_MIRROR_TOKEN 就用 Basic header 注入(PAT)
|
||||
if [ -n "${GITHUB_MIRROR_TOKEN:-}" ]; then
|
||||
AUTH_B64="$(printf '%s:%s' "${GITHUB_ACCOUNT_NAME:-git}" "$GITHUB_MIRROR_TOKEN" | base64 | tr -d '\n')"
|
||||
git -c http."$GITHUB_REMOTE".extraheader="Authorization: Basic $AUTH_B64" push -u github main
|
||||
else
|
||||
git push -u github main
|
||||
fi
|
||||
echo "🚀 已 push → $GITHUB_REMOTE"
|
||||
fi
|
||||
Reference in New Issue
Block a user