# 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.

> \[!NOTE] You can also use GL2GH extension of the GitHub CLI to perform your migration. See [Understand migrations from GitLab to GitHub](/es/migrations/using-github-enterprise-importer/migrate-from-gitlab/understand-migrations).

## Step 0: Get ready to use the GitHub GraphQL API

Para realizar consultas de GraphQL, tendrás que escribir scripts propios, o bien usar un cliente HTTP como [Insomnia](https://insomnia.rest/).

Para más información sobre cómo empezar a trabajar con GraphQL API de GitHub, incluido cómo autenticarse, consulta [Formar llamados con GraphQl](/es/graphql/guides/forming-calls-with-graphql).

Enviarás todas las consultas de GraphQL al **destino** de tu migración. Si vas a migrar a Nube de GitHub Enterprise con residencia de datos, asegúrate de enviar consultas al punto de conexión del subdominio de la empresa de GHE.com.

## Step 1: Get the `ownerId` for your migration destination

Como propietario de la organización en GitHub Enterprise Cloud, usa la consulta `GetOrgInfo` para devolver `ownerId`, también denomino id. de organización, para la organización que quieras que posea los repositorios migrados. Necesitarás el valor `ownerId` para identificar el destino de la migración.

#### Consulta `GetOrgInfo`

```graphql
query(
  $login: String!
){
  organization (login: $login)
  {
    login
    id
    name
    databaseId
  }
}
```

| Variable de consulta | Descripción                   |
| -------------------- | ----------------------------- |
| `login`              | El nombre de la organización. |

#### Respuesta `GetOrgInfo`

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

En este ejemplo, `MDEyOk9yZ2FuaXphdGlvbjU2MTA=` es el id. de la organización o `ownerId`, que se usará en el paso siguiente.

## Step 2: Identify where you're migrating from

Puedes configurar un origen de migración mediante la consulta `createMigrationSource`. Tendrás que proporcionar el valor `ownerId`, o id. de organización, recopilado de la consulta `GetOrgInfo`.

Your migration source is your GitLab instance.

### `createMigrationSource` mutation

```graphql
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 consulta | Descripción                                                                                                            |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `name`               | Nombre para el origen de la migración. Este nombre es para referencia propia, por lo que puedes usar cualquier cadena. |
| `ownerId`            | El id. de la organización en GitHub Enterprise Cloud.                                                                  |

### `createMigrationSource` response

```json
{
  "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](https://docs.gitlab.com/api/project_import_export/) 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](/es/migrations/using-github-enterprise-importer/migrate-from-gitlab/manage-access).

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](/es/migrations/using-github-enterprise-importer/migrate-from-gitlab/manage-access). 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.

   ```shell
   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`.

   ```shell
   curl --header "PRIVATE-TOKEN: $GITLAB_PAT" \
     "https://GITLAB-SERVER/api/v4/projects/GROUP%2FPROJECT/export"
   ```

3. Download the archive.

   ```shell
   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](/es/migrations/using-github-enterprise-importer/migrate-from-gitlab/configure-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.

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

> \[!NOTE] 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.

```shell
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"
```

> \[!NOTE] 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.

```json
{
  "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

Al iniciar una migración, un único repositorio y sus datos adjuntos se migran a un repositorio nuevo de GitHub que identifiques.

Si quieres mover varios repositorios a la vez desde la misma organización de origen, puedes poner en cola varias migraciones. Puedes ejecutar hasta cinco migraciones de repositorio a la vez.

### `startRepositoryMigration` mutation

```graphql
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 consulta   | Descripción                                                                                                                                                                                                                                                                                                                                                                                                  |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `sourceId`             | El origen de migración `id` devuelto por la mutación `createMigrationSource`.                                                                                                                                                                                                                                                                                                                                |
| `ownerId`              | El id. de la organización en GitHub Enterprise Cloud.                                                                                                                                                                                                                                                                                                                                                        |
| `repositoryName`       | Un nombre de repositorio único personalizado que actualmente no se use en ninguno de los repositorios propiedad de la organización en GitHub Enterprise Cloud. Se creará una incidencia de registro de errores en este repositorio cuando se complete la migración o se haya detenido.                                                                                                                       |
| `continueOnError`      | Valor de migración que permite que continúe al encontrar errores que no hacen que se produzca un error en la migración. Debe ser `true` o `false`. Se recomienda encarecidamente establecer `continueOnError` en `true` para que la migración continúe a menos que Importer no pueda mover el origen de Git o Importer haya perdido la conexión y no se pueda volver a conectar para completar la migración. |
| `githubPat`            | El valor personal access token de la organización de destino en GitHub Enterprise Cloud.                                                                                                                                                                                                                                                                                                                     |
| `accessToken`          | El valor personal access token para el origen.                                                                                                                                                                                                                                                                                                                                                               |
| `targetRepoVisibility` | La visibilidad del nuevo repositorio. Debe ser `private`, `public` o `internal`. Si no se establece, el repositorio se migra como privado.                                                                                                                                                                                                                                                                   |
| `gitArchiveUrl`        | A 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`.                                                                                                                                                   |
| `sourceRepositoryUrl`  | The 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](/es/migrations/using-github-enterprise-importer/migrate-from-gitlab/manage-access).

En el paso siguiente, usarás el id. de migración devuelto por la mutación `startRepositoryMigration` para comprobar el estado de la migración.

## Step 5: Check the status of your migration

Para detectar errores de migración y asegurarse de que la migración funciona, puedes comprobar el estado de la migración mediante la consulta `getMigration`. También puedes comprobar el estado de varias migraciones con `getMigrations`.

La consulta `getMigration` devolverá con un estado para que sepas si la migración es `queued`, `in progress`, `failed` o `completed`. Si se ha producido un error en la migración, en Importer se proporcionará un motivo para el error.

#### Consulta `getMigration`

```graphql
query (
  $id: ID!
){
  node( id: $id ) {
    ... on Migration {
      id
      sourceUrl
      migrationSource {
        name
      }
      state
      failureReason
    }
  }
}
```

| Variable de consulta | Descripción                                                                                                                 |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `id`                 | El valor `id` de la migración que ha devuelto [la mutación `startRepositoryMigration`](#startrepositorymigration-mutation). |

## Step 6: Validate your migration and check the error log

Para finalizar la migración, se recomienda comprobar la incidencia "Registro de migración". Esta incidencia se crea en GitHub en el repositorio de destino.

![Captura de pantalla de una incidencia con el título "Registro de migración". El segundo comentario de la incidencia incluye registros para una migración.](/assets/images/help/github-enterprise-importer/migration-log-issue.png)

Por último, se recomienda revisar los repositorios migrados para obtener una comprobación de solidez.

## Further reading

* [Follow-up tasks](/es/migrations/using-github-enterprise-importer/migrate-from-gitlab/follow-up-tasks)