DevOps

GitLabからGitHubへの移行|比較検討から実施までの方法をご紹介

菅野

こんにちは、管理職なのに現役で開発大好き、ラーメン大好き菅野です

サンエルでは長らくGitLabを使ってきたのですが、この度GitHubへ移行することになりました。GitLabの公式サイトに記載されている通り、2022年10月19日よりFreeプランが1ネームスペースあたり5ユーザーに制限されてしまったためです。GitLabの機能自体に不満があったわけではなく、今回の変更がなければ今も使い続けていたと思います。やはりDocker同様、GitLabが上場したからでしょうか。GitHubは無料でPrivate Repositoryが持てるようになったのに、GitLabは逆に無料枠の制限が厳しくなった感じです。今回の変更で移行された方は結構多いようですね。

今回の記事では、GitHubに移行するにあたっての導入検討のプロセスを経て、実際に移行してみて分かったことをご紹介します。移行についての情報収集真っ只中の方や、どちらを導入するか検討している方の参考になればと思います。

GitHubへ移行する以前のサンエルの状況と、当記事の対象読者について

本題に入る前に、GitHubへ移行する以前のサンエルの状況についてご紹介します。

  • GitLabを10年以上使っていた
  • GitLabの利用者数はエンジニア7名、テスター3名、プロジェクト管理者3名
  • GitLab CIを使ってCI/CDは一通り組んでいた
  • GitHubは受託など案件の事情で使ったことはあった

対象者

  • 既にGitでの開発をしている人
  • ローカル環境のセットアップが自力でできる人
  • GitHubやGitLabの最低限の操作方法は自力で調べられる方

当記事ではGitの基本的な説明やnode.jsのイントール方法等は説明しませんのでご承知願います。

GitLabとGitHubの比較検討から移行までの流れ

結論

GitLabとGitHubの違いを簡単に知りたい方向けに、私の出した結論を先にお伝えします。

  • 5人以下の規模ならGitLabでも無料なのでお好みで
  • 1人あたり$19/月出せないならGitHub。GitHubなら無料or 1人あたり$4/月
  • $19/月出せて、プロジェクト管理機能を重要視するならGitLab
  • 学習コストを重要視するならGitHub。GitLabは(特に国内)ユーザーがGitHubに比べて少ない

その1 GitLabを継続するかどうかの検討

GitLabを使い続けようとする場合、選択肢は以下3つでした。

  1. 1ネームスペースあたり5ユーザーにならないようにする
  2. 有料版にアップグレードする
  3. 自分でサーバーを立てるSelf-managed版に移行する

まず1は即却下です。端的にいうと、1プロジェクトあたり最大5人までしか使えないからです。また、管理もかなり煩雑になってしまいます。次に2ですが、プランはFree、Premium、Ultimateの3つしかなくて、Premiumはなんと$19もするんですよ。ちょっと、その金額は払いたくないです。残りは3なんですが、実は、サンエルは元々Self-managed版を使ってたんですよ。しかも2年前まで。しかしサーバーのメンテナンスはもちろん、バージョンアップとかも自分たちでやらないと駄目なのでクラウド版に移行した、という経緯があり、今更Self-managed版に戻す気にはなれませんでした。
ということでGitLabからGitHubへの移行が決定しました。

その2 GitHubの料金プランの検討

GitHubはFree、Team、Enterpiseの3つのプランがあり、Teamは1ユーザーあたり月$4です。GitHubに比べるとかなり良心的ですね。Enterpiseは$21なので、GitLabがいかに高いかがわかります。そもそもGitLabは、プロジェクト管理機能がかなり充実しているので、そもそも単純な金額比較しちゃだめなんでしょうけど。

各プランの比較は公式サイトや他サイトにお任せするとして、私はFreeで良いのかどうかのポイントは以下2点だと思ってます。

  1. Organaizationトークンが作れない
  2. DraftのPull Requestが作れない
  3. Protectedブランチの設定ができない

以前は、Private Repositoryに対して制限があったので、企業が利用する場合は有料版(Team)が必須でしたが、今はFree版でも無制限にPrivate Repositoryが作れます。このため、この2点が問題なければ私は無料で十分だと思っています。もちろん、どこを重要視するかで変わってくるとは思いますが、サンエルではドキュメント管理はNotionを使ってるのでGitHubのWikiは不要ですし、GitHub Actionsの実行時間は月2,000分あれば十分です。

1のOrganaizationトークンが使えないのは結構不便で、各プロジェクトで担当ユーザーのPAT(PersonalAccessToken)を使うしかないのですが、管理上よろしく無いので結構問題視しています。2と3はGitLabではFree版でも使える機能なので、使えないのはつらいです。運用事故につながるので、CI/CDを組むような開発規模は、Freeでは厳しいですね。

サンエルでは、とりあえずFree版にして移行をしましたが、この2点が問題なので、今後Team版にする予定です。

その3 実際にGitHubへ移行してみた感想

良かった点

Slack連携が便利

私的にはコレが一番かな。GitLabでも連携はできますが、サインインする機構がないため、Issueの内容はSlack上に表示されません。それに比べ、GitHubはSlack上からIssueの内容が分かり、コメントしたりクローズすることもできます。またSlack上からGitHubにサインインすれば、GitHubのアカウント名からSlackのアカウント名に変換してくれるため、確実にSlack上でメンションされます。これについては、GitLabはメチャクチャ不便でした。SlackにGitHubアプリをイントールできてる前提ですが、対象のチャンネルで

/github signin

と入力して、あとは指示通り連携すれば良いだけです。メチャ簡単。

GitHub Actionsの方が手軽で簡単

これはCI/CDでやりたいことによって変わるとは思いますし、好みもあるかと思いますが、GitLabCIよりGitHub Actionsの方が構築が楽だと感じています。これはユーザー数の多さとMarketPlaceの存在が大きいと思います。一般的なActionは大抵ありますし、やり方もググれば大抵見つかります。GitLab CIは、スクリプトをゴリゴリ書いていく感じですが、GitHub ActionsはActionを呼び出して実行していく感じです。

スマートフォンアプリが便利

これは使ってみるまで全く想定外ですが、メチャクチャ便利です。特に認証周り。2段階認証はアプリ無しだと面倒くさすぎてもう手放せません。またこれはレビュアーとしての使い方ですが、GitHubアプリならなんとかレビューが可能です。GitLabはそもそもアプリが無いのでブラウザで見るしか無いのですが、スマホで操作するのはかなり厳しかったです。出張が多く、急ぎにレビューとかはどうしてもスマホでレビューできると便利なのですが、GitLabの時は諦めてました。GitHubアプリだと快適にできるという訳ではないのですが、レビューしてコメントするなりマージするなりの作業が普通にできます。

悪かった点

やはりプロジェクト管理機能は、GitLabの方に軍配が上がります。

リポジトリをグルーピングできない

これは不便です。特にフロントエンドとバックエンドでリポジトリを分けたいんだけど、1つのプロジェクトとして管理したい場合とかに困ります。その点、GitLabはリポジトリをグルーピングして、IssueのLabelやMilestoneを共有で管理したりできたので便利でした。またグルーピングが無いので、IssueのLabelなども組織内で統一して持つこともできません。Organaizationの設定でデフォルトのLabelを設定できますが、これはあくまでリポジトリ作成時のデフォルトラベルなので、組織全体としてこのLabelを追加したい、とかの場合に一斉に追加する、といったことができません。

Issue単体でボード(カンバン)管理できない

GitLabは、Issue自体にDueDateやMilestoneを設定し、ボードビューで管理することができましたが、GitHubの場合はIssueにその機能はなく、Projectという機能に備わっています。そしてProjectとRepositoryを紐付けることで管理できる仕組みになっています。
これについては、最初は複数のリポジトリを束ねることができるので便利かなと思いました。しかし、実際に使ってみると地味に不便です。UIの構造の問題だと思うのですが、GitHubは、Issueの画面でボード管理できないことや、ボードの画面だとIssueに対する細かい操作ができないといった一面もあります。プロジェクトマネジメントをしている立場としては、細かい操作感がストレスになります。

実際の移行方法

ここからは、実際に移行する作業を説明します。単にソースコードを移行するだけなら簡単ですが、問題はIssueとMerge Requestの移行です。この移行にはhttps://github.com/piceaTech/node-gitlab-2-githubというツールを使用します。使い方はREADMEにかなり丁寧に記載されていますが、主な流れは以下です。

  1. node-gitlab-2-githubをgit cloneする
  2. npmインストールする
  3. GitLabリポジトリからGitHubリポジトリにミラーリングする
  4. sample_settings.tsをsttings.tsにコピーする
  5. settins.tsを編集する
  6. npm run startする

それぞれの細かいやり方については、READMEを見れば分かるので割愛して、ポイントとなる部分を説明していきます。

この移行方法で対応できないこと

このツールでIssueとMergeRequestを移行することができますが、全て完璧に移行できるわけではありません。どれも許容範囲だと思いますが、もし以下の内容が許容できない場合は、この移行方法では対応することができません。

Source Branchが無いMerge RequestをPull Requestに移行できない

Source Branchがある場合はMerge RequestはPull Requestに移行できますが、マージされた時にSource Branchが消される設定にしていたりして、Source Branchが無いMerge Requestは、Pull RequestではなくIssueに変換されて移行されます。移行すると、gitlab merge requestというラベルが自動的に付けられて、CloseされたIssueに追加されます。

IssueやMergeRequestの添付ファイルは移行できない

添付ファイルは、ツールのオプション機能でS3にアップロードすることができますが、ファイルを参照しているURLを置換してくれる訳ではないので、どちらかというと添付ファイルをGitLabからS3に退避してくれるだけです。

IssueのOwner情報は引き継げない

IssueのOwnerは、すべて今回移行する時の実行アカウント、正確に言うと実行する時のスクリプトに設定するアカウント名になってしまいますので、GitLabで発行した時のIssue発行者が誰かは分からなくなってしまいます。

対象ユーザーがいないIssueは移行できない

AssigneeやReviewerに設定されているユーザーがGitHubにいない場合、そのIssueは移行できずにエラーになります。極力移行元のGitLabと移行先のGitHubでアカウントを揃えておいた方がよいです。

1. 事前準備

移行する全てのユーザーのGitHubアカウントを取得してもらい、GitHubのアカウントIDを把握しておきます。またGitHubのOrganaizationを作成しておく必要があります。作成はそれほど難しくありません。準備ができたら、まずは移行するリポジトリをGitHubに作成しましょう。移行先のリポジトリがあれば良いので、リポジトリ設定はとりあえずデフォルトのままで大丈夫です。次にGitHubへのミラーリングですが、これはREADMEのPreliminaries(予備知識)部分に記載されてる通りに実行すればOKです。

2. コード修正

node-gitlab-2-githubなんですが、そのままのコードだと3点問題が起きたので、私は自分のローカルで修正して対応しました。

エラー出力の追加

そのままだと、添付ファイルのアップロードに失敗した時に原因が分からないので出力を追加しました。

       return Buffer.from(data, 'binary');
     } catch (err) {
+      console.log(`err=${err}`)
       console.error(`Could not download attachment #${relurl}.`);
       return null;
     }

LabelがGroup LabelとProject Labelで重複している場合の対応

これは、そもそもLabelが重複している状態になっていること自体良くないのですが、残念ながらGroup LabelとProject Labelで重複していることがありました。おそらく間違って作成してしまい、気付かずに放置されていたのだと思いますが、この場合エラーになって移管できません。そこで強制的に重複除去するコードを追加しました。

       if (settings.conversion.useLowerCaseLabels) {
         labels = labels.map((el: string) => el.toLowerCase());
       }
+      labels = Array.from(new Set(labels))
     }

添付ファイルに日本語が含まれる場合の対応

これは、普通にありえると思います。特にバグIssueに添付されるスクリーンショットなどは、デフォルトが日本語を含むファイル名になっているからです。このため、URLエンコードするように修正しました。

   async getAttachment(relurl: string) {
     try {
-      const attachmentUrl = this.host + '/' + this.projectPath + relurl;
+      const attachmentUrl = encodeURI(this.host + '/' + this.projectPath + relurl);
       const data = (

3. settings.tsの編集と実行

編集方法も、READMEのWhere to find info for the settings.tsでどこに情報が書いてあるか細かく記載されています。AccessTokenの記載場所なども、丁寧に説明書かれてるので、特に迷うことはないと思います。準備が整ったらnpm run startを実行すれば、以下のように結果が出力されます。

$ npm run start

> gitlab-2-github@0.1.5 start
> node node_modules/ts-node/dist/bin.js ./src/index.ts

==================================
Transferring Description
==================================
==================================
Transferring Milestones
==================================
Creating: 初期開発完了
Creating: 納品完了
==================================
Transferring Labels
==================================
Creating: doing
Creating: improvement
Creating: in review
Creating: tested
Creating: testing
Creating: to do
Already exists: bug
Creating: discussion
Already exists: documentation
Already exists: duplicate

〜〜〜〜〜(略)〜〜〜〜〜

==================================
Transferring Releases
==================================
Transferring 0 releases
==================================
Transferring Issues
==================================
Transferring 141 issues.

Migrating issue #1 ('アカウント一覧')...
        Migrating issue comments...
        ...Done creating comments (migrated 11 comments, skipped 3 comments)
        ...DONE migrating issue #1.

〜〜〜〜〜(略)〜〜〜〜〜

DONE creating issues.

        Statistics:
        Total nr. of issues: 141
        Nr. of used placeholder issues: 0
        Nr. of used replacement issues: 0
        Nr. of issue migration fails: 0
==================================
Transferring Merge Requests
==================================
Transferring 218 merge requests
Creating pull request: !1 - 開発環境作成
Pull request #1 (source branch 'sugano/basic_structure' does not exist => cannot migrate pull request, creating an issue instead.
        Migrating pull request comments...
        ...Done creating comments (migrated 24 comments, skipped 3 comments)

〜〜〜〜〜(略)〜〜〜〜〜

Creating pull request: !218 - ページングを100件に変更
Pull request #218 (source branch 'sugano/update_perpage' does not exist => cannot migrate pull request, creating an issue instead.
        Migrating pull request comments...
        ...Done creating comments (migrated 3 comments, skipped 0 comments)

Transfer complete!

ちなみに、実行は結構時間かかります。IssueやPullRequestの数によりますが、合計500件で1時間くらいかかりました。

4. GitLabCIからGItHub Actionsへの書き換え

さて、これでリポジトリの移行は完了です。以上で終わるのであれば大した事ありません。移行が最も面倒なのは、CI/CDの移行です。

一応GitHubにGitLab CiからGitHub ActionsへのMigration方法が記載されています。

https://docs.github.com/ja/actions/migrating-to-github-actions/migrating-from-gitlab-cicd-to-github-actions

ただ私の感想としては、単純に記述方法を変換していくのではなく、GitHubActionsの書き方を覚えてゼロから書き直した方が良いと思います。GitLab CIとGitHub Actionsでは、考え方がそもそも違う上に流儀も異なるため、Migrationする書き方にしてしまうと、GitLabの流儀に引きずられてGitHub Actionsの良さが薄れてしまうからです。

GitLab CIを書いてた人なら、以下を抑えておけば比較的簡単にGitHub Actionsをかけると思います。

・ジョブとランナーの考え方はほぼ一緒
・stageという概念はGitHubには無いのでジョブをグルーピングできない
・ジョブの依存関係はneedsを使う
・useでActionを呼び出す。ActionはMarketPlaceで大抵見つかる
・workflow_callはGitLab CIには無い素敵なジョブ呼び出し機能です
・workflow_dispatchもGitLab CIには無いGUIから呼べる素敵な機能です

まとめ

菅野

いかがでしたか?GitLabから移行を考えてる方、Bitbucket等からどちらに移行するか悩んでる方々にとって、なにかのお役に立てれたら幸いです

個人的はGitLabは長く使っていただけに慣れており、愛着もあったので、今回GitHubへの移行は少し寂しい感じもしますが、やっぱり新しい環境を試すのは楽しいですね。サンエルでは地方を拠点にしてますが、技術に対するアンテナは低くならないように、引き続き精進したいと思います。

最後に、ケース別のオススメをまとめておきます。

ケース別オススメ

今GitLabの人

ユーザー5人以下、または1ユーザー月$19払える人は移管する必要なし

今GitHubの人

RedmineとかJiraとかプロジェクト管理ツールを1つにまとめたいならGitLabに移管はありかも

どちらでも無い人
  • 小規模から手軽に始めるならGitHub。小規模なら無料で十分
  • Pull Requestの制限を書けたいなど組織的な機能が欲しくなったらGitHubの$4のTemaプラン
  • $19払えてプロジェクト管理機能を重視するならGitLab

-DevOps
-,