从 500 多次 GitHub 迁移中获得的经验教训
Source: Dev.to
请提供您希望翻译的正文内容,我将按照要求把它翻译成简体中文并保留原有的格式、Markdown 语法以及技术术语。谢谢!
介绍
在将 500+ 仓库 从 Azure DevOps、BitBucket、SVN 以及其他系统迁移到 GitHub 后,我们遇到了几乎所有可以想象的迁移挑战。我们构建了一个自动化框架来解决这些问题,并将其开源,以便其他面临企业级 GitHub 迁移的团队能够受益于我们的经验。
本文分享了我们遇到的挑战、我们如何应对,以及 GitHub Copilot 如何通过 基于技能的配置 帮助我们使框架更易维护。
未使用 LFS 的大文件
问题: 仓库中包含大于 100 MB 的大文件,但未使用 LFS 进行跟踪。GitHub 拒绝推送,导致整个迁移受阻。
解决方案:
- 在推送 之前 检测大文件。
- 自动为这些文件配置 Git LFS 跟踪。
- 将已有文件转换为 LFS 存储。
分支命名混乱
问题: 不同系统使用 main、master 或 trunk。流水线中断,受保护的分支失效。
解决方案: 检测源仓库的默认分支,并在迁移过程中 保留它,而不是假设为 main 或 master。
丢失的历史与元数据
问题: 提交作者变成 “migration‑bot”,时间戳消失,分支被扁平化。
解决方案: 使用 git clone(而非迁移 API)来保留完整历史,包括原始作者、时间戳、所有分支、标签和合并拓扑。
密钥扫描障碍
问题: 历史遗留的密钥阻塞整个迁移,需要数小时的人工修复。
解决方案:
- 在迁移期间临时禁用密钥扫描推送保护。
- 立即在迁移后重新启用。
这使团队能够在迁移后修复密钥,而不会阻塞整个过程。
改进空间: 我们当前的方法依赖于团队在迁移后撤销所有泄露的密钥,这在我们的规模下可行。更好的方案可以使用预提交扫描来检测密钥、进行掩码处理,并将发现导出到安全位置供问题发起者处理——但我们发现迁移后撤销更符合我们的实际需求。
SVN 到 Git 的转换
问题: SVN 的 trunk/branches/tags 结构无法干净地映射到 Git refs。
解决方案: 使用 git‑svn 并启用自动布局检测,将 trunk/branches/tags 结构转换为 Git 约定。
权限混乱
问题: 团队失去访问权限,权限分配错误,可见性配置错误。
解决方案:
- 自动创建层级团队(
parent/owner/admin)。 - 在允许迁移之前,验证请求者的团队成员身份。
- 根据 criticality level 设置仓库可见性。
Monorepo 拆分
问题: 从 monorepo 中提取单个文件夹会丢失历史记录,或需要手动使用 git‑filter‑repo 进行处理。
解决方案: 添加一个 only‑folder 参数,使用 git 过滤来迁移特定路径,同时保留相关的提交历史。
集成中断
问题: CI/CD pipelines, Azure Boards, webhooks—everything points to the old repo.
解决方案(Azure DevOps 迁移):
- 自动 rewire pipelines 指向 GitHub。
- 配置 board 集成。
- 将源仓库锁定为 只读。
框架概览
我们在 GitHub Actions 和 PowerShell 上构建了该框架,工作流简洁如下:
- 创建 GitHub Issue,其中包含迁移参数(组织、团队、仓库名称、源 URL)。
- 工作流 验证 团队成员资格和命名规范。
- 创建仓库 并迁移代码,保留完整历史。
- 设置 团队层级 与权限。
- 重新连接 流水线和集成(针对 ADO 源)。
- 在 Issue 上 评论 成功或失败的详细信息。
我们学到的
企业框架的一大挑战是随着需求变化保持其可维护性。我们使用 GitHub Copilot 来帮助解决这个问题。
技能目录
我们在 .github/skills/ 中创建了常见自定义任务的说明。例如:
Use the update-app-name skill to update all references with:
App Name: repo-migrate
App ID: 123456789
Copilot 可以扫描整个仓库并在多个文件中更新引用。
可用技能
| Skill | Purpose(用途) |
|---|---|
add-import-source | 添加对新源码控制系统(GitLab 等)的支持 |
add-custom-properties | 添加仓库元数据要求 |
update-app-name | 更新 GitHub App 引用 |
update-default-org | 更新组织特定的设置 |
Copilot 的帮助
- 更快地添加了新源码系统支持(BitBucket、SVN)。
- 使用适当的错误处理重构了复杂的 PowerShell 函数。
- 从工作流文件生成故障排除文档。
- 通过回答关于代码库的问题,帮助新贡献者快速上手。
这种方法让框架更容易被他人根据其特定需求进行定制。
已知限制与未来工作
我们说实话——这个框架并不完美。以下是我们知道可以改进的方面:
- Secret Handling – 目前我们暂时关闭了密钥扫描,并让团队在迁移后自行处理撤销。更成熟的做法应该是主动检测密钥、在历史记录中对密钥进行掩码处理,并在迁移完成 之前 提供安全报告以便修复。
- Pre‑Migration Validation – 添加仓库健康检查(检测 LFS 文件、大型二进制文件、格式错误的分支名称),并提前生成报告。
- Post‑Migration Verification – 自动比较源仓库与迁移后仓库(提交数量、文件校验和、分支结构),以捕获我们可能遗漏的边缘情况。
如果你在这些方面实现了改进,欢迎分享你的方案!
入门
框架是开源的,仍在不断演进。如果您正在进行企业级 GitHub 迁移,请尝试:
- 仓库: (link to repo)
- 使用仓库 模板 创建您自己的实例。
- 配置 GitHub App 认证(参见 README)。
- 为您的源系统(ADO、BitBucket 等)设置密钥。
- 使用 迁移请求模板 创建一个 issue。
大规模迁移的挑战与技巧
每个组织的需求各不相同,但以下指南可以帮助您规避常见的陷阱。
贡献与获取帮助
- 发现 bug 吗? – 打开 issue
- 有功能请求吗? – 通过打开 issue 告诉我们。
- 为新的源系统添加了支持? – 提交 PR。
- 为您的组织定制过? – 分享成功经验。
.github/skills/ 中的 Copilot 技能 让定制更容易——您可以通过描述需求来添加新的源系统、自定义属性或验证规则。
迁移最佳实践
- 使用试点仓库进行彻底测试 – 大规模迁移会隐藏复杂性;小规模试点有助于及早发现潜在问题。
- 尽可能实现自动化 – 手动迁移无法扩展;对自动化的投入从长远来看回报丰厚。
- 仔细规划权限 – 团队结构的错误后期难以修复。
- 记录边缘案例 – 这些案例在未来迁移中必然会再次出现。
- 分享解决方案 – 开源惠及所有人;贡献您的修复并向他人学习。
有问题或迁移“战场”故事?
在框架仓库中打开 issue。我们很想了解它在您的迁移中是如何(或为何不)工作的!