ghe-migratorを使用して、GitHub.comからGitHub Enterpriseへ移行してみた

GitHub

GitHub.com で管理していたリポジトリを、GitHub Enterprise(GHE) へ移行する手順になります。

概要

Issue や Pull Request 等の内容を含めてリポジトリデータを移行するには、ghe-migrator機能を使用する必要があります。
本記事では、GHEバージョン 2.11 系で実施した際の手順をまとめました。

※ 2018年4月現在のGHE最新バージョンは 2.13 になりますが、大きな変更はないかと思います。
公式ドキュメントも併せてご確認ください。

※ GHEバージョン 2.10 系未満ですと、一部機能の移行に対応していません。ご注意ください。
GitHub Enterprise 2.10.0 Release notes

Use the ghe-migrator tool to migrate pull request reviews, pull request review comments, protected branches, project boards, multiple assignees, and repository deploy keys.

移行の大まかな流れ

  1. GitHub.com の API を叩いて、リポジトリをエクスポートする
  2. エクスポートしたアーカイブの中身を確認する
  3. GHE のサーバに、アーカイブを置く
  4. GHE のサーバで、インポートコマンドを実行する

案外ハマりどころ満載でしたので、順を追って書いていきます。

1. GitHub.com の API を叩いて、リポジトリをエクスポートする

1-1. GitHub.com のアクセストークンを発行する

こちらから発行します。
repo と admin:org の権限をつけます。

1-2. リポジトリをアーカイブ化する

下記コマンドを実行します。

GITHUB_ACCESS_TOKEN: 1-1で発行したアクセストークン
ORG_NAME: 移行元のオーガニゼーション名
REPO_NAME: 移行元のリポジトリ名

lock_repositories の値を true にすると、git pull/push どころか、GitHubのページすら見れなくなってしまう(GitHubが落ちてるのと同じような状態になってしまう)ので、テストで実行する際などには気をつけてください。

コマンド実行後に払い出される id が今後必要になるので控えておいてください。

1-3. アーカイブ化の進行状況を確認

アーカイブ化には時間がかかるので、下記コマンドで進行状況を確認します。

ID: 1-2で払い出された id

リポジトリの容量次第ですが、およそ10分程度を見込んでおくと良いです。
レスポンスの state の値が exported になったら完了です。

1-4. アーカイブをダウンロード

下記コマンドを実行します。

GITHUB_USERNAME: 1-1でアクセストークンを発行したユーザ名

2. エクスポートしたアーカイブの中身を確認する

ダウンロードしたアーカイブの中身は以下のような構成になっています。

migration_archive.tar.gz
├──attachments/
├──attachments_000001.json
├──commit_comments_000001.json
├──issue_comments_000001.json
├──issue_events_000001.json
├──issues_000001.json
├──milestones_000001.json
├──organizations_000001.json
├──projects_000001.json
├──protected_branches_000001.json
├──pull_request_review_comments_000001.json
├──pull_request_review_000001.json
├──pull_requests_000001.json
├──releases_000001.json
├──repositories/
├──repositories_000001.json
├──schema.json
├──teams_000001.json
└──users_000001.json

リポジトリの使用状況によって中身が異なるので注意してください。(Project機能を使ってなければ projects_000001.json は存在しない等)
後にこれらのファイルを GHE にインポートするのですが、注意が必要です

2-1. users_000001.json の中身

リポジトリが所属していたオーガニゼーションのユーザ情報がすべて含まれています。
GHE にインポートした際、GHE のアカウントが存在しないユーザは非アクティブ(有償ライセンスを消費しない)ユーザとして自動作成されます。

明らかにリポジトリに関わっていないユーザが含まれていないか確認しておくことをお勧めします。
リポジトリに関わっていたユーザを削除してしまうと、インポート時にエラーが発生することがありますので、注意してください。

2-2. organizations_000001.json の中身

リポジトリが所属していたオーガニゼーション名と、オーガニゼーションに所属するユーザ情報がすべて含まれています。
GHE にインポートした際、オーガニゼーションが自動生成され、ユーザはアクティブ(有償ライセンスを消費する)ユーザとなってメンバーに追加されます。

購入しているライセンス数以上に有償化が行われることはありませんが、事前に対象のユーザのみが入っているか確認しておくことをお勧めします。

2-3. teams_000001.json の中身

リポジトリが所属していたオーガニゼーションのチーム情報と、各チームに所属するユーザ情報がすべて含まれています。
ユーザはアクティブユーザとなってチームメンバーに追加されます。

購入しているライセンス数以上に有償化が行われることはありませんが、事前に対象のユーザのみが入っているか確認しておくことをお勧めします。

注意点

アーカイブ内のJSONファイルの編集は推奨されていません。
インポート時にエラーが発生する可能性がありますので、可能であればインポート後にユーザのサスペンド等を行なうことを推奨します。

3. GHE のサーバに、アーカイブを置く

scpコマンド等でサーバにアーカイブを転送します。

4. GHE のサーバで、インポートコマンドを実行する

4-1. GHE のアクセストークンを発行する

repo と admin:org の権限をつけます。

4-2. インポート準備のためのコマンドを実行し、GUID を取得する

コマンド実行後に払い出される GUID が今後必要になるので控えておいてください。

4-3. GHE とアーカイブのコンフリクトがないか確認する

GUID: 4-2で払い出されたGUID

コンフリクトの解消方法が出力されるので、CSVファイルとして保存します。
コンフリクトがない(CSVファイルが空の)場合は、4-6までスキップします。

4-4. コンフリクトの解消方法(CSVファイルの中身)を確認する

conflicts.csv

上記は、「GHEに同名のユーザとオーガニゼーションが既に存在しているよ」というコンフリクトの例です。
action は map (既存を優先する)で問題ないので、CSVファイルの編集は行いません。
actionの一覧はこちら

4-5. コンフリクトを解消する

CSVファイルを読み込ませてコンフリクト解消を試みます。
解消できても別のコンフリクトが検出されることがあるので、全て解消するまで 4-3 〜 4-5 を繰り返しましょう。

4-6. インポートを実行する

GHE_USERNAME: 4-1でアクセストークンを発行したユーザ名
GHE_ACCESS_TOKEN: 4-1で発行したアクセストークン

かかる時間はアーカイブの中身次第だと思うのですが、60MBのアーカイブで20分、800MBのアーカイブで30分でした。よく分かりません。

ここでエラーが出て失敗する場合は、JSONファイルの編集内容に問題があると思うので、確認してください。

4-7. 移行が正常に行われたか確認する

インポートが完了したら、下記コマンドを実行します。

アーカイブの JSONファイルのインポート結果が成功失敗問わずすべて出力されるので、
上記のようにオプションで失敗したレコードのみに絞り、 CSVファイルに書き出すことをお勧めします。

audit_failed.csv

失敗した原因等は書かれていないので、URLから推測するしかありません。
GitHub.com と GHE の該当ページを見比べて、違いを確認してください。

または、下記ログファイルに詳細が残っている可能性があります。
/var/log/github/ghe-migrator.log

audit_failed.csv が空だったら、すべて成功してます。

4-8. リポジトリのロックを解除する

GitHub.com は 1-2 で明示的にロックしましたが、移行先の GHE については、移行直後は必ずロック状態になっているので手動で解除する必要があります。

GHE

GitHub.com

以上で移行完了です。お疲れさまでした。
ブラウザで 各ページが問題なく移行できているか確認しましょう。

補足

移行元のオーガニゼーション名と移行先のオーガニゼーション名が違う場合は、conflicts.csv に下記の記述をすることでマッピングできました。

同様に、ユーザ名が異なる場合

ご参考までに。

この記事を書いた人

小野 充輝
小野 充輝
BABYMETALのゆいちゃん推しだった、悲しみに暮れているエンジニアです

GitHub