GitLabからGitHubへの移行

# はじめに
GitLabからGitHubへの移行に関して、まとまった記事があまりないなあと思ったのでまとめました。編集リクエストお待ちしています。

# 前提
移行元のGitLabのリポジトリは https://gitlab.mycompany.com/hoge/fuga とする。
移行先のGitHubリポジトリは空のリポジトリを作成していて、 https://github.com/hoge2/fuga2 とする。

# 移行手順

## ソースコードの移行（ブランチ、タグ含む）

### CUIでの方法

CUIでGitLabから--mirrorオプションをつけてcloneし、--mirrorオプションをつけてremoteリポジトリとして移行先を登録する（ここではgithubという名前で登録しています）

```shell
% cd {WORKDIR}
% git clone --mirror https://gitlab.mycompany.com/hoge/fuga
% cd fuga.git/
% git remote add --mirror=push {適当なshortname} ssh://git@github.com/hoge2/fuga2.git
% git push {適当なshortname}
```

### GUIでの方法
GitLabのミラーリング機能を使う。この方法だと、GitHubとGitLabがミラーリングできるので、タイミングを図らなくても移行できる。ミラーリングを切ってもコードはGitHubにはそのまま残るが、GitLabへの変更は同期されない。

1. GitHub のアクセストークンを取得する
1. GitLabのリポジトリページ( https://gitlab.mycompany.com/hoge/fuga )から、Settings > Repository > Mirroring repositories を開く
2. `Git repository URL`に`https://{nishioka_github_username}@github.com/hoge2/fuga2`を入力
3. `Mirror direction`は`Push`、`Authentication method`は`Password`を選択
4. `Password`に GitHub の Access Token を入力
5. `Mirror Repository`を押す
6. `Mirrored repositories`に先ほどの入力内容が反映され、正常にミラーリングされていることを確認する

## Wikiの移行
移行先のリポジトリで適当に１つwikiのページを作っておく。

ソースコードの場合と同様にCUIでGitLabからcloneし、remoteリポジトリとして移行先を登録する。この時、「.wiki」をつけること（下記参照）。

```shell
% cd {WORKDIR}
% git clone --mirror https://gitlab.mycompany.com/hoge/fuga.wiki
% cd fuga.wiki.git/
% git remote add --mirror=push {適当なshortname} ssh://git@github.com/hoge2/fuga2.wiki.git
% git push {適当なshortname}
```

## Milestone, Label, MergeRequest, Issueの移行
[node-gitlab-2-github](https://github.com/piceaTech/node-gitlab-2-github)というツールを使う。手順は下記参照のこと。

参考： [GitLab の Issue を GitHub に移行する node.js スクリプトを試す](https://mseeeen.msen.jp/migrate-gitlab-issues-to-github/)

### Access Token の取得
GitHub と GitLab 双方のアクセストークンを取得する。

### 設定ファイルの編集
```
% cp sample_settings.js settings.js
% vi settings.js
```

```javascript:settings.js
module.exports = {
  gitlab: {
    url: 'https://gitlab.mycompany.com',
    token: 'XXXXXXXXXXXXXXXXXXX',
    projectId: null, // 初回はnullのままにしておく
  },
  github: {
    owner: 'hoge2',
    token: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
    repo: 'fuga2',
  },
  usermap: {
    'nishioka_gitlab_username': 'nishioka_github_username',
  },
  projectmap: {
    'hoge/fuga': 'hoge2/fuga2',
  },
  conversion: {
    useLowerCaseLabels: true,
  },
  debug: false,
  mergeRequests: {
    logFile: './merge-requests.json',
    log: false,
  },
};
```
`projectId: null`のままで`npm run start`実行すると、以下の様にプロジェクトID一覧が表示される。

```shell-session
　...
511 	 XXXXXXXXXX	--	 XXXXXXXXXX
489 	 fuga 	--	 # 移行したいリポジトリ
480 	 XXXXXXXXXX 	--	 XXXXXXXXXX
476 	 XXXXXXXXXX 	--
　...
```

`settings.json`に反映。

```javascript:settings.js
module.exports = {
  gitlab: {
    url: 'https://gitlab.mycompany.com',
    token: 'XXXXXXXXXXXXXXXXXXX',
    projectId: 489, // 移行したいリポジトリのプロジェクトIDをセット
  },
  ...
};
```
### 実行結果

`npm run start`実行すると、以下の様に転送ができます。

```shell-session
==================================
Transferring Milestones
==================================
  ... (略)
==================================
Transferring Labels
==================================
Creating: バグ
Creating: レビュー依頼
Creating: 保留
Creating: 優先度中
  ... (略)
==================================
Transferring Issues
==================================
Transferring 2 issues
Creating: 1 - Data Augmentation
Creating: 2 - no requiremenrs.txt
  ... (略)
==================================
Transferring Merge Requests
==================================
Transferring 2 merge requests
Creating pull request: !1 - add requirements.txt
Merge request !1, source branch: develop-nishioka does not exist
Thus, cannot migrate merge request; creating an issue instead
Creating pull request: !2 - add requirements.txt
Merge request !2, source branch: develop-nishioka does not exist
Thus, cannot migrate merge request; creating an issue instead
  ... (略)


Transfer complete!
```

今回の例ではMerge Requestは転送失敗してますけど...。（おそらく、マージしたらブランチを消す運用なので、今ブランチが存在しないから転送失敗してるのだと思います。