GitLabとEclipseのEgitでGitLab Flow運用をやってみよう


はじめに

ブランチ戦略が決まったら結局何をやったら良いの?という疑問を掘り下げてみた。
CUIでやってみるのが一番理解が深まりそうだが、結局、プログラムを書く人がオペレーションするのはIDEなので、IDE上での操作を中心に運用方法を整理してみよう。

GitLabのインストール

今回の目的はちゃんとしたGitLabを作ることではないので、以下の記事を参考にしながら手抜きで作る。GitLabを起動した後のメモリ使用量は2.5GB程度になるので、t2.mediumなEC2を用意しよう。

【Qiita】Docker ComposeでGitLabを起動

ちなみに、テキトーに起動するとGitLab内のリンク動作があやしくなるので、URLだけはちゃんと設定する。本来はEIPとってRoute53でドメイン固定にするか、ALB/NLBあたりに頑張らせるかとかを考えるのだけど、面倒なので、今回はEC2起動時のパブリックDNSを使って起動することにしよう。EC2が再起動すると、ローカルリポジトリが迷子になるので、実運用では絶対にやってはいけない。

EC2のパブリックDNSをEC2自らが取得する方法は↓これ。
【AWS公式】インスタンスメタデータの取得

以下の様に環境変数を定義して、

$ export EXTERNAL_URL=`curl http://169.254.169.254/latest/meta-data/public-hostname`

こんな感じでdocker-compose.ymlに渡してあげる。

docker-compose.yml
version: "3.7"
services:
  gitlab:
    container_name: gitlab
    image: gitlab/gitlab-ce:latest
    restart: always
    volumes:
      - ".conf:/etc/gitlab"
      - ".log:/var/log/gitlab"
      - ".data:/var/opt/gitlab"
    ports:
      - "9001:80"
      - "10022:22"
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url "http://${EXTERNAL_URL}"
        nginx['listen_port'] = 80
        nginx['listen_https'] = false
        gitlab_rails['time_zone'] = 'Asia/Tokyo'

これで

$ docker-compose up

で起動すればGitLabの準備完了だ!

基本的にWebのGUIなので重要なのは80番ポートのポートフォワードだが、SSHで git clone するのであれば、"10022:22" のポートフォワードが必要なので留意しておく。

GitLabの日本語化

英語じゃ嫌よ、と言う人はこの手順で日本語化。

右上のメニューから

「Settings」を選択して

出てきた画面のサイドバーから「Preferences」を選択して

下の方にスクロールしていって、「Localization」セクションの「Language」で日本語を選択して、「Save changes」ボタンを押せば完了!

リポジトリのチェックアウト

リポジトリURIのコピー

GitLabのプロジェクトの画面で、以下のボタンを操作してURIをコピーする。

Gitリポジトリービューの表示

Eclipseのメニューの「ウィンドウ」⇒「ビューの表示」⇒「その他」を選択。

開いたダイアログで、「Git」でフィルタし、「Gitリポジトリー」を選択。

↓のようなビューが開けば成功。好きなところに配置しておく。

リポジトリのチェックアウト

Gitリポジトリービューのメニューアイコンで矢印の点のものを選択し、出てきたメニューから「リポジトリーのクローン」を選択。

開いたダイアログで、URIにコピーしたURIを貼り付け。「ホスト」と「リポジトリー・パスは」オートフィルされる。ポートは80から変更していないなら指定は不要。
認証は、GitLabの認証IDとパスワード。「セキュア・ストアに保管」にチェックを入れていると次回以降はオートフィルされる。

以降はデフォルトのまま「次へ」を選択していけば、以下の様にGitLabのリポジトリがcloneされてローカルで参照可能になる。

プロジェクト・エクスプローラーの設定

上記のままだと操作がしにくいので、プロジェクト・エクスプローラーでも編集可能なように設定をする。

プロジェクト・エクスプローラー上で右クリックをして「インポート」を選択。

開いたダイアログで、「Git」でフィルタして「Gitからプロジェクト」を選択し、「次へ」ボタンを押す。

開いたダイアログで「既存ローカルリポジトリー」を選択して「次へ」ボタンを押す。

開いたダイアログで、前の手順でcloneしたgitのローカルリポジトリを選択して「次へ」ボタンを押す。

開いたダイアログで、「一般的なプロジェクトとしてインポート」して「次へ」ボタンを押す。
もしかして、Mavenプロジェクトだった場合は「新規プロジェクト・ウィザードを使用してインポート」しないといけないかもしれない。

あとは、適当にプロジェクト名をつけて「完了」すれば良い。

プロジェクト・エクスプローラーにGitのローカルリポジトリが入った!

Gitの概念を知っておく

色々といじり倒す前に、Gitの概念をちゃんと知っておかないと痛い目にあう。
以下の記事が分かりやすい。

【Qiita】【Git】リモートからの取得とリモートへの反映で行っていること(fetch,pull,push)

記事中で「リモート追跡ブランチ」と書かれているものは、Eclipseでは「リモート・トラッキング」と表現されている。
以下はGitリポジトリービューでの表示例。リモート・トラッキングにはissue01があるが、ローカルには無い。これは、fetchはしてきたが、checkoutはしていないという状態である。この状態では編集ができない。

ヒストリーで見るとこんな感じ。色と、originが付与されているかどうかで見分けがつく。

逆に、ローカルでCommitしていても、Pushしていなければリモートに反映されないので注意が必要。

この辺りの概念を踏まえて、GitLabとEclipseで行うオペレーションを整理する。

featureブランチにIssueを登録する

GitLab Flowの原則は、masterブランチからfeatureブランチを分岐させて開発を行うことである。
GitLabでは、課題(Issue)をもとにブランチを作成するのが基本らしい。

課題(Issue)の登録

プロジェクトのサイドバーから「課題」を選択する。

開いた課題一覧の画面で「新規課題」のボタンを押す。

適当に課題を起票して「Submit 課題」ボタンを押す。

課題の詳細画面にある「マージリクエストとブランチを作成」の右にある▼のボタンを押して「ブランチ作成」を選択。ブランチ名をfeature/ブランチ名にして、ソースをmasterにしてから「ブランチ作成」ボタンを押す。

リポジトリのブランチ一覧を見ると、さきほど追加したブランチが表示されている。

Eclipseへの反映

当然、これはEclipse側には反映されていないので、Eclipse側のローカルリポジトリとリモート・トラッキングリポジトリに取り込みを行う。

Gitリポジトリービューで、対象のリポジトリを右クリックして表示されたメニューのプルを選択する。

すると、先ほど作ったブランチがPullされた旨のダイアログが表示される。

Gitリポジトリービューを見ると、リモート・トラッキング側に追加したブランチが表示されるようになる。ただし、↑に書いた通り、これはまだローカルブランチまで反映されていない。

リモート・トラッキングにfetchされてきたブランチを右クリックして、表示されたメニューで「ブランチの作成」を選択する。これ、めちゃくちゃ分かりにくいけど、「ローカルブランチの作成」を意味するらしい……

次に表示されるダイアログは、特に何もいじらず「完了」ボタンを押す。

すると、ローカルリポジトリにもPullしてきたリモート・トラッキングと同じ内容になる。

featureブランチを更新する

今回の変更の前提

今回の修正は以下のような内容とする。
これを、masterに書き戻すところまでやってみよう。

test.sh(変更前)
#!/bin/sh

echo "master"
test.sh(変更後)
#!/bin/sh

echo "master"

echo "feature/issue01"

更新したらまずはCommitする

上記の更新をしたら、まずはCommitをしてみよう。

プロジェクト・エクスプローラーの対象リポジトリのプロジェクトを右クリックして、表示されたメニューで「チーム」⇒「コミット」を選択する。

Gitステージングのビューが開くので、Commitしようとしているブランチが正しいか確認し、「ステージされた変更」に対象ファイルが入っていることを確認したら「コミット」ボタンを押す。入っていなかったら「ステージされていない変更」から「ステージされた変更」にドラッグ&ドロップする。
「コミット」ボタンは、その左の「コミット及びプッシュ」ボタンでも良いが、今回は状態も含めて確認するために一旦Commitのみにする。
あと、例では書き忘れたらコミット・メッセージが入っていないとエラーになるので注意。

こうすると、Gitリポジトリービューのブランチの表示に「↑1」という文字が現れる。
これは、まだリモートリポジトリにPushしていないものがあるということを意味する。

次は、Gitリポジトリービューで対象のリポジトリを右クリックして「アップストリームへプッシュ」をする。

すると、プッシュ結果と、「マージリクエストするならここに来い」というリンクが表示される。
このリンクを踏むとEclipse内でブラウザが上がってうざいので、通常使っているブラウザにコピー&ペーストしよう。

リモートリポジトリ側も確認してみよう。ちゃんと更新が反映されている!

featureブランチをmasterブランチにマージする

さて、課題からブランチを作ったのだから課題からマージができるのだろうと思うが、課題からマージリクエストとしようとするとなぜかブランチがもう一本できてしまうので、手動でマージリクエストをする。

プロジェクト画面のサイドバーから「マージリクエスト」を選択し、表示されたマージリクエストの一覧画面で「New Merge Request」ボタンを押す。

Source Branchの「ソースブランチを選択」のプルダウンから対象のブランチ(今回はfeature/issue01)を選択し、Target Branchは今回はそのままで問題ないはず。もし、masterが選択されていないようであれば、masterにして、「Compare branches and continue」のボタンを押す。

マージリクエストの詳細はテキトーに入れて、「Submitマージリクエスト」のボタンを押す。
ソースブランチは消しちゃっても問題ないが、今回は一応消さないようにチェックを外しておく。

マージリクエストが送られたら、マージ可能なユーザが詳細画面に行き「Merge」ボタンを押す。

マージ完了!普通はここからCI/CDが起動するから、実運用時はちゃんとコードレビューが終わってからマージするように。

グラフを確認しても、ちゃんとfeature/issue01がmasterに取り込まれたグラフになっていることが分かる。

なお、マージ前のレビューはWebからも行える。
詳細画面の「Web IDEで開く」ボタンを押す。

こんな感じでdiff確認のようなものができる。
小さいソースでやる分には良いけど、差分が多かったりしたらEclipseとかの方がレビューしやすいのではないかな、と思う。

なお、マージ後のローカルリポジトリへの反映は、最初と同じようにPullすれば良い。

ここから後は

基本は同じ。pre-productionブランチなり、productionブランチなりにマージリクエストをすればよい。ブランチに合わせてCI/CDパイプラインを作っておけば、夢の「起動環境ごとの自動化」も実現可能。夢が広がる。

ちなみに、GUIは乏しいが、この記事で書いたことはCodeCommitでも行える。CodeCommitの場合、マージリクエストではなくプルリクエストという名称だが、中身は変わらない。たぶんGitHubも同じだと思う(GitHubは使ったことがない)。

masterが次期開発で汚れているときのhotfixのcherry-pickはどうやるべきなの?といった課題は出てくるので、追々検証して追記してみようと思う。