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.

メモ

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

GraphQL クエリを作成するには、独自のスクリプトを記述するか、Insomnia などの HTTP クライアントを使う必要があります。

認証方法など、GitHub GraphQL API の概要については、「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 クエリ

query(
  $login: String!
){
  organization (login: $login)
  {
    login
    id
    name
    databaseId
  }
}
クエリ変数説明
loginOrganization の名前。

GetOrgInfo の応答

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

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移行元の名前。 この名前は自分の参照用であるため、任意の文字列を使用できます。
ownerIdGitHub Enterprise Cloud での Organization の Organization ID。

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"

メモ

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"

メモ

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

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

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

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

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

Step 5: Check the status of your migration

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

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

getMigration クエリ

query (
  $id: ID!
){
  node( id: $id ) {
    ... on Migration {
      id
      sourceUrl
      migrationSource {
        name
      }
      state
      failureReason
    }
  }
}
クエリ変数説明
idstartRepositoryMigration ミューテーションが返した移行の id

Step 6: Validate your migration and check the error log

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

"移行ログ" というタイトルの issue のスクリーンショット。 issue の 2 番目のコメントに、移行に関するログが含まれます。

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

Further reading