Skip to main content

Use GraphQL to migrate repositories from GitLab to GitHub Enterprise Cloud

You can build your own tooling to migrate repositories from GitLab to GitHub Enterprise Cloud using the GraphQL API.

Remarque

You can also use GL2GH extension of the GitHub CLI to perform your migration. See Understand migrations from GitLab to GitHub.

Step 0: Get ready to use the GitHub GraphQL API

Pour créer des requêtes GraphQL, vous devez écrire vos propres scripts ou utiliser un client HTTP comme Insomnia.

Pour en savoir plus sur l’utilisation de l’API GraphQL GitHub, notamment sur la façon de s’authentifier, consultez Création d’appels avec GraphQL.

Vous enverrez toutes les requêtes GraphQL à la destination de votre migration. Si vous migrez vers GitHub Enterprise Cloud avec résidence des données, veillez à envoyer des requêtes au point de terminaison du sous-domaine de votre entreprise, GHE.com.

Step 1: Get the ownerId for your migration destination

En tant que propriétaire de l’organisation dans GitHub Enterprise Cloud, utilisez la requête GetOrgInfo pour retourner l’ownerId, également appelé ID d’organisation, pour l’organisation dont vous souhaitez posséder les dépôts migrés. Vous aurez besoin de l’ownerId pour identifier votre destination de migration.

Requête GetOrgInfo

query(
  $login: String!
){
  organization (login: $login)
  {
    login
    id
    name
    databaseId
  }
}
Variable de requêteDescription
loginNom de votre organisation.

Réponse GetOrgInfo

{
  "data": {
    "organization": {
      "login": "Octo",
      "id": "MDEyOk9yZ2FuaXphdGlvbjU2MTA=",
      "name": "Octo-org",
      "databaseId": 5610
    }
  }
}

Dans cet exemple, MDEyOk9yZ2FuaXphdGlvbjU2MTA= est l’ID d’organisation ou le ownerId, que nous utiliserons à l’étape suivante.

Step 2: Identify where you're migrating from

Vous pouvez configurer une source de migration à l’aide de la requête createMigrationSource. Vous devez fournir l’ownerId, ou l’ID d’organisation, collecté à partir de la requête GetOrgInfo.

Your migration source is your GitLab instance.

createMigrationSource mutation

mutation createMigrationSource($name: String!, $url: String!, $ownerId: ID!) {
  createMigrationSource(input: {name: $name, url: $url, ownerId: $ownerId, type: GITLAB}) {
    migrationSource {
      id
      name
      url
      type
    }
  }
}

Set url to the full URL of your GitLab instance, such as https://gitlab.com or https://gitlab.example.com. Make sure to use GITLAB for type.

Variable de requêteDescription
nameNom pour votre source de migration. Ce nom est juste pour vous, donc vous pouvez utiliser n’importe quelle chaîne.
ownerIdID d’organisation de votre organisation sur GitHub Enterprise Cloud.

createMigrationSource response

{
  "data": {
    "createMigrationSource": {
      "migrationSource": {
        "id": "MS_kgDaACQxYmYxOWU4Yi0wNzZmLTQ3NTMtOTdkZC1hNGUzZmYxN2U2YzA",
        "name": "GitLab Source",
        "url": "https://gitlab.com",
        "type": "GITLAB"
      }
    }
  }
}

In this example, MS_kgDaACQxYmYxOWU4Yi0wNzZmLTQ3NTMtOTdkZC1hNGUzZmYxN2U2YzA is the migration source ID, which we'll use in a later step.

Step 3: Generate and host your migration archive

Migrations from GitLab are archive-based. Instead of connecting to your GitLab instance during the migration, GitHub Enterprise Importer imports a migration archive that you generate from your GitLab project. A GitLab archive is a single file that contains both the Git source and the repository's metadata.

Before you start the migration, you must:

  1. Generate a migration archive for the GitLab project you want to migrate.
  2. Host the archive at a URL that GitHub Enterprise Cloud can access.

You'll provide this URL as the gitArchiveUrl value in the next step.

Generating a migration archive

Use the GitLab project export API to export the project you want to migrate. The token you use must have the api scope and a role with permission to export the project. For more information, see Manage access for a migration from GitLab to GitHub.

In the following requests, set the GITLAB_PAT environment variable to the token you created in Manage access for a migration from GitLab to GitHub. Replace GITLAB-SERVER with the host of your GitLab instance, such as gitlab.com, and replace GROUP%2FPROJECT with the URL-encoded path of your project. For example, the project acme-group/my-project is encoded as acme-group%2Fmy-project. For nested subgroups, include the full path, such as parent-group%2Fsubgroup%2Fmy-project.

  1. Schedule the export.

    curl --request POST \
      --header "PRIVATE-TOKEN: $GITLAB_PAT" \
      "https://GITLAB-SERVER/api/v4/projects/GROUP%2FPROJECT/export"
    
  2. Check the status of the export. Repeat this request until export_status is finished.

    curl --header "PRIVATE-TOKEN: $GITLAB_PAT" \
      "https://GITLAB-SERVER/api/v4/projects/GROUP%2FPROJECT/export"
    
  3. Download the archive.

    curl --location \
      --header "PRIVATE-TOKEN: $GITLAB_PAT" \
      --output archive.tar.gz \
      "https://GITLAB-SERVER/api/v4/projects/GROUP%2FPROJECT/export/download"
    

Hosting the archive

You must host the archive at a URL that GitHub Enterprise Cloud can access. You can either upload the archive to GitHub-owned blob storage or use an external blob storage provider. For information about external providers, see Configure blob storage.

To upload the archive to GitHub-owned blob storage, you'll need the database ID of your organization on GitHub Enterprise Cloud. Replace ORGANIZATION with the name of your organization to get this ID from the id field in the response.

curl --header "Authorization: Bearer YOUR-TOKEN" \
  "https://api.github.com/orgs/ORGANIZATION"

Remarque

If you're migrating to GHE.com, replace https://api.github.com with the base API URL for your enterprise's subdomain, such as https://api.octocorp.ghe.com.

Upload the archive with a POST request, replacing ORGANIZATION-ID with your organization's database ID. This request works for archives up to 100 MiB. For larger archives, use an external blob storage provider.

curl --request POST \
  --header "Authorization: Bearer YOUR-TOKEN" \
  --header "Content-Type: application/octet-stream" \
  --data-binary @archive.tar.gz \
  "https://uploads.github.com/organizations/ORGANIZATION-ID/gei/archive?name=archive.tar.gz"

Remarque

If you're migrating to GHE.com, replace uploads.github.com with the uploads host for your enterprise's subdomain, such as uploads.octocorp.ghe.com.

The response includes a uri in the format gei://archive/GUID. Use this value as the gitArchiveUrl in the next step.

{
  "guid": "ff7b1a25-aa10-41a9-8e42-f170304b1c0d",
  "node_id": "MA_kgDaACRmZjdiMWEyNS1hYTEwLTQxYTktOGU0Mi1mMTcwMzA0YjFjMGQ",
  "name": "archive.tar.gz",
  "size": 7103,
  "uri": "gei://archive/ff7b1a25-aa10-41a9-8e42-f170304b1c0d",
  "created_at": "2024-11-13T12:35:45.761-08:00"
}

Step 4: Start your repository migration

Lorsque vous démarrez une migration, un seul dépôt et ses données associées migrent vers un tout nouveau dépôt GitHub que vous identifiez.

Si vous souhaitez déplacer plusieurs dépôts à la fois de la même organisation source, vous pouvez mettre en file d’attente plusieurs migrations. Vous pouvez exécuter jusqu’à 5 migrations de dépôt en même temps.

startRepositoryMigration mutation

mutation startRepositoryMigration (
  $sourceId: ID!,
  $ownerId: ID!,
  $sourceRepositoryUrl: URI!,
  $repositoryName: String!,
  $continueOnError: Boolean!,
  $accessToken: String!,
  $githubPat: String!,
  $gitArchiveUrl: String!,
  $targetRepoVisibility: String!
){
  startRepositoryMigration( input: {
    sourceId: $sourceId,
    ownerId: $ownerId,
    repositoryName: $repositoryName,
    continueOnError: $continueOnError,
    accessToken: $accessToken,
    githubPat: $githubPat,
    targetRepoVisibility: $targetRepoVisibility,
    gitArchiveUrl: $gitArchiveUrl,
    sourceRepositoryUrl: $sourceRepositoryUrl,
  }) {
    repositoryMigration {
      id
      migrationSource {
        id
        name
        type
      }
      sourceUrl
    }
  }
}
Variable de requêteDescription
sourceIdid de votre source de migration retournée par la mutation createMigrationSource.
ownerIdID d’organisation de votre organisation sur GitHub Enterprise Cloud.
repositoryNameNom de dépôt unique personnalisé qui n’est actuellement utilisé par aucun de vos dépôts appartenant à l’organisation sur GitHub Enterprise Cloud. Un problème de journalisation des erreurs sera créé dans ce dépôt une fois votre migration terminée ou arrêtée.
continueOnErrorParamètre de migration qui permet à la migration de se poursuivre en cas d’erreurs qui n’entraînent pas l’échec de la migration. Doit être true ou false. Nous vous recommandons vivement de définir continueOnError sur true afin que votre migration continue, sauf si Importer ne peut pas déplacer la source Git ou que Importer a perdu la connexion et ne peut pas se reconnecter pour terminer la migration.
githubPatpersonal access token pour votre organisation de destination sur GitHub Enterprise Cloud.
accessTokenpersonal access token pour votre source.
targetRepoVisibilityVisibilité du nouveau dépôt. Doit être private, public ou internal. Si elle n’est pas définie, votre dépôt est migré avec une visibilité privée.
gitArchiveUrlA GitHub Enterprise Cloud-accessible URL to the migration archive you generated in the previous step. GitLab migrations use a single archive that contains both the Git source and metadata, so you don't need to provide a separate metadataArchiveUrl.
sourceRepositoryUrlThe URL of your source repository on GitLab, using the format https://GITLAB-SERVER/{group}/{project}. For nested subgroups, include the full path, such as https://GITLAB-SERVER/{parent-group}/{subgroup}/{project}. GitHub Enterprise Cloud does not connect to this URL during the migration; it's recorded for reference.

Because GitLab migrations are archive-based, GitHub Enterprise Cloud does not connect to GitLab during the migration. The accessToken variable is required by the mutation but isn't used, so you can set it to any placeholder value, such as not-used.

For personal access token requirements, see Manage access for a migration from GitLab to GitHub.

À l’étape suivante, vous allez utiliser l’ID de migration retourné par la mutation startRepositoryMigration pour vérifier l’état de la migration.

Step 5: Check the status of your migration

Pour détecter les échecs de migration et vous assurer que votre migration fonctionne, vous pouvez vérifier l’état de votre migration en utilisant la requête getMigration. Vous pouvez également vérifier l’état de plusieurs migrations avec getMigrations.

La requête getMigration est retournée avec un état pour vous indiquer si la migration est queued, in progress, failed ou completed. Si votre migration a échoué, Importer fournit la raison de l’échec.

Requête getMigration

query (
  $id: ID!
){
  node( id: $id ) {
    ... on Migration {
      id
      sourceUrl
      migrationSource {
        name
      }
      state
      failureReason
    }
  }
}
Variable de requêteDescription
idid de votre migration que la mutation startRepositoryMigration a retourné.

Step 6: Validate your migration and check the error log

Pour terminer votre migration, nous vous recommandons de consulter le problème « Journal de migration ». Ce problème est créé sur GitHub dans le dépôt de destination.

Capture d’écran d’un problème avec le titre « Journal de migration ». Le deuxième commentaire du problème contient les journaux d’une migration.

Enfin, nous vous recommandons de passer en revue vos dépôts migrés pour en contrôler l’intégrité.

Further reading