Files
sub2api/tools/sync-upstream.sh
mini 808b9dd8ad
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
tools(sync-upstream): 上游同步脚本
只刷新 gitea/ora_main 镜像(默认)或 --try-merge 在临时分支启动合并。
永远不直接动 main,最后一步合并由人工 ff-only。包含冲突预检 + 完整
next-steps 引导。
2026-05-03 00:51:55 +08:00

192 lines
6.8 KiB
Bash
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 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-onlygit >= 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