FR | EN
Parler de votre projet

Migrating a Rails Codebase from GitLab to GitHub Without Breaking CI/CD

The git history moves in one command. Everything else, CI, branch protection, integrations, is the actual project.

Publié le 16 juin 2024 · 4 min de lecture

Moving a Rails repository from GitLab to GitHub sounds like a single push to a new remote. The actual work is everything that isn't the code: CI, merge request history, webhooks, and the dozen integrations quietly wired into GitLab-specific behavior.

Git history is the easy part

git clone --mirror git@gitlab.example.com:team/app.git
cd app.git
git remote set-url --push origin git@github.com:team/app.git
git push --mirror

Branches, tags and commit history move over cleanly. What doesn't come with it: merge request discussions, approvals, and CI job history. None of that lives in the git object graph, and GitLab and GitHub don't share a common export format for it.

Rewriting CI is the real project

GitLab CI and GitHub Actions share a lot of concepts, jobs, stages, caching, but not syntax, and some of GitLab's built-in features don't map one-to-one to Actions equivalents. We treat this as a rewrite, not a translation, and run both pipelines in parallel against the same branch for a couple of weeks before cutting over, comparing results job by job.

Branch protection rules don't transfer themselves

Required approvals, required status checks, and merge restrictions all have to be recreated by hand in GitHub's settings, and it's easy to under-specify them the first time. We write the target ruleset down explicitly before the cutover, as a checklist, rather than reconstructing it from memory of how GitLab was configured months earlier.

Webhooks and integrations, audited before, not after

Every external tool wired into the GitLab project, deployment triggers, chat notifications, a status page integration, needs its own equivalent configured on GitHub before the old repository is archived. We run a full audit of GitLab webhooks and project integrations first, migrate each one deliberately, and only archive the GitLab project once nothing is left pointing at it.

The migration itself takes an afternoon. Making sure nothing silently stopped working takes the two weeks around it, and that's the part worth planning for.