弁護士ドットコム株式会社 Creators’ blog

弁護士ドットコムがエンジニア・デザイナーのサービス開発事例やデザイン活動を発信する公式ブログです。

さよなら Tanuki こんにちは Octocat (GitLab から GitHub へ移行しています)

この記事は 弁護士ドットコム Advent Calendar 2025 の 20 日目の記事です。

こんにちは。クラウドサインの SRE として働いている中村です。

最近は応援している J リーグのチームである鹿島アントラーズが 9 年ぶりのリーグ優勝を果たし、優勝記念グッズへの投資が止まりません。

鹿の話はさておきこの記事のタイトルについて補足説明します。

Tanuki は皆さんご存じ GitLab のロゴとして有名なタヌキです1。Octocat も皆さんご存じ GitHub で利用されるキャラクターです。ちなみに名前は Monalisa(モナリサ)です2

というわけで Tanuki から Octocat へ。

弁護士ドットコム社では長らく利用していた GitLab から GitHub への移行が進んでいます。

本記事では GitLab から GitHub への移行にあたって考えたポイントやハマったことを紹介します。

前提

まず弊社の体制について紹介させてください。

弁護士ドットコム社では、弁護士ドットコム税理士ドットコムクラウドサインLegalBrain などの複数のプロダクトを提供しています。

全社のエンジニア組織内にそれぞれのプロダクト開発を担当しているエンジニア組織があり 2025 年 11 月時点で 170 名弱のエンジニアが在籍しています。

私はクラウドサインのエンジニア組織で Embedded SRE としてクラウドサインに関する SRE 業務やプラットフォーム整備に携わっていますが、弊社には全社横断で SRE 業務やプラットフォームの整備を進めている SRE 室という組織もあります。

今回の GitHub 移行では SRE 室が GitHub のオーナーとして全社方針を設計しつつ、クラウドサインのリポジトリ移行にあたっての設計をクラウドサインの SRE が行いました。

GitHub 移行にあたって話題になる問題としては GitHub Actions への移行がありますが、この記事では CI/CD に関する移行よりも GitHub 自体への移行をオーナーではない状況ですすめていくために設計したことやはまったことに重点を置いて紹介します。

GitHub 移行における設計

弊社が利用する GitHub Enterprise プランには次のような要素で構成されています。

要素 意味
Enterprise 複数の Organization を管理する共有アカウント
Organization Team と Repository を管理する共有アカウント
Team Organization に所属するメンバーのグループ
Repository 特定のプロジェクトに関するすべてのファイルを含む単位
User Account GitHub の利用者がログインするアカウント。マネージドユーザーアカウントと個人用アカウントが存在

これらの要素の関係性を図で説明します。

GitHub Enterprise がもつ要素間の関係を示した構造図
GitHub Enterprise の構成要素

移行にあたっての各要素の状況としては次のとおりでした。

  • Enterprise アカウントが作成済みで主に情シスが Enterprise オーナーとして管理
  • Organization は全社共通の Organization が作成済みで SRE 室が Organization オーナーとして管理
  • Organization の設定は SRE 室管理の terraform リポジトリで管理されているが、リポジトリやチームは管理されていない
  • Enterprised Managed Users を有効化してマネージドユーザーアカウントを利用している

これらを踏まえてクラウドサインとしては次の選択が必要でした。

  1. クラウドサイン用の Organization を作成してクラウドサインの SRE がオーナーとなる
  2. クラウドサイン用の Organization を作成して SRE 室がオーナーとなる
  3. 全社共通の Organization を利用してクラウドサインの SRE もオーナーとなる
  4. 全社共通の Organization を利用してクラウドサインの SRE はオーナーにならない

Organization をどう利用するか。利用する Organization に対してどのような権限を持つかはどのように考えるべきなのでしょうか。

Organization の利用

Organization をどのように利用するかにあたっては GitHub が Enterprise 内の Organization 構成に関するベストプラクティスGitHub Enterprise の Organization に関するガイド を公開しています。

これらをまとめると次のような内容が紹介されています。

  • Organization は作業プロジェクトやガバナンス要件でグループにする
  • Organization は削除よりも追加が簡単なので最小が望ましい
  • 複数 Organization を採用するケース
    • Organization のオーナー単位でリポジトリのアクセス権を制御すべき場合
    • ポリシー、設定、要件を個別に構成する必要がある場合
  • Organization と会社のエンティティを紐づけるのは非推奨
    • 紐づけるのであれば構造エンティティが望ましい

別のプロダクトであるという理由や会社の組織構造を理由に Organization を別にしてしまうことは推奨されていないようです。

統制という観点では分離しても良さそうですが、むしろ明確な理由や要件がなければ Organization を分ける必要はないといえそうです。

Organization のオーナー構成例は紹介されていませんが、ベストプラクティスやガイドの内容から考えると、それぞれ別のオーナーが管理する形や Organization 内で役割の違うチームがオーナーになることは管理面での調整やコミュニケーションコストが発生しそうです。

クラウドサインの開発、運用においてどのような要件があるかで構成を考えていくことにしました。

クラウドサインにおける要件

クラウドサインでは ISMAP(政府情報システムのためのセキュリティ評価制度)3の登録を受けています。

この制度は、政府が求めるセキュリティ基準を満たしているかを客観的に評価するもので、変更管理やアクセス制御を含む、厳格な管理基準の遵守が求められます。

GitHub 移行にともないこの評価制度を維持するための運用要件を確認したところ、供給者としての管理の他に次のような要件を満たすことが必要でした。

  1. 監査ログが取得されていること
  2. ユーザーアカウントの管理が適切に行われていること
  3. ソースコードに関するアクセス制御が行われていること

この要件の 1、2 は Organization よりも上位の Enterprise の設計ですでに実現されていることがわかりました。

クラウドサインとしては 3 のアクセス制御要件をふまえて Organization の利用方針を決められそうです。

アクセス制御として考慮すべき点を社内で確認したところ次の 2 点が必要でした。

  • ソースコードが社外公開されないようになっていること
  • ソースコードは制限されたメンバーのみに変更可能とすること

前者は文字通りリポジトリの公開設定です。

後者は『クラウドサインの開発、運用者だけがソースコードを変更できる』状態、もしくは『クラウドサインの開発、運用者がソースコードの変更を承認すること』で評価制度のために定めた要件を満たしているとみなせることを確認しました。

またこれらの要件に関する設定はクラウドサインの開発、運用者で常時変更できる状態にせず、クラウドサインの組織外の管理者に管理を委ねることで責任範囲が明確になり統制を効かせやすいのではと考えました。

クラウドサインで採用した Organization の設計

今回は クラウドサインのリポジトリは全社の Organization 内で管理し、クラウドサインの SRE は Organization のオーナーにならない 選択をしました。

まず『ソースコードの社外公開設定(リポジトリの公開設定)』は全社共通 Organization の設定として SRE 室がコードオーナーの terraform リポジトリで管理されていました。

クラウドサインの開発、運用者以外により管理され、変更の際にはレビューも行われており Organization の分割や権限を移譲してもらう理由はありませんでした。

次に『ソースコードの変更制御』は全社共通 Organization の設計として Organization 内のリポジトリに対する全プロダクトの開発、運用者への変更権限の付与が行われていました。

これはプロダクトを超えた情報共有やコラボレーションを目的としたもので弊社のエンジニア組織のポリシーに基づくものでした。

既存の設計を踏まえると Organization の分割によるアクセス制御も考えられましたが『クラウドサインの開発、運用者がソースコードの変更を承認すること』でもアクセス制御の要件は満たせます。

エンジニア組織としてのポリシーの踏襲を優先し Organization を分割する判断はしませんでした。

権限に関しては terraform で管理されており、クラウドサインの SRE チームが権限を持たなくても必要に応じて変更リクエストが出せること、同じ Organization を利用することで最初に紹介した GitHub の各要素について階層構造で責任範囲を明確にできるためオーナーにならない判断をしました。

  • Enterprise: 情シスが管理(オーナー)
  • Organization: SRE 室が管理(オーナー)
  • Repository: クラウドサイン SRE チームが管理(管理者)

また Organization を分けない構成の方が AI エージェントやツールの導入に関する設計や運用の効率化においてもメリットをうけられそうなことも判断材料の 1 つとなりました。


クラウドサインではこのような設計で GitHub 移行を進めています。

アプリケーションのリポジトリや運用用途でのリポジトリが 85 個存在していましたが、SRE だけではなくエンジニアの協力もあり 2025 年 12 月現在約 80 %のリポジトリ移行が完了し GitHub での運用に切り替わっています。

まだ道半ばではありますが、すでにいくつかハマった点を紹介しておきます。

ここにはまった GitHub

プルリクエストのレビュアーにしたチームの削除タイミング

GitHub ではレビュアーにチームを割り当てることでチームのメンバーを自動アサインしたり、チームに通知できます。

このレビュアーへのチーム割り当てに関する理解不足がありました。

前述した『クラウドサインの開発、運用者がソースコードの変更を承認すること』を Organization のブランチ保護ルールとコードオーナーで実現しました。

次のような設定です。

  • Organization のブランチ保護ルールで Require review from Code Owners を有効化
  • クラウドサインの各リポジトリで CODEOWNERS ファイルにクラウドサインの開発、運用者全員が所属する GitHub のチームを指定

あわせて GitHub のチームを次のように設計しました(チーム名は仮称です)。

  • 親チーム(レビュアーの自動アサインなし)
    • all-engineer
      • クラウドサインの開発、運用者全員
      • CODEOWNERS ファイルにコードオーナーとして記載
  • 子チーム(レビュアーの自動アサインあり)
    • backend-enginer
      • クラウドサインのバックエンド領域が得意な開発、運用者
    • frontend-enginer
      • クラウドサインのフロントエンド領域が得意な開発、運用者
    • infra-engineer
      • クラウドサインのインフラ領域が得意な開発、運用者

クラウドサインの開発、運用者のレビューを必須としつつ、レビュアーの自動アサインをプルリクエストの変更内容に応じて行いたかったことが狙いです。

このような構成をとることで期待した挙動は以下です。

  1. プルリクエスト作成画面でレビュアーに必ず all-engineer チームが割り当てられる(クラウドサインの開発、運用者のレビューを要求)
  2. プルリクエスト作成画面で 1 と合わせてランダムアサイン用のチームをレビュアーに割り当ててプルリクエストを作成する
  3. プルリクエスト作成完了時に 2 で指定したチームのメンバーがレビュアーとして割り当てられる
  4. 3 が行われることで all-engineer とランダムアサイン用のチームがレビュアーから削除されメンバーのみがレビュアーに残る

ところが GitHub への移行後に運用開始すると 4 で削除されるのはランダムアサイン用のチームだけでした。

事前検証では動作した気がしたのですが、次のように GitHub のドキュメントに明記されており完全に認識違いでした。

コードオーナーが自動的にレビューをリクエストされた場合でも、ブランチ保護ルールがコードオーナーからのレビューを必須として設定されていないかぎり、やはりTeamは外され、個人に置き換えられます。 そういったブランチ保護ルールがある場合、Team 要求は削除できないので、Team に追加される形式で個々の要求が表示されます。 レビューが完了すると、Team は削除されます4

今回の設定ではブランチ保護ルールがコードオーナーのレビュー必須に設定されているため、コードオーナーとして指定されたチームがレビュアーから削除されるのは、そのチームのメンバーがレビューへのコメントや承認、変更リクエストを行ったタイミングだけです。

この仕様の理解不足によりプルリクエスト作成完了時にはメンバーに加えてコードオーナーである all-engineer チームも割り当てられた状態となり、すべてのプルリクエストでチーム宛の通知が発生することになってしまいました…。

チームの通知設定を無効化しても通知量は多く特に GitHub 上の通知画面でのアサイン状況の把握が難しくなってしまいました。

GitHub の通知画面で Review requested が 1,000 件表示されている状況
Review requested が機能していない状況

ひとまずは slack 連携による個人のリマインダー設定やプルリクエスト一覧画面でのフィルタークエリをブックマークすることで対応してもらっています。

またシンプルに運用すべく 2025 年 11 月に発表されたチームレビュー機能5 の活用や、パスやファイルタイプによるコードオーナーの指定でレビュアーへの割当を上手くコントロール出来ないかを検証中です。

特殊ケースな気もしますが、レビュアーが削除されるタイミングにはご注意ください。

terraform-provider-github による GitHub の設定管理

クラウドサインの SRE チームは権限を持たず、必要に応じて変更リクエストを出すために terraform を活用する想定でしたが、実際に開発していく中で terraform だけでは完結できないことがわかりました。

terraform では terraform-provider-github を利用することで GitHub の設定を管理します。

こちらで一通りの設定作業は可能だと思っていたのですが、構築時点で利用していた v6.3.0 では例えば次のような操作は terraform で実現できませんでした。

  • GitHub Apps の Organization へのインストール
  • GitHub Apps のアクセス可能なリポジトリの変更
  • GitHub Apps の権限変更
  • GitHub Packages コンテナレジストリに対するリポジトリ権限設定
  • GitHub Pages の Enforce HTTP 設定
  • ブランチ保護ルールでマージ方法の変更6

なお記事執筆時点での最新版は v6.9.0 です。詳細は最新版のドキュメントも確認してみてください。

これらの制限により terraform で完結させることが難しく、特に GitHub Apps 関連では SRE 室の作業を増やすことになってしまいました。

GitHub の Organization で作成できるカスタムロールは権限のメンテが煩雑だと判断して利用を避けていましたが、terraform によるコード管理にこだわらずカスタムロールを発行してもらうのがお互いの作業を楽にできたかもしれません。

もちろんこの制限は terraform-provider-github の問題ではなく、プロバイダー、GitHub どちらも開発、改善が行われ続けていることによるものです。

弊社でも利用するだけではなく出来ないことをリポジトリへフィードバックし、開発に貢献していきたいと考えています。

プロバイダーの開発は今も行われておりマイルストーンも公開されています7。最新状況をふまえて利用方針の決定や、カスタムロールの発行を考慮しておくことが必要です。

パイプラインが成功したときにマージさせる仕組み

レビュアーの承認だけではなく、実行されるテストや静的解析(パイプライン)が成功したらマージできるようにしたい。という要望はソースコードの品質を保つために必要です。

この設定は GitLab では Pipelines must succeed という設定を有効化するだけで利用できます。

GitHub でも Require status checks to pass というステータスチェックに関する設定項目を確認して安心していたのですが、実際には次のような設定が必要でした。

  1. ブランチ保護ルールの Require status checks to pass を有効化
  2. 1 を実施したうえでステータスチェックの対象とするジョブを指定

GitHub では設定の有効化だけではなくジョブの指定も必要です。

そのため GitHub Actions のワークフローに各ジョブの状態をチェックするジョブを追加したり、ジョブの状態を監視するワークフローを実装する必要があります。

このチェック用のジョブの実装方法は各社から紹介されていますが、クラウドサインではジョブの状態を監視するワークフローを実装する選択をしました。

詳細はあらためてブログにまとめますが、各ワークフローにジョブを追加する方法はワークフロー内での依存関係がわかりやすくなる反面、変更や実装漏れを引き起こすデメリットを含んでいます。

クラウドサインではジョブの状態を監視するワークフローを作成して次のようにステータスチェックに対応しました。

  • 各リポジトリにプルリクエストの承認(Approve)をトリガーに実行されるワークフロー(check-pr-workflow)を追加
  • check-pr-workflow ワークフローでは、そのプルリクエストで実行された各ワークフローのジョブ成功状況を確認する
  • Organization のブランチ保護ルールでステータスチェックを有効化し、対象として check-pr-workflow のジョブを追加

GitLab では標準提供されていた仕組みだったので、パイプラインの移行とは別に思わぬ時間と対応が発生しました。

移行前のリポジトリの要件を踏まえて移行前にパイプライン設計を見直しておくことをおすすめします。

特定ファイルのプッシュ禁止

こちらは大きな問題にはなりませんでしたが共有しておきます。

GitLab ではプッシュルールというルールでシークレットファイルやファイル名、ファイルサイズに応じたファイルプッシュを禁止する設定があります8

クラウドサインではこのルールに .go.work を記載して GitLab のグループ配下のすべてのリポジトリに適用していました。

プッシュさせないファイルは .gitignore を利用したほうがよさそうですが(実際に設定されているリポジトリもありました)、複数リポジトリに一括で設定を強制するというねらいがあったのかもしれません。

移行タイミングでルールの整理をしている中で発見し GitHub で同様の設定を確認しましたがブランチ保護ルールの項目としては存在していませんでした。

各リポジトリでプリコミットフックを利用したり GitHub ではシークレットスキャン機能で代替は可能ですが、GitLab から移行する際には確認が必要な設定です。

まとめ

GitHub に移行するにあたって設計したこと、はまったことを紹介しました。

今回の作業を通して以下のような課題と学びがありました。

  • Organization は安易に分割せず利用する組織の状態や要件から考慮するのが望ましい
  • プルリクエストのレビュアーにしたチームの削除タイミングはアサイン設定やコードオーナー設定に影響される
  • terraform で GitHub の設定を管理できないものもある
  • GitHub でパイプラインが成功したときにマージさせるにはワークフローを実装する必要がある
  • GitHub では特定ファイルのプッシュ禁止を横断的に設定する方法はない

どの課題も既存の運用で実現したかった目的を見直して GitHub の設計思想とうまくすり合わせていくことが必要でした。

新しいツールの導入や移行においてはどうしても既存運用を変えず、影響を少なくしたくなってしまいますが、製品の思想をふまえて最適な業務フローや運用を見直すいい機会にできました。

GitHub 移行をすすめていくにあたって考慮すべきポイントとして参考になれば幸いです。

最後まで読んでいただきありがとうございます。