在开源项目尤其是大型 monorepo 的维护中,平台迁移已成为常见挑战。Zig 编译器项目最近从 GitHub 切换到 Codeberg(基于 Forgejo),这一过程展示了如何在保留完整 git 历史、LFS 文件、issues/PRs 连续性的前提下,实现 CI/CD 无缝适配,避免任何 downtime。这种工程化迁移策略适用于任何规模的 monorepo 项目,特别是那些依赖 GitHub Actions 但饱受其不稳定困扰的团队。
迁移核心观点:原子切换 + 双轨管理
迁移的核心是 “零丢失、零中断”。传统迁移往往因 history 丢失或 CI 中断导致开发者不满,而 Zig 采用镜像式 git 推送结合编号隔离,确保所有数据完整转移。证据显示,Zig 的 36,057 commits 和 554 MiB 仓库大小在 Codeberg 上完美保留,包括 LFS 二进制(如测试二进制和构建产物)。这种方法避免了数据导出工具的复杂性,直接利用 git 原生能力。
可落地参数:
- 预迁移准备清单:
- 备份:
git clone --mirror https://github.com/ziglang/zig.git zig-mirror.git - LFS 迁移:进入镜像仓库,
git lfs fetch --all/origin;验证git lfs ls-files - Codeberg 新建空 repo:ziglang/zig(无需初始化 commit)
- 备份:
- 推送 history:
cd zig-mirror.git && git remote add codeberg https://codeberg.org/ziglang/zig.git && git push codeberg --mirror- 参数解释:
--mirror推送所有 refs(branches/tags),包括 LFS via git-lfs。 - 阈值:仓库 > 500MiB 时,分批
git push codeberg +refs/heads/master:refs/heads/master避免超时(Codeberg 默认 push 超时 300s,可调至 600s)。
- 参数解释:
这一步耗时视仓库大小,Zig 约需 10-20min,确保网络稳定(使用git config --global http.postBuffer 524288000增大缓冲)。
Issues/PRs 处理:Copy-on-Write 语义
直接迁移 issues/PRs 易导致 ID 冲突和关联丢失。Zig 创新采用 “旧 GitHub 留存、新 Codeberg 从 #30000 起”,实现双轨并行。开发者无需手动搬迁,除非需编辑旧项;新讨论无缝继续。“我们仍会审阅 GitHub 上已开 PR”(Zig 公告)。
可落地清单:
- Codeberg 设置:项目设置 > Issues > 起始编号 = 30000
- 迁移脚本(可选自动化新 issues 链接):
# 示例:webhook监听新issue,跨平台关联 curl -X POST https://codeberg.org/ziglang/zig/issues/30000/comment \ -d 'Related GitHub: https://github.com/ziglang/zig/issues/$GH_ID' - 风险控制:监控双平台活跃度,若 GitHub PR>10 未合,设置 mirror webhook 同步通知。
引用 Zig 公告:“请勿移动现有 GitHub issues/PRs,除非需编辑。” 此策略适用于 > 10k issues 的 monorepo,回滚成本为零。
CI/CD 适配:Forgejo Actions 取代 GitHub Actions
GitHub Actions “vibe-scheduling” 导致 Zig CI 积压,Forgejo Actions(兼容 YAML 语法)提供稳定替代。Zig 已添加.forgejo/workflows目录,适配自托管 runner。
关键参数与配置:
- Runner 注册(自托管避免云限额):
./forgejo-runner register --instance https://codeberg.org --token YOUR_TOKEN \ --name zig-ci --labels ubuntu-latest:docker://node:20-bullseye- labels:
self-hosted,linux,arm64(Zig 跨平台需求) - timeout: 2h(比 GH 默认 1h 长,防大型编译)
- labels:
- Workflow YAML 适配(从
.github/workflows复制):name: CI on: [push, pull_request] jobs: build: runs-on: self-hosted steps: - uses: actions/checkout@v4 with: { fetch-depth: 0 } # 保留history - run: zig build -Doptimize=ReleaseFast # Zig特有 timeout-minutes: 120- 改动:
runs-on: self-hosted;添加cache: { path: ~/.cache/zig }加速。
- 改动:
- 无 downtime 切换:原子更新
build.zig中 CI 脚本指向 Codeberg origin;并行运行双平台 1 周,监控zig build-exe成功率 > 99%。 - 监控点:Prometheus exporter for Forgejo(actions 日志),阈值 alert:job 失败率 > 5%、queue>10。
回滚策略:若 Forgejo 负载高,临时git remote set-url origin https://github.com/ziglang/zig.git(5s 生效)。
工程化监控与最佳实践
- 参数阈值:
方面 参数 推荐值 风险阈值 Git Push http.postBuffer 500MB >1GB OOM Runner timeout 2h <1h 失败 Issues 起始 ID 30000 冲突重置 CI Queue concurrency 5 >20 backlog - 清单:1. 预热 Codeberg quota(Zig 554MiB < 免费 5GB);2. 通知社区(Zig 公告式);3. 捐赠迁移(GitHub Sponsors→Every.org)。
此迁移证明,非营利 Forgejo 在 monorepo 场景下媲美 GitHub,且更稳定。适用于编译器 / 大型 C++ 项目。
资料来源: