Commands: - /sync-upstream [--dry-run] — casdoor-internal upstream sync with commit classification - /check-migrations [repo|all] — Alembic/Prisma/Drizzle consistency checker (focuses on xiaoshou pending migrations) Specialist agents: - migration-reviewer — Critical/High/Low severity review for DB schema changes across all 6 repos (Alembic, Prisma, Drizzle, xorm Sync2, raw SQL) Playbooks: - playbooks/casdoor-upstream-rebase.md — quarterly upstream rebase flow with commit classification, batched merging, cross-repo JWT compat check, rollback criteria Hooks (active by default via settings.json): - .claude/hooks/pre-commit-check.sh — PreToolUse on Bash: * blocks inline secrets in command strings (10+ patterns: sk-ant-, ghp_, AKIA, PEM, etc.) * on git commit, scans staged diff for same patterns * blocks diffs > 5000 lines (override with [huge-diff-ok] in commit msg) - settings.json: wire PreToolUse hook
7.2 KiB
Casdoor 上游 Rebase Playbook
频率: 每季度一次,或上游发布新 release 时触发
负责人: 你派给 casdoor-specialist 执行,人类审批
预期耗时: 半天到 1 天
风险等级: 🔴 高(影响全团队认证)
前置条件(全部 ✅ 才能开始)
casdoor-internal/当前 main 分支干净(git status无未提交)- 最近 3 次 CI(
.github/workflows/build.yml+build-and-deploy.yml)都通过 - 生产环境 Casdoor 最近 48 小时没有告警
- 已通知团队"即将 rebase,请暂缓改动 casdoor-internal"
- 生产数据库已做备份(ACA PG 自动快照,确认最近 24h 有快照)
阶段 1:侦察(1-2 小时)
cd /workspace/casdoor-internal
git fetch upstream main
git log --oneline ^HEAD upstream/main | tee /tmp/upstream-commits.txt
对每个 commit 分类(见 /sync-upstream 命令的分类规则)。
产出:reports/casdoor-rebase-plan-<date>.md,包含:
- 上游 commit 总数
- 各等级分类统计
- 🔴/⚫ 清单(需要决策)
- 建议执行顺序
暂停点:把报告发到团队 review,得到 "继续 / 修改计划 / 放弃" 的明确答复再往下走。
阶段 2:准备工作区(30 分钟)
# 拉 rebase 分支
git checkout -b chore/upstream-rebase-$(date +%Y%m%d)
# 记录当前状态
git rev-parse HEAD > /tmp/rebase-baseline-hash
git diff HEAD upstream/main --stat > /tmp/rebase-diff-stat.txt
阶段 3:分批 merge(核心,2-4 小时)
批次 A:🟢 safe commits
while read hash; do
git cherry-pick "$hash" || git cherry-pick --abort
done < <(grep -E "^🟢" /tmp/upstream-commits.txt | awk '{print $2}')
# 验证
make fmt && make vet && make ut
失败的 commit → 跳过,追加到 /tmp/rebase-skipped.txt,不要逼自己过。
批次 B:🔵 feature commits
逐个 cherry-pick + 跑测试。feature 之间有依赖就按时间序。
批次 C:🟡 careful commits
这是最危险的批次。 每个 commit 单独处理:
for hash in <🟡 列表>; do
git cherry-pick "$hash"
# 冲突?进入下面流程
done
🟡 冲突处理流程
git status看冲突文件列表- 对每个文件:
- 读上游改动:
git show $hash:<file> - 读我们版本:
git show HEAD:<file> - 理解上游意图(读 commit message + diff)
- 决策三选一:
- 全接受上游:
git checkout --theirs <file>(仅当我们没碰过这文件) - 保留我们:
git checkout --ours <file>(仅当上游改动与我们无关) - 人工合并:手动编辑,确保既有我们的改动又吸收上游新逻辑
- 全接受上游:
- 读上游改动:
git add <file>- 全部解完
git cherry-pick --continue - 跑
make fmt && make vet立即验证不挂
绝不粗暴 -X theirs 或 -X ours 一把梭。
批次 D:🔴 / ⚫ —— 不做
这批永远不在自动 rebase 范围内。PR 描述里列清楚,交给人类决策。
阶段 4:前端同步(30 分钟)
cd web
yarn install # 拉可能的新依赖
yarn build # 必须通过
yarn test # 如果有测试
cd ..
前端有冲突时参考上面"冲突处理流程"。重点关注:
web/src/App.js路由web/src/Setting.js全局配置- i18n 文件
web/src/locales/*/data.json
阶段 5:全量验证(1 小时)
# Backend
make fmt
make vet
make lint-install && golangci-lint run
make ut
# Docker 构建
sh ./build.sh # 本地 patch 脚本
make docker-build
# 集成烟测(如果本地能起完整栈)
docker compose up -d
sleep 30
curl -f http://localhost:8000/api/get-global-providers || echo "FAIL"
curl -f http://localhost:8000/api/health || echo "FAIL"
docker compose down
阶段 6:跨仓库兼容性验证
上游改动可能影响下游 JWT 解析:
# 1. 找到 JWT claim 结构变化
git diff HEAD~<N>..HEAD -- object/token.go object/application.go | grep -E "(struct|field)"
# 2. 如果 claim 字段变了,必须同步改:
rg -l "casdoor.*jwt|jwt.*casdoor" /workspace/chat-gw/
rg -l "casdoor.*jwt|jwt.*casdoor" /workspace/xiaoshou/
rg -l "casdoor.*jwt|jwt.*casdoor" /workspace/gongdan/
rg -l "casdoor.*jwt|jwt.*casdoor" /workspace/lobechat-enterprise/
如果发现 JWT 字段变化且下游使用: rebase PR 必须引用配套的下游 PR。
阶段 7:出 PR
git push -u origin chore/upstream-rebase-$(date +%Y%m%d)
PR 描述模板:
## 目标
同步 upstream casdoor/casdoor 到 <hash-short> (<date>)
## 执行范围
- 上游 commit 区间:`<old>..<new>` 共 N 个 commit
- 吸收:X safe + Y feature + Z careful
- 挂起:K dangerous + M breaking(见"需人工决策")
## 本地验证
- [x] make fmt / vet / ut / golangci-lint
- [x] yarn build(web)
- [x] sh ./build.sh + make docker-build
- [x] 本地 docker compose 起栈烟测
- [x] 跨仓库 JWT claim 兼容性扫描:<结果>
## 对下游的影响
- chat-gw:<影响/无影响>
- xiaoshou:<...>
- gongdan:<...>
- lobechat-enterprise:<...>
- 配套下游 PR:<链接或"N/A">
## 需人工决策(🔴/⚫)
- [ ] Commit abc: 上游升级 Beego 到 v3 → 我们拒绝(Makefile 锁 v2.3.8)
- [ ] Commit def: 上游改 conf/app.conf 结构 → 需确认 ACA 部署配置
## 跳过的 commit(冲突放弃)
- abc123:package renaming 太复杂
- def456:删了我们重度依赖的 helper
## 回滚方案
基线 hash:`<rebase-baseline-hash>`
回滚命令:`git reset --hard <baseline-hash>` + 重部署 ACA
阶段 8:合并后监控(24 小时)
合并后的生产部署要监控:
- ACA 部署成功(
az containerapp revision list) - Casdoor 首次启动日志无报错
/api/get-global-providers响应正常- 下游 4 个仓库的 JWT 校验正常(用 chat-gw
/healthz做代理指标) - 24 小时内登录成功率无异常跌落
如果 24 小时内出现异常 → 立刻回滚到基线 hash。
常见翻车场景(前人踩过的坑)
场景 1:上游改了 object/user.go 的字段 tag
症状:Sync2 不会改已有列,新 tag 不生效 应对:rebase PR 附带一个人工执行的 DDL SQL 给 DBA
场景 2:上游新增 OAuth provider
症状:需要 secrets 配置,本地开发没配会启动失败
应对:在 conf/app.conf.example 加空配置(skip-worktree 实际文件由 ops 维护)
场景 3:前端路由新增 /discover 或类似
症状:我们之前可能 de-brand 删过
应对:检查 web/src/App.js,决定吸收还是保留删除
场景 4:controllers/account.go 上游改了登录流程
症状:可能破坏我们与下游系统的 SSO 集成 应对:读上游 commit 原文 + 手动测试 Casdoor → chat-gw → xiaoshou 整条链路
放弃阈值
遇到以下情况,立即停止本次 rebase,回 baseline:
- 🛑
make ut失败数 > 10 且 30 分钟修不好 - 🛑 JWT claim 字段变化但下游 PR 需要 > 2 天才能出
- 🛑 上游删除了我们系统依赖的 helper / 接口
- 🛑 需要 Beego / xorm 主版本升级(当前不支持)
回滚:
git checkout main
git branch -D chore/upstream-rebase-$(date +%Y%m%d)
# 写一个复盘记录到 reports/casdoor-rebase-abandoned-<date>.md