多仓库同步系统
这是一个支持多方向、多仓库批量同步的自动化流水线系统,适用于在不同 Git 服务器之间同步代码的场景。
🚀 功能特性
- 多方向同步:支持 A→B, B→C, A→C 等多种同步方向
- 独立配置:每个同步方向使用单独的配置文件和流水线
- 环境隔离:每个方向使用不同的环境变量前缀,安全性更高
- 批量同步:每个方向可以通过配置文件管理多个仓库
- 灵活调度:每个方向可以配置不同的定时任务
- 手动触发:支持手动触发单个方向的同步
- 详细日志:提供每个仓库同步过程的详细日志
- 冲突自动处理:使用
reset --hard策略,确保目标仓库完全同步为上游状态
📁 项目结构
code-sync-project/
├── .gitea/
│ └── workflows/
│ ├── sync_A_to_B.yml # A→B 同步流水线
│ └── sync_B_to_C.yml # B→C 同步流水线
├── configs/
│ ├── A_to_B.yaml # A→B 同步配置
│ └── B_to_C.yaml # B→C 同步配置
├── scripts/
│ └── sync_tool.py # 核心同步工具(支持动态环境变量前缀)
├── repos.yaml # 旧版单配置文件(向后兼容)
├── sync_repos.py # 旧版同步脚本(向后兼容)
└── README.md # 本文档
🔧 配置说明
1. 配置 Secrets
在 Gitea 仓库的 Settings > Secrets 中配置以下变量:
对于 A→B 同步:
SYNC_A_B_USERNAME=your_username # 源A的用户名
SYNC_A_B_TOKEN=your_token # 源A的访问令牌
对于 B→C 同步:
SYNC_B_C_USERNAME=your_username # 源B的用户名
SYNC_B_C_TOKEN=your_token # 源B的访问令牌
注意:每个同步方向使用不同的环境变量前缀,确保安全性。
2. 配置同步任务
编辑 configs/A_to_B.yaml:
name: "A_to_B_Sync" # 同步任务名称
repositories:
- name: "bladex-tool"
source_url: "https://${USERNAME}:${TOKEN}@center.javablade.com/blade/BladeX-Tool.git"
target_url: "https://${USERNAME}:${TOKEN}@gitea.fjy8018.top/BladeX/BladeX-Tool.git"
branch: "master"
# 添加更多仓库...
编辑 configs/B_to_C.yaml:
name: "B_to_C_Sync" # 同步任务名称
repositories:
- name: "bladex-tool"
source_url: "https://${USERNAME}:${TOKEN}@gitea.fjy8018.top/BladeX/BladeX-Tool.git"
target_url: "https://${USERNAME}:${TOKEN}@backup.example.com/backup/BladeX-Tool.git"
branch: "master"
# 添加更多仓库...
配置字段说明:
| 字段 | 必填 | 说明 |
|---|---|---|
name |
是 | 同步任务名称,用于日志输出 |
repositories[].name |
是 | 仓库标识名称 |
repositories[].source_url |
是 | 上游仓库地址,使用 ${USERNAME}:${TOKEN} 格式 |
repositories[].target_url |
是 | 目标仓库地址,使用 ${USERNAME}:${TOKEN} 格式 |
repositories[].branch |
否 | 要同步的分支,默认为 master |
3. 定时任务
A→B:每天凌晨 2 点执行(.gitea/workflows/sync_A_to_B.yml)
schedule:
- cron: '0 2 * * *'
B→C:每天凌晨 3 点执行(.gitea/workflows/sync_B_to_C.yml)
schedule:
- cron: '0 3 * * *'
可以在对应的 workflow 文件中修改 cron 表达式。
🚀 使用方法
方法 1:自动触发
当满足以下条件之一时自动触发:
- 定时任务到达设定时间
- 修改了对应的配置文件
- 修改了对应的流水线文件
- 修改了核心脚本
sync_tool.py
方法 2:手动触发
进入 Gitea 仓库页面的 Actions 标签页:
- 选择 "同步 A → B" 或 "同步 B → C"
- 点击 Run workflow
- 查看执行日志
📊 执行结果
执行后,Actions 页面会显示:
================================================================================
多仓库同步工具
================================================================================
开始时间: 2025-11-22 10:00:00
配置文件: configs/A_to_B.yaml
环境前缀: SYNC_A_B
✓ 配置任务: A_to_B_Sync
✓ 找到 2 个仓库配置
[1/2] 正在同步...
============================================================
开始同步仓库: bladex-tool
源地址: ***:***@center.javablade.com/blade/BladeX-Tool.git
目标地址: ***:***@gitea.fjy8018.top/BladeX/BladeX-Tool.git
分支: master
============================================================
[1/6] 克隆目标仓库...
[2/6] 添加上游远程...
[3/6] 获取上游更改...
[4/6] 检查分支...
[5/6] 同步到上游分支 (使用 reset --hard)...
[6/6] 推送到目标仓库...
✅ [bladex-tool] 同步成功!
================================================================================
同步完成报告
================================================================================
✅ 成功 bladex-tool
✅ 成功 another-repo
总计: 2 个仓库
成功: 2 个
失败: 0 个
✅ 所有仓库同步成功!
结束时间: 2025-11-22 10:05:00
🔧 添加新的同步方向
要添加新的同步方向(例如 A→C):
步骤 1:创建配置文件
cp configs/A_to_B.yaml configs/A_to_C.yaml
编辑 configs/A_to_C.yaml:
name: "A_to_C_Sync"
repositories:
- name: "bladex-tool"
source_url: "https://${USERNAME}:${TOKEN}@center.javablade.com/blade/BladeX-Tool.git"
target_url: "https://${USERNAME}:${TOKEN}@backup.example.com/backup/BladeX-Tool.git"
branch: "master"
步骤 2:创建流水线
cp .gitea/workflows/sync_A_to_B.yml .gitea/workflows/sync_A_to_C.yml
编辑 .gitea/workflows/sync_A_to_C.yml:
name: "同步 A → C"
env:
CONFIG_FILE: 'configs/A_to_C.yaml'
# ... 其他配置 ...
- name: 执行同步 A → C
env:
SYNC_A_C_USERNAME: ${{ secrets.SYNC_A_C_USERNAME }}
SYNC_A_C_TOKEN: ${{ secrets.SYNC_A_C_TOKEN }}
run: |
python3 scripts/sync_tool.py ${{ env.CONFIG_FILE }} --env-prefix SYNC_A_C
步骤 3:配置 Secrets
在 Gitea 中配置:
SYNC_A_C_USERNAMESYNC_A_C_TOKEN
步骤 4:提交并推送
git add configs/A_to_C.yaml .gitea/workflows/sync_A_to_C.yml
git commit -m "添加 A→C 同步方向"
git push
🛠️ 本地测试
在本地测试同步:
# 设置环境变量
export SYNC_A_B_USERNAME="your_username"
export SYNC_A_B_TOKEN="your_token"
# 运行同步
python3 scripts/sync_tool.py configs/A_to_B.yaml --env-prefix SYNC_A_B
⚠️ 重要说明
-
强制同步策略:使用
git reset --hard策略,确保目标仓库完全与上游一致。任何在目标仓库上的修改都可能被覆盖。 -
权限要求:提供的 Token 必须有对目标仓库的写入权限。
-
冲突处理:由于采用强制重置策略,不会保留目标仓库与上游的冲突修改。
-
大仓库同步:对于大型仓库,可能需要调整流水线超时时间。
-
私有仓库:需要确保 Token 具有访问私有仓库的权限。
🔍 故障排除
问题:权限被拒绝(Permission denied)
解决方案:
- 检查 Secrets 中的用户名和 Token 是否正确
- 确认 Token 具有 repo 范围的权限
- 验证仓库 URL 是否正确
问题:仓库不存在
解决方案:
- 在目标服务器上预先创建空仓库
- 检查配置文件中的仓库地址是否正确
问题:同步超时
解决方案:
- 在 workflow 文件中增加超时时间
- 检查网络连接是否稳定
问题:环境变量未设置
解决方案:
- 检查是否在 Gitea Secrets 中配置了对应的变量
- 检查环境变量前缀是否与配置文件中的一致
- 查看日志中的环境变量检查输出
📖 最佳实践
- 分环境配置:不同环境(开发/测试/生产)使用不同的配置
- 逐步添加仓库:初次使用时,先配置 1-2 个仓库测试
- 监控执行:定期检查 Actions 执行日志
- 测试环境:先在测试仓库验证同步逻辑
- 备份策略:重要仓库确保有备份机制
- 安全隔离:不同方向使用不同的 Token,降低风险
🔄 向后兼容
保留旧版文件以支持单配置文件场景:
repos.yaml- 单配置文件sync_repos.py- 旧版同步脚本.gitea/workflows/multi-repo-sync.yml- 旧版流水线
如需使用旧版,请配置以下 Secrets:
UPSTREAM_USERNAMEUPSTREAM_TOKENTARGET_USERNAMETARGET_TOKEN
建议:新项目使用新版多配置文件架构。
🤝 贡献
欢迎提交 Issue 和 Pull Request 来改进这个工具!
📄 许可证
MIT License