tools(sync-upstream): 上游同步脚本
Some checks failed
continuous-integration/drone/push Build is passing
CI / test (push) Has been cancelled
CI / frontend (push) Has been cancelled
CI / golangci-lint (push) Has been cancelled
Security Scan / backend-security (push) Has been cancelled
Security Scan / frontend-security (push) Has been cancelled
Some checks failed
continuous-integration/drone/push Build is passing
CI / test (push) Has been cancelled
CI / frontend (push) Has been cancelled
CI / golangci-lint (push) Has been cancelled
Security Scan / backend-security (push) Has been cancelled
Security Scan / frontend-security (push) Has been cancelled
只刷新 gitea/ora_main 镜像(默认)或 --try-merge 在临时分支启动合并。 永远不直接动 main,最后一步合并由人工 ff-only。包含冲突预检 + 完整 next-steps 引导。
This commit is contained in:
191
tools/sync-upstream.sh
Executable file
191
tools/sync-upstream.sh
Executable file
@@ -0,0 +1,191 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# tools/sync-upstream.sh
|
||||||
|
#
|
||||||
|
# 同步上游 (Wei-Shaw/sub2api) 最新代码到我们 Gitea fork 的工作流脚本。
|
||||||
|
#
|
||||||
|
# 设计目标:
|
||||||
|
# 1. 在 Gitea 上维护一个纯净的上游镜像分支(默认 ora_main),永远 = upstream/main HEAD
|
||||||
|
# 2. 永远不直接合并到 main —— 创建临时分支让人工 review/preview 后手动合并
|
||||||
|
# 3. 合并前打印冲突预检,让人提前知道改动范围
|
||||||
|
#
|
||||||
|
# 使用方式:
|
||||||
|
# ./tools/sync-upstream.sh # 仅刷新 gitea/ora_main 镜像
|
||||||
|
# ./tools/sync-upstream.sh --try-merge # 刷新 + 创建临时分支并启动合并(停在 --no-commit)
|
||||||
|
#
|
||||||
|
# --try-merge 模式的完整步骤:
|
||||||
|
# 1. fetch upstream + force-with-lease 推到 gitea/ora_main
|
||||||
|
# 2. 预检:列出预计会冲突的文件
|
||||||
|
# 3. 从最新的 main 切出临时分支 merge/upstream-YYYY-MM-DD-HHMM
|
||||||
|
# 4. 在临时分支启动 git merge --no-commit --no-ff upstream/main(停在合并状态)
|
||||||
|
# 5. 打印 next-steps 引导后续 typecheck/build/preview/commit/main 合并
|
||||||
|
#
|
||||||
|
# 自定义环境变量(可覆盖默认):
|
||||||
|
# UPSTREAM_REMOTE 远程名(默认 upstream,应指向 GitHub Wei-Shaw/sub2api)
|
||||||
|
# GITEA_REMOTE 远程名(默认 gitea,自建)
|
||||||
|
# MIRROR_BRANCH 镜像分支名(默认 ora_main)
|
||||||
|
#
|
||||||
|
# 安全注意:
|
||||||
|
# - 强制推送只发生在镜像分支上(force-with-lease,比 force 安全),不会动 main
|
||||||
|
# - 主分支 main 完全由人工接手最后一步 git merge --ff-only + git push
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
UPSTREAM_REMOTE="${UPSTREAM_REMOTE:-upstream}"
|
||||||
|
GITEA_REMOTE="${GITEA_REMOTE:-gitea}"
|
||||||
|
MIRROR_BRANCH="${MIRROR_BRANCH:-ora_main}"
|
||||||
|
TEMP_BRANCH_PREFIX="merge/upstream-"
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# 前置检查
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
if ! git rev-parse --git-dir >/dev/null 2>&1; then
|
||||||
|
echo "Error: 当前目录不是 git 仓库" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! git remote get-url "$UPSTREAM_REMOTE" >/dev/null 2>&1; then
|
||||||
|
echo "Error: remote '$UPSTREAM_REMOTE' 未配置" >&2
|
||||||
|
echo " 添加方式: git remote add $UPSTREAM_REMOTE https://github.com/Wei-Shaw/sub2api.git" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! git remote get-url "$GITEA_REMOTE" >/dev/null 2>&1; then
|
||||||
|
echo "Error: remote '$GITEA_REMOTE' 未配置" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# 1. 拉最新 upstream
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
echo "[1/3] Fetching $UPSTREAM_REMOTE/main..."
|
||||||
|
git fetch "$UPSTREAM_REMOTE" main --tags
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# 2. 刷新 Gitea 镜像分支
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
UPSTREAM_HEAD=$(git rev-parse --short "$UPSTREAM_REMOTE/main")
|
||||||
|
echo "[2/3] Refreshing $GITEA_REMOTE/$MIRROR_BRANCH to $UPSTREAM_REMOTE/main ($UPSTREAM_HEAD)..."
|
||||||
|
# force-with-lease:远端如果在我们 fetch 之后被别人改过会拒绝推送(比 --force 安全)
|
||||||
|
git push --force-with-lease "$GITEA_REMOTE" \
|
||||||
|
"refs/remotes/$UPSTREAM_REMOTE/main:refs/heads/$MIRROR_BRANCH"
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# 3. 状态报告
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
BASE=$(git merge-base main "$UPSTREAM_REMOTE/main")
|
||||||
|
NEW_COMMITS=$(git rev-list --count "$BASE..$UPSTREAM_REMOTE/main")
|
||||||
|
|
||||||
|
echo "[3/3] Status:"
|
||||||
|
echo " upstream/main HEAD : $UPSTREAM_HEAD"
|
||||||
|
echo " $GITEA_REMOTE/$MIRROR_BRANCH : refreshed"
|
||||||
|
echo " 距上次合并到 main 的新 commit : $NEW_COMMITS"
|
||||||
|
|
||||||
|
# 没有 --try-merge 就到此为止
|
||||||
|
if [[ "${1:-}" != "--try-merge" ]]; then
|
||||||
|
echo ""
|
||||||
|
echo "完成。要尝试合并到临时分支:./tools/sync-upstream.sh --try-merge"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# --try-merge 模式
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
if [[ "$NEW_COMMITS" -eq 0 ]]; then
|
||||||
|
echo ""
|
||||||
|
echo "上游无新 commit,跳过合并。"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 预检:列冲突文件
|
||||||
|
echo ""
|
||||||
|
echo "[Pre-flight] 检测预计会冲突的文件..."
|
||||||
|
CONFLICT_LIST=""
|
||||||
|
|
||||||
|
# 优先用 merge-tree --name-only(git >= 2.38)
|
||||||
|
if git merge-tree --name-only --no-messages main "$UPSTREAM_REMOTE/main" >/tmp/.sync-conflicts 2>/dev/null && [[ -s /tmp/.sync-conflicts ]]; then
|
||||||
|
CONFLICT_LIST=$(cat /tmp/.sync-conflicts)
|
||||||
|
else
|
||||||
|
# Fallback:求两边都改过的文件作为「潜在冲突」候选(不一定真冲突,但是个高准确率的提示)
|
||||||
|
CONFLICT_LIST=$(comm -12 \
|
||||||
|
<(git diff --name-only "$BASE" "$UPSTREAM_REMOTE/main" | sort) \
|
||||||
|
<(git diff --name-only "$BASE" main | sort))
|
||||||
|
fi
|
||||||
|
rm -f /tmp/.sync-conflicts
|
||||||
|
|
||||||
|
if [[ -n "$CONFLICT_LIST" ]]; then
|
||||||
|
echo " 以下文件预计需要手动解冲突 (或 auto-merge 后核对):"
|
||||||
|
echo "$CONFLICT_LIST" | sed 's/^/ /'
|
||||||
|
else
|
||||||
|
echo " 无冲突预测,auto-merge 应该干净通过。"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 工作树检查
|
||||||
|
if [[ -n "$(git status --porcelain)" ]]; then
|
||||||
|
echo ""
|
||||||
|
echo "Error: 工作树非干净,请先 commit 或 stash" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 同步本地 main 到远端
|
||||||
|
echo ""
|
||||||
|
echo "[Branch] 同步本地 main 到 $GITEA_REMOTE/main..."
|
||||||
|
git fetch "$GITEA_REMOTE" main >/dev/null 2>&1
|
||||||
|
git checkout main >/dev/null
|
||||||
|
if ! git merge --ff-only "$GITEA_REMOTE/main" >/dev/null 2>&1; then
|
||||||
|
echo " Warning: 本地 main 与 $GITEA_REMOTE/main 不同步(非 fast-forward)。继续基于本地 main。" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 创建临时分支
|
||||||
|
TIMESTAMP=$(date +%Y-%m-%d-%H%M)
|
||||||
|
TEMP_BRANCH="${TEMP_BRANCH_PREFIX}${TIMESTAMP}"
|
||||||
|
|
||||||
|
echo "[Branch] 从 main 创建临时分支 $TEMP_BRANCH..."
|
||||||
|
git checkout -b "$TEMP_BRANCH"
|
||||||
|
|
||||||
|
# 启动合并(不 commit,让人工解冲突)
|
||||||
|
echo "[Merge] 启动 git merge --no-commit --no-ff $UPSTREAM_REMOTE/main..."
|
||||||
|
# || true 因为冲突时 git merge 退出码非 0
|
||||||
|
git merge --no-commit --no-ff "$UPSTREAM_REMOTE/main" || true
|
||||||
|
|
||||||
|
# Next-steps 引导
|
||||||
|
cat <<EOF
|
||||||
|
|
||||||
|
================================================================
|
||||||
|
合并已在分支 $TEMP_BRANCH 上启动(停在 --no-commit)
|
||||||
|
================================================================
|
||||||
|
|
||||||
|
接下来人工操作:
|
||||||
|
|
||||||
|
1. 解冲突(如果有)
|
||||||
|
git status # 看 Unmerged paths
|
||||||
|
# 编辑冲突文件,git add <file>
|
||||||
|
# 全部解完后:
|
||||||
|
git commit -m "Merge upstream/main ($UPSTREAM_HEAD) into $TEMP_BRANCH"
|
||||||
|
|
||||||
|
2. 验证:
|
||||||
|
cd frontend && pnpm run typecheck && pnpm run build
|
||||||
|
cd backend && go build ./cmd/server
|
||||||
|
|
||||||
|
3. 浏览器实测:
|
||||||
|
cd frontend && pnpm run preview
|
||||||
|
# 重点回归我们改过的页面:/ /pricing /docs /login /register
|
||||||
|
|
||||||
|
4. 测试通过后合并到 main:
|
||||||
|
git checkout main
|
||||||
|
git merge --ff-only $TEMP_BRANCH
|
||||||
|
git push $GITEA_REMOTE main
|
||||||
|
|
||||||
|
5. 清理临时分支:
|
||||||
|
git branch -d $TEMP_BRANCH
|
||||||
|
|
||||||
|
放弃合并:
|
||||||
|
git merge --abort
|
||||||
|
git checkout main
|
||||||
|
git branch -D $TEMP_BRANCH
|
||||||
|
|
||||||
|
EOF
|
||||||
Reference in New Issue
Block a user