cd /news/developer-tools/github-to-gitlab-migration-the-easy-… · home topics developer-tools article
[ARTICLE · art-103502] src=about.gitlab.com ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

GitHub-to-GitLab migration the easy way

GitLab announced that migrating from GitHub to GitLab is easier than ever with its built-in project importer and GitLab Duo AI assistant, which converts GitHub Actions workflows into GitLab CI/CD. The importer automatically transfers most project data, including repositories, issues, pull requests, comments, labels, milestones, and wiki pages, while collaborators, markdown attachments, large comment volumes, Git LFS objects, and secrets require manual handling or caveats. GitLab Duo handles the traditionally manual CI/CD translation, and user contribution mapping (GitLab 17.8+) simplifies attribution without requiring matching public email addresses.

read8 min views4 publishedAug 19, 2026
GitHub-to-GitLab migration the easy way
Image: About (auto-discovered)

Updated on: August 18, 2026

12 min read

Learn how easy it is to migrate from GitHub to GitLab using GitLab's project importer and GitLab Duo AI.

If you're evaluating a move to GitLab, the first question is almost always the same: How hard is the migration? For most DevSecOps teams, the fear of "heavy lifting" is the biggest obstacle between them and a single, AI-native DevSecOps platform.

Migrating to GitLab is easier than ever. GitLab's built-in importer moves the vast majority of your project data automatically and in the background. Additionally, translating your CI/CD pipeline, one part that has traditionally required a human, is now largely handled by GitLab Duo. Duo, our AI-native assistant, can convert GitHub Actions workflows into GitLab CI/CD.

In this post, I'll walk through the full migration end to end:

Let's get started.

GitLab's built-in GitHub importer is accessed directly from GitLab's project creation UI, and it runs as a background job, meaning you can kick off an import and walk away. Most of your project data comes across automatically. A smaller set of items are optional toggles or have caveats worth knowing about up front.

The table below breaks down what migrates and how:

Data Status
Git repository, branches, tags, and commit history ✅ Automatic. Includes fork branches for open pull requests.
Issues ✅ Automatic
Pull requests (become merge requests) ✅ Automatic. Includes reviews, review comments, suggestions, assigned reviewers, and "merged by" info.
Issue and pull request comments ✅ Automatic
Labels and milestones ✅ Automatic
Release notes content ✅ Automatic
Wiki pages ✅ Automatic
Branch protection rules ✅ Automatic
Issue and pull request events ✅ Automatic
Collaborators (members) ⚠️ With caveats. Optional toggle (on by default). Requires the read:org scope; GitHub roles are mapped to GitLab roles (see below). GitHub Enterprise Cloud custom roles aren't supported and are added manually.
Markdown attachments (in descriptions, comments, releases) ⚠️ With caveats. Optional toggle. Attachments in private repos from before May 2023 can't be imported (a GitHub limitation); GitHub Enterprise Server imports only images and video.
Large comment volumes (~30,000+) ⚠️ With caveats. Enable the alternative comments import to work around GitHub's per-issue API limits. Comments from before 2017 may import as separate threads.
Git LFS objects ⚠️ With caveats. LFS must be enabled on the destination project before the import runs, or objects are silently skipped.
GitHub Actions workflows 🛠️ Manual (AI-assisted). Converted to .gitlab-ci.yml . GitLab Duo can do most of this for you.
Secrets → CI/CD variables 🛠️ Manual. Recreate secrets as

GitHub and GitLab use different naming conventions, so a mapping is performed during migration. When collaborators are imported, GitHub roles map to GitLab roles as follows:

GitHub role GitLab role
Read Guest
Triage Reporter
Write Developer
Maintain Maintainer
Admin Owner

The prerequisites have gotten simpler over the years. Notably, you no longer need every GitHub author to have a matching public email address on GitLab. GitLab now handles attribution automatically with user contribution mapping (GitLab 17.8+). More on that below.

To import from GitHub.com or GitHub Enterprise Server into either GitLab.com or a GitLab Self-Managed instance, you need:

A couple of situational prerequisites:

read:org

scope on your token and at least Write or Maintain access on the GitHub project.Previously, contribution history only carried over cleanly if each GitHub user's public email matched their GitLab email. Today, GitLab creates placeholder users for any GitHub author, assignee, or reviewer without a matching GitLab account, and preserves their contributions.

After the import, a group Owner or Maintainer goes to Members → Placeholders and reassigns each placeholder to the real GitLab user, who then accepts the reassignment. This means you can migrate first and sort out attribution afterward.

There are three ways to run the import. Pick the one that fits your source and scale.

This is the fastest path for most teams.

Optional toggles:

Toggle Default Use it when
Import collaborators On You want project members brought over with role mapping.
Import Markdown attachments Off You want images and files embedded in descriptions, comments, and releases.
Use alternative comments import Off Your project has ~30,000+ comments and you're hitting GitHub API limits.

If OAuth isn't configured, authenticate with a token instead.

github.com/settings/tokens/new

with the repo

scope (add read:org

if you're importing collaborators or LFS). Note: Fine-grained tokens aren't supported.For migrating many repositories at once, scripting a move, or importing public repos you don't own, use the import API.

curl --request POST \
  --url "https://gitlab.com/api/v4/import/github" \
  --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "personal_access_token": "<github_classic_pat>",
    "repo_id": 12345678,
    "target_namespace": "my-group",
    "new_name": "imported-project",
    "optional_stages": {
      "single_endpoint_notes_import": true,
      "attachments_import": true,
      "collaborators_import": true
    }
  }'

Track progress with:

curl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
  "https://gitlab.com/api/v4/projects/<project_id>/import"

You'll need a GitHub classic PAT with the repo

scope plus a GitLab PAT with the api

scope.

Once the import finishes, do a quick sanity check:

Re-importing creates a fresh copy (you can't import into an existing project), so if something looks off, delete and re-run.

Migration doesn't have to be a hard cutover. Most teams move gradually, keeping GitHub in play while they stand up GitLab, validate their pipelines, and bring people over team by team. GitLab is designed to coexist with GitHub during that transition, so you can adopt it incrementally instead of flipping a switch overnight.

Here are the main ways the two platforms work side by side while you migrate:

.gitlab-ci.yml

conversion against real commits while the source of truth still lives in GitHub.CI/CD is one part of the migration that isn't automatic. It's your chance to modernize your pipelines. Many core concepts map cleanly between the two platforms:

GitHub Actions GitLab CI/CD
.github/workflows/*.yml .gitlab-ci.yml
Workflow Pipeline
Job Job
Step in a job Line in script:
Event triggers (on: ) rules: / workflow:
runs-on: / container: image: and runner tags:
Actions Marketplace

strategy.matrix

parallel.matrix

actions/checkout

actions/cache

cache:

keywordactions/upload-artifact

artifacts:

keywordA key difference to keep in mind: In GitLab, stages run sequentially and jobs within a stage run in parallel, and you can use needs:

to build an explicit Directed Acyclic Graph (DAG).

GitLab Duo Agent Platform includes a Convert to GitLab CI/CD flow that translates your GitHub Actions workflows into .gitlab-ci.yml

for you, so you're reviewing a draft instead of rewriting from scratch.

GitLab Duo helps across the whole migration, not just conversion:

needs:

DAGs, and CI/CD components.GitLab Duo Agentic Chat can pull in context from your issues, merge requests, and pipelines to answer questions in-platform, and Duo Code Suggestions help as you edit .gitlab-ci.yml

in the Web IDE.

If GitLab Duo isn't available in your environment, the same conversions work well with a frontier model using a structured prompt. A prompt that produces reliable results:

Convert this GitHub Actions workflow to GitLab CI/CD. Preserve matrix builds, job dependencies, artifacts, and conditional rules. Return a valid

.gitlab-ci.yml

.

A few guardrails when using any AI assistant for migration: Never paste secrets, tokens, or internal hostnames; always validate generated YAML with GitLab's CI Lint tool; and treat the output as a reviewable draft, not a final commit.

Whether GitLab Duo drafts the code or you write it by hand, it helps to see the translation. Here's a typical GitHub Actions build-and-test workflow:

name: CI
on: [push, pull_request]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '18' }
      - run: npm install
      - run: npm test
      - run: npm run build

And the equivalent GitLab CI/CD. Notice checkout disappears (GitLab clones for you), runs-on

becomes image

, and each step becomes a line in script:

:

stages: [test, build]

include:
  - template: Jobs/SAST.gitlab-ci.yml

test:
  stage: test
  image: node:18
  script:
    - npm install
    - npm test

build:
  stage: build
  image: node:18
  script:
    - npm install
    - npm run build
  artifacts:
    paths: [dist/]

Matrix builds translate just as directly: strategy.matrix

becomes parallel.matrix

:

test:
  image: node:${NODE_VERSION}
  parallel:
    matrix:
      - NODE_VERSION: ['16', '18', '20']
  script:
    - npm install
    - npm test

And conditional deployments map to rules:

:

deploy:
  stage: deploy
  script: ./deploy.sh
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

Once you commit .gitlab-ci.yml

, GitLab runs the pipeline immediately. To learn more, see the GitLab CI/CD documentation.

GitHub isn't the only source. GitLab's importer supports one-click migration from several other platforms:

We also have documentation covering migrations from:

Thanks for reading! Migration doesn't have to be the scary part of adopting a new platform. GitLab moves your data automatically and GitLab Duo handles the CI/CD conversion, so you can focus on shipping. For more, follow the links below:

Are you just managing tools or shipping innovation?

Quiz will take 5 minutes or less

Enjoyed reading this blog post or have questions or feedback? Share your thoughts by creating a new topic in the GitLab community forum.

Start building faster today

See what your team can do with the intelligent orchestration platform for DevSecOps.

── more in #developer-tools 4 stories · sorted by recency
── more on @gitlab 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/github-to-gitlab-mig…] indexed:0 read:8min 2026-08-19 ·