跳到内容
SIAX.io

迁移指南 · 来自 GitHub

从 GitHub 迁移到 SIAX Git 和 CI

GitHub 不是糟糕的工具,而且它很少是促使任何人迁移的原因。原因通常有三个:随团队增长而水涨船高的按开发者计费许可成本、难以预测的 CI 分钟数,以及代码和构建链都处于美国司法管辖之下。对面向公共部门或有监管要求的客户销售的公司来说,最后一个论点往往起决定性作用。

我们的 Git 和 CI 是自托管的 Gitea,配 Actions 兼容的 runner,全部位于欧盟。Git 协议是相同的,因此 clone、remote 和工具都能原样工作,工作流语法也基本与 GitHub Actions 相同。价格为 10 个用户 199 克朗/月,相比之下 GitHub 是按开发者许可加上可变的 CI 成本。

坦诚的提醒:Actions 兼容性很好,但并非完全一致。工作流文件通常可以直接搬过去,但个别的 marketplace actions 需要替换,而且 GitHub 生态的某些部分,比如 Codespaces、Advanced Security、Pages、与云提供商的 OIDC 联合,没有对应物。本指南把时间放在真正费力之处:用在流水线上,而不是代码上。

所需时间

对一个带简单流水线的仓库来说,半天。对 20-30 个带活跃工作流的仓库:预计两到三个工作日,其中大部分用于测试工作流,而不是迁移代码。

停机时间

代码零停机。Git 是分布式的,每个人都有完整 clone,因此仓库迁移本身无感。但 CI 存在一段空窗:重写期间会有那么一段,构建只在一个系统上验证过。在让我们的 CI 成为强制检查之前,请两套并行运行直到结果一致。

01

操作步骤

  1. 1

    盘点仓库、工作流和集成

    列出所有仓库,包括最新提交、大小,以及是否使用 LFS。逐个过一遍每个活跃工作流,记录它使用了哪些 actions、读取了哪些密钥以及部署到什么。同时记录 Git 之外的一切:GitHub Apps、webhooks、分支保护、code owners 和必需的 status checks。这份清单才是你真正的规格,而不是仓库列表。

  2. 2

    设置组织、用户和权限

    在我们这里创建组织,并按照与 GitHub 相同的权限级别设置团队。如果你有身份提供者,就通过 OIDC 把登录连接到它,否则使用强制双因素认证的本地账户。立即设置分支保护,推迟很容易,而它要到有人往 main 推送时你才会注意到。

  3. 3

    镜像仓库并迁移 issue 历史

    迁移工具通过 GitHub API、用个人访问令牌拉取仓库、tags、releases、wiki、issues 和 pull requests。先对一个中等规模的仓库做一次测试迁移,检查结果后再迁其余的。LFS 对象和 ghcr.io 中的容器镜像要单独迁移,不在同一批里。

  4. 4

    迁移密钥,并同时轮换它们

    密钥无法从 GitHub 里读出来,所以无论如何都得重新设置。利用这一点:把每个密钥作为迁移的一部分轮换,而不是粘贴相同的值。把多个仓库共享的密钥放到组织级,并记录哪个流水线需要哪些。

  5. 5

    重写工作流,换掉那些带不过来的 actions

    .gitea/workflows 的语法与 GitHub Actions 基本一致,因此文件通常可以直接照搬。然后逐个测试每个工作流:checkout、setup-node、cache 这类常见 actions 正常工作,而调用 GitHub 自己的 API、使用 OIDC 联合、或假定 GitHub runner 镜像的 actions 则不行。显式锁定版本,并用纯 shell 步骤替换失败的。这一步预计会占用最多时间。

  6. 6

    两套系统并行运行,直到结果一致

    把 GitHub 保留为镜像,在某个时段同时推送到两个 remote。在同一 commit 上逐行比较构建日志,差异通常来自 runner 镜像中预装的工具,而不是你的代码。只有当连续十到十五次运行的产出都一致时,才可以把我们的 CI 设为必需的 status check。

  7. 7

    重定向部署目标和 webhooks,然后归档 GitHub

    更新部署密钥、容器仓库,以及所有指向 github.com 的 webhook。如果流水线部署到我们的 App Hosting(从 99 克朗/月起),一个部署密钥加一个 webhook 就够了。把 GitHub 仓库设置为归档、只读模式,而不是删除,否则文档和 issues 中的旧永久链接会失效。至少保留一个季度。

02

真正棘手的地方

  • Marketplace actions 并不总能原样运行。只运行命令的没问题;调用 GitHub 的 REST 或 GraphQL API、对 AWS 或 GCP 做 OIDC 联合、或依赖 GitHub runner 镜像的则不行。逐个测试每个 action,锁定版本,并预计要用 shell 步骤替换掉几个。
  • Runner 镜像不是 GitHub 的 ubuntu-latest。假定某个工具已经安装好的流水线会失败,而且通常是构建深处一个含义不明的错误。与其依赖镜像,不如在工作流中显式安装依赖。
  • 与云提供商的 OIDC 联合会消失。凡是经由 GitHub 的身份提供者获取 AWS 或 GCP 临时凭据的工作流,都必须改用长期密钥或其他机制。这是一项安全回退,应该被有意识地处理,而不是事后才发觉。
  • GitHub 的某些部分没有对应物:Codespaces、Advanced Security 和代码扫描、Pages、Discussions,以及组织级 rulesets。如果其中任何一项对业务至关重要,答案不是全盘迁移,而是迁移能迁移的,并为其余的买单。
  • Issue 历史会以文本形式带过来,但 pull request 的评审讨论串、status-check 历史和指向 github.com 的永久链接不会完整转移。旧文档中的链接仍然指向那里,这正是 GitHub 仓库应该归档而非删除的原因。
03

成本示例

GitHub Team 上一个十人团队,许可费用大约每月 40 USD,约合 450 克朗,再加上超出包含额度的 CI 分钟成本。对一个活跃且并行构建很多的 monorepo 来说,CI 这一项往往比许可还大。价格和包含的额度会不断变化,请核对当前价表。我们这边对应的方案:Git 和 CI,10 个用户 199 克朗/月。需要重度并行构建?我们会在从 890 克朗/月起的专用服务器上为你配置一台专属 runner,这仍然是可预测的,而不是可变的。

04

常见问题

我们的 GitHub Actions 工作流能原样运行吗?
文件通常可以不加修改地复制,语法是相同的。actions 则是另一回事:最常见的那几个能用,但对话 GitHub API 或使用 OIDC 联合的不行。预计要逐一测试和调整每个工作流,而不是盲目搬运。
issues 和 pull requests 会一起迁移吗?
会。迁移工具通过 GitHub API 拉取 issues、pull requests、releases、tags 和 wiki。评审讨论串和 status-check 历史不会完全一致。先在单个仓库上做一次测试迁移,看看结果再决定全量迁移。
我们能并行保留 GitHub 吗?
可以,而且我们建议在过渡期这么做。Git 是分布式的,向两个 remote 推送只是一行配置。很多团队会把 GitHub 永久保留为公共仓库的只读镜像。
ghcr.io 里的容器镜像怎么办?
它们单独迁移。我们的包仓库讲的是同一种 OCI 协议,所以只是重新打标签再推送,外加更新 Kubernetes manifests、compose 文件和部署脚本中的所有 pull 引用。别忘了镜像拉取密钥。
你们有 ISO 27001 或 SOC 2 吗?
没有。我们既没有 ISO 27001、SOC 2,也没有 PCI-DSS。我们有的是 GDPR 合规(所有数据在欧盟境内)、一路开源到底,这样你能审计实际运行的是什么,以及任何时刻都允许你导出数据的合同。如果你的采购流程有认证要求,你应该在项目开始之前就知道这一点。
如果行不通,我们怎么迁出去?
克隆这些仓库,它们包含完整历史。issues 和 pull requests 通过 API 导出,工作流文件也已经在仓库里了。出来和进去同一条路,这正是开放格式的意义。