# 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](/ja/migrations/using-github-enterprise-importer/migrate-from-gitlab/understand-migrations).

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

GraphQL クエリを作成するには、独自のスクリプトを記述するか、[Insomnia](https://insomnia.rest/) などの HTTP クライアントを使う必要があります。

認証方法など、GitHub GraphQL API の概要については、「[GraphQLでの呼び出しの作成](/ja/graphql/guides/forming-calls-with-graphql)」を参照してください。

すべての GraphQL クエリを、移行**先**に送信します。 データ所在地付き GitHub Enterprise Cloud に移行する場合は、GHE.com のエンタープライズのサブドメインのエンドポイントにクエリを送信してください。

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

GitHub Enterprise Cloud の Organization 所有者として、`GetOrgInfo` クエリを使って、移行されたリポジトリを所有する Organization の `ownerId` (Organization ID とも呼ばれます) を取得します。 移行先を識別するには、`ownerId` が必要です。

#### `GetOrgInfo` クエリ

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

| クエリ変数   | 説明                |
| ------- | ----------------- |
| `login` | Organization の名前。 |

#### `GetOrgInfo` の応答

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

この例では、`MDEyOk9yZ2FuaXphdGlvbjU2MTA=` が Organization ID つまり `ownerId` であり、次のステップでそれを使います。

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

`createMigrationSource` クエリを使って、移行元を設定できます。 `GetOrgInfo` クエリで収集した `ownerId` つまり Organization ID を指定する必要があります。

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

| クエリ変数     | 説明                                                         |
| --------- | ---------------------------------------------------------- |
| `name`    | 移行元の名前。 この名前は自分の参照用であるため、任意の文字列を使用できます。                    |
| `ownerId` | GitHub Enterprise Cloud での Organization の Organization ID。 |

### `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](/ja/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](/ja/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](/ja/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

移行を始める、1 つのリポジトリとそれに付随するデータが、ユーザーが指定した新しい GitHub リポジトリに移行されます。

同じ移行元 Organization から複数のリポジトリを一度に移動したい場合は、複数の移行をキューに登録できます。 同時に最大 5 つのリポジトリの移行を実行できます。

### `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
    }
  }
}
```

| クエリ変数                  | 説明                                                                                                                                                                                                                                                                                                                                 |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sourceId`             | `createMigrationSource` ミューテーションから返された移行元の `id`。                                                                                                                                                                                                                                                                                   |
| `ownerId`              | GitHub Enterprise Cloud での Organization の Organization ID。                                                                                                                                                                                                                                                                         |
| `repositoryName`       | GitHub Enterprise Cloud 上で Organization が所有するどのリポジトリでも現在使われていない一意のカスタム リポジトリ名。 移行が完了または停止すると、このリポジトリにエラー ログ issue が作成されます。                                                                                                                                                                                                         |
| `continueOnError`      | 移行の失敗を引き起こさないエラーが発生したときに移行を続行できるようにする移行設定。 `true` または `false` である必要があります。 Importer が Git ソースを移動できない場合、または Importer が接続を失い、移行を完了するために再接続できない場合を除き、移行が続けられるように、`continueOnError` を `true` に設定することを強くお勧めします。                                                                                                                          |
| `githubPat`            | personal access token 上の移行先 Organization の GitHub Enterprise Cloud。                                                                                                                                                                                                                                                                |
| `accessToken`          | 移行元の personal access token。                                                                                                                                                                                                                                                                                                        |
| `targetRepoVisibility` | 新しいリポジトリの可視性。 `private`、`public`、または `internal` にする必要があります。 設定されていない場合、リポジトリはプライベートとして移行されます。                                                                                                                                                                                                                                      |
| `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](/ja/migrations/using-github-enterprise-importer/migrate-from-gitlab/manage-access).

次のステップでは、`startRepositoryMigration` ミューテーションから返された移行 ID を使って、移行の状態を調べます。

## Step 5: Check the status of your migration

移行エラーを検出し、移行が行われていることを確認するには、`getMigration` クエリを使って移行の状態を調査できます。 また、`getMigrations` を使うと、複数の移行の状態を調べることもできます。

`getMigration` クエリから返される状態を調べて、移行が `queued`、`in progress`、`failed`、または `completed` であるかどうかを確認できます。 移行が失敗した場合、Importer によってエラーの原因が示されます。

#### `getMigration` クエリ

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

| クエリ変数 | 説明                                                                                     |
| ----- | -------------------------------------------------------------------------------------- |
| `id`  | [`startRepositoryMigration` ミューテーション](#startrepositorymigration-mutation)が返した移行の `id`。 |

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

移行を完了するには、"移行ログ" の issue を確認することをお勧めします。 この issue は、移行先リポジトリの GitHub に作成されます。

!["移行ログ" というタイトルの issue のスクリーンショット。 issue の 2 番目のコメントに、移行に関するログが含まれます。](/assets/images/help/github-enterprise-importer/migration-log-issue.png)

最後に、移行したリポジトリで健全性チェックを確認することをお勧めします。

## Further reading

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