ベストプラクティス GitLab

ベストプラクティス シリーズ。

俺の GitLab 的な?

※ かつての記事のリライトのため、現状の GitLab の UI とはズレがある可能性があります。

はじめに

個人で GitHub 使ってたり、業務で GitLab 使っている中で、

うまくいった事・うまくいかなかった事 いずれもあるわけですが、これら経験を踏まえて、

  • こうすると上手くいく ( かもよ )
  • こうすると失敗する ( かもよ )
  • この機能使うと便利 ( かもよ )

的な Tips をまとめてみます。

※ 俺の 〇〇 的な Tips なので、適当なカスタマイズやプロジェクト毎の最適化推奨。
※ 職場等では殆ど利用されていないと思われる系機能に関しても記す。活用する事でプロジェクトの質を上げる事が可能 ( かもよ )。


Git

基本操作は自分で覚えましょう。

GitLab を利用する場合、Git は利用するはず。
※ Issue管理は使わない場合はありそう ( タスク管理は Redmine だけど、ソース管理は GitLab という管理ツールミックス状態 )

Git の使い方が怪しい場合は、以下のような方法を利用して基本操作はマスターしましょう。

  • 自分で学ぶ / 調べる ( 書籍 / ネット )
  • 個人で github 等を使って慣れる
  • 詳しい人に聞く
    企業によっては、全くわかってない状況の方に一から教えてくれる人は少ないかもしれない。

操作に自信がない場合に、実運用しているブランチを適当に触って壊すとか、企業/プロジェクトによっては追放されるかもな事象です。テスト用のリポジトリ用意して練習しましょう。
練習もせず本番環境壊したとかなると、無能扱いされても仕方ありません。

GitLab + GitLab Runner 込みで docker-compose で環境構築する事も可能なので、色々弄ってみたい向きには docker で環境構築するのをお勧めします。

※ 昔 Git も SVN も使い方怪しいって人見た事あるけど、本当に開発者だったのか? ( 経歴詐称じゃないよね? ) と冗談交じりで疑われていた。


権限管理

プロジェクトにメンバーを追加する場合には適切なロールを割り当てるようにしましょう。

ベストプラクティス cron に書いた

※ GitLab でも push 可能な権限を制限できるはず。MR必須の運用にするならば、指定ブランチへの直pushを制限する等 ( スローガンではなく ) ツールで制約を。

といった対応をする場合、

特定ブランチへの merge/push は 特定ロール(以上)のみ許可するといった設定を行う必要があります。
※ プロジェクトの [Settings]>[Repository]>[Protected branches] から行える。

しかし、協力会社メンバー含め、全員が Maintainer 権限といった状態だと、上記設定を行っても適切な制限は行えない事になります。

適切な機能制限が行えない点を挙げましたが、そもそもセキュリティ上問題であり、

Maintainer 権限を持つメンバーは社員のみ ( できれば適切な設定が行える一部のメンバー ) 等に制限し、通常の開発者は Developer 権限に設定するのが適切です。

※ 監査上も不要な権限を意味なく割り当てるのはNG ( なはず )

Redmine 等にも言える事ですが、何でこのメンバーにこのロール割り当ててんの?な権限割り当てザル状態は結構企業でも見かけた 気がします。
何となく、便利だからといった理由で権限付与するのはNGでしょう。もしやっちゃってる場合には修正しましょう。


ブランチ戦略

既に稼働中なプロジェクトに関しては、プロジェクト毎のブランチ戦略があると思います。
既に決まった運用方法があり、上手く行っているのであればそれを使いましょう。

一例として過去に採用したブランチ戦略を示します。

gitブランチ

※ gitflowに似てるので使った事がある方であれば理解は容易いと思います。

  • master ( または main )
    リリース用。運用環境にデプロイされる。
    master は直接編集しない。
    master に マージ した場合は tag を付けます。
  • develop
    開発のメインブランチ。master から作成。
  • feature
    各 issue に対応したブランチ。
    develop の最新から作成。
    ブランチ名は feature/issueNNN ( NNNはissue番号 ) とした。
    issue 毎に個別のブランチを作成し、実装完了後は develop にマージされる。
    ※ 当初個々人の開発用ブランチを作成する場合に機能単位ではなくメンバー単位で作成という話もあった ( メンバーが以前そういう方法を採っていたとの事 ) が、この場合、( フロントとサーバサイドで開発者が異なる場合等 ) 一つの機能変更が複数ブランチに跨る可能性もありうる事から、この方法は止めた。
  • hotfix
    master で致命的なバグが発生した場合に利用。
    ( 致命的なバグが発生した ) master から作成。
    ブランチ名は hotfix/issueNNN ( NNNはissue番号 )。 バグ改修後、master にマージされる。

マージする際にはMRを作成し、レビュー後にマージする。

※ プロジェクトのメンバー構成、MRの内容によってはセルフレビューを許可した。
※ 上記ルールはチケット駆動開発を手法として取り入れている場合 ( 必ず issue を作成しているはずなので ) 機能し易い。チケット駆動でない場合にはどうするか?チケット駆動開発にしてしまえ!( お勧め )。

※ ちなみに、以前 feature/#NNN 形式でブランチ名を採用した事があったが、ブランチ名に # が含まれると GitLab へのリンクで問題が発生する ( Slack 通知からリンクされない ) ためこの形式は廃止になりました。ブランチ名に # を含めるのはやめた方が良い。


ブランチ作成

新たに機能を追加したりバグ修正を行う場合には プロジェクトで策定/採用した ブランチ戦略 に従ってブランチ作成を行います。

ブランチの作成は GitLab 上でも行えますが、以下の副作用があります。

  • GitLab 上で New Branch した場合、作成したブランチが Commit/Push されてしまうため CI/CD ( Pipeline ) が実行されてしまう。
    gitlab-ci.yml の条件指定で GitLab 上から New Branch されたかどうかを判別する方法があればよいが、現状判別は出来ないっぽいため、New Branch しただけで CI/CD が実行されてしまう。
    これは以下の点で都合が悪い
    • 不要な CI/CD が走る。色々 ( 計算機リソース、時間、リモートリポジトリ上のストレージ等 ) 無駄。
    • 機能追加やバグFIX等が Push された場合のみ CI/CD が走る方が、CI/CD(Pipeline) で問題が発生した場合に、問題を発見しやすい。ブランチ作成の度 Pipeline が走ると Pipeline の確認がきちんとされなくなる可能性がある。

上記の点を踏まえ、ブランチ作成に関しては特別な理由がない限り以下の手順で行うのをお勧めします。

  1. 作成元のブランチからローカルでブランチを作成する。
  2. 作成したローカルブランチを利用して何らかの変更 ( 機能追加やバグ修正 ) を行い、ローカルでビルド、動作確認を行う。
  3. ローカルで Commit する。
  4. リモート ( GitLab ) に Push する。
    新規に作成したブランチに関しては、この時点で初めてリモートにブランチ作成され、CI/CD が実行される。

上記手順を採用する利点は以下。

  • 実際の変更 ( ローカル Commit ) が反映 ( Push ) されるまでは、リモートにブランチが生成されない。
    ブランチ作成したけど、結局は Commit/Push されない場合もあり得るが、この場合に GitLab リソースが無駄にならない。
  • 余計なCI/CDが走らない。
    GitLab で New Branch した場合、上述の通り CI/CD が走るが、これはブランチ生成元のブランチ( develop 等 ) の最終コミットの状態を再度 CI/CD している事になる。既に CI/CD 確認済みの Commit/Push に対し CI/CD を再実行するのは無駄である。
  • Pipelineの履歴が汚れない。
    上と関連するが、無駄な Pipeline が走ると Pipeline の履歴に本来不要な実行履歴が残る。CI/CD で何らかの問題が発生して、過去履歴を調査する必要が発生した場合に、この手の履歴が多いと調査コストが増える。

GitLab上から New Branch せずとも、VSCode 等の開発環境でブランチ作成は行える。上記手順でブランチ作成を行うようにしましょう。

※ 殆どのメンバーは上記手順でブランチ作成していたが、一部メンバーがGitLab上で New Branch した際に Pipeline 実行される状態が発生。なんだ?この Pipeline となったため、上記内容でかつて文書化/展開した。
※ 「うちのプロジェクトでは CI 使ってないからいいや」と言う方もいるかもしれないが、今後 CI を導入する可能性は常にある。一度慣れてしまった方法を直すのは ( メンバーにもよるが ) コストが高い場合がある。 より問題が少ない方法を採用する方がよいと思う。


コミット

コミットする場合には コミットコメントを適切に書きましょう。

GitLab でチケット駆動開発を行っている場合、コミットは先に起票しているチケット ( issue ) に対応する作業なので、コミットコメントには issue id を記載するようにします。
これによって issue と コミットが自動的に関連付けされます ( 相互リンクが張られる )。

issue idを記載する場合 #nnn 形式 ( nnn は issue id (10進数値) ) で記載する。
場所はコミットコメントの最初に書くのが判りやすく、書き忘れにくい。
※ # nnn と # と nnn の間にスペースを入れてしまってリンクが張られていないのも見た事があるので、間にスペースは入れないように。

※ チケット自体は Redmine で管理している場合にも、Redmine のリポジトリ機能を利用し、Git リポジトリと連携する事で チケットとの連携を行う事も可能である ( 設定は別途必要 ) 。


マージリクエスト

マージを行う場合には必ずマージリクエスト ( MR ) を作成する。
( MR 無しでのマージは行わない )

  1. GitLab のメニューから Merge requests をクリックする。
  2. MR一覧画面が表示されるので New merge request ボタンをクリックする。
  3. Source / Target の二つのブランチ入力欄が表示されるので、それぞれのブランチを設定します。
    通常の機能開発を行っている場合には、以下のようになります。(hotfixの場合やmasterへのマージの場合にはこれとは異なります。不安な場合は識者に相談して下さい)
  • Source branch にマージするブランチ (feature/issueNNN)
  • Target branch にマージ先のブランチ (develop)
  1. Compare branches and continue をクリックする。
  2. New merge request 画面に遷移するので、先ずは変更内容を確認します。
    画面を下にスクロールすると、Commits, Pipelines, Changes タブが表示されているので、以下が正しいかを確認して下さい。もし問題があった場合には一旦MR作成は止め、ブランチ作成手順やファイル編集に問題がないか解決してから再度MRを作成するようにしましょう。
  • Commits
    MRに含まれるコミット内容。自分が行おうとしているMRと異なる内容のコミットが含まれる場合は何か問題があると思ってください。
  • Changes
    MR前後のファイル差分が含まれます。差分(変更)内容が正しいかを確認して下さい。自分が行っていない変更や、誤った変更内容が含まれた場合には何か問題があると思ってください。
  1. Commits, Changes に問題が無い場合には、以下MR内容を適宜設定して下さい。
  • Title
    MR のタイトルを適宜設定して下さい。
  • Description
    MR に含まれる変更の概要を書いておくと良いでしょう。
  • Reviewer
    誰かにMRをレビューして欲しい場合にはそのメンバーをレビュアーに設定して下さい。GitLabで設定しただけだと相手が気づかない場合もあるため、Slackなどでレビュー願いも通知するのがお勧めです。
  1. Create merge request をクリックします。
  2. レビューを依頼されたメンバーはMRの内容に問題がないか確認し、必要であればMRにコメントして下さい。
  3. MR作成者はレビュアーのコメントに対して説明やコード修正等を行い問題を解消して下さい。
  4. 6 -> 7 のプロセスを繰り返し問題がなくなったら、レビュワーは MR の Approve ボタンをクリックします。
  5. MR作成者 ( あるいは、MRをアサインされたメンバー ) は Approved された事を確認して、Merge ボタンをクリックします。
    デフォルトでは Delete source branch にチェックが入っています。マージ後もソースブランチ(feature/issueNNN等)を削除したくない ( その後もそのブランチで作業する ) 場合にはチェックを外してから Merge ボタンを押しましょう。

企業などでも時々発生する

  • 一人で作業した。
  • チェック体制がなかった。機能していなかった。
  • レビューを行っていなかった。

といった問題を防止するためにも有効です。


issue作成

issue を作成する場合、適切な issue を作成する。

ベストプラクティス Redmine にも似たような事を書いたのですが、以下のような点に気をつけるとよいでしょう。

  • 適切な粒度で作成
  • 適切なタイトルを付ける
  • 必要十分な説明 ( 概要 ) もきちんと書く
  • 複数のタスクを書かない
  • 終了条件が明確になるようにする
  • 担当を割り振る
  • 期間を設定する ( 仮の期間でも良い )
  • バグの場合、再現手順、環境(利用ブラウザ等)、バージョン等必要な情報を記載する
    ※ 且て某外資系で働いてた時に、BTS(bug tracking system) にこの手の情報書かずに登録して「クソなissue書いてんじゃねー。とっとと書き直せ」って返されてるの見た事あるw。

ここからはあまり使われていない系

ラベル

issue にはラベルを付ける事ができる。ラベルは Project 単位で設定可能。利用する事で issue の視認性が向上する。
※ board (カンバン。後述) やissue 一覧表示時に特に有用。
※ 背景色も個別設定可能なので、適切に設定して運用していれば、ラベル色からどの系統の情報かも判るようになってくる。

プロジェクトの左メニュー一番上のアイコン[Project information]>[Labels] から設定できる。

私は以下のようなラベルを設定している。

カンバン用

  • Doing
    実行中。色は #5CB85C
  • To Do
    実行予定。色は #F0AD4E

Close 系

Closed issue の分類に利用。色は #808080

  • Close: Fixed
    修正/対応した
  • Close: Wontfix
    対応しない
  • Close: Duplicate
    重複している
  • Close: Invalid
    誤っている
  • Close: Postponed
    延期

Priority 系

優先度

  • Priority: Critical
  • Priority: High
  • Priority: Middle
  • Priority: Low

優先度系は順位付け可能なのでラベル背景色をグラデーションになるように設定している。
Critical から順に #ff0000, #ff4400, #ff8800, #ffbb00

Type 系

issue 分類。色は #6699dd

  • Type: Bug
    バグ
  • Type: Documentation
    文書/資料作成
  • Type: Feature
    機能追加/拡張
  • Type: Refactoring
    リファクタリング
  • Type: Review
    レビュー
  • Type: Test

issue 一覧や カンバンがカラフルになるだけで、何となく気分が上がる ( ※個人の感想です ) し、視認性が高まるという点においてデメリットは少ないと思われる。

尚、ラベル設定した際に、issue には必ずラベルを付ける必要があると受け取ったメンバーがいましたが、そうではありません。

ラベルの種類によっては付与を必須にしてもよいものもあるかとは思いますが、優先度等 issue 作成者が直ぐに設定可能とは言えないでしょう。
一旦ラベルが付与されてしまう=既に設定済み・設定したラベルで問題が無いと受け取られる可能性もあるため、確実に設定可能なもの以外については付与せずに打合せの中等で設定する方がよいと思います。

※ Scoped labels という機能があって、これが利用できればと考えていたが、非PREMIUM版では利用できなかった。
この機能はラベル名に :: を入れる事で key::value 形式のラベルを設定できるとの事。Priority や Severity といったラベル付けをする場合にはこの形式が使えた方が便利。

Reference


マイルストーン

Issues > Milestones から設定/利用できます。

私は仕事での実プロジェクトでもマイルストーンを利用して、各リリースで行う内容(予定)を記載していますが、私の周りではマイルストーンを設定しているプロジェクトは少ないように思われます。
請負開発で作ったら終わりといった場合でない限り、現在、あるいは、これから行う(次リリース)までの開発で何を行うか? ( 主目的や主な追加機能 ) を記しておくとプロジェクトの見通しがよくなります。
個々の issue までマイルストーンに記載する必要はありませんが、issue 自体にマイルストーンが設定可能なので、

  • その issue がどのマイルストーンで実施されたのか?
  • あるリリース ( Milestone ) で対応された issue には何があるのか?

といった振り返りに利用する事も可能ですし、

  • issue としては上がっているが、そのタスクは現マイルストーンでは行わない事を示す (要望としては把握、ただし、実装未定扱いにする) 用途にも利用できます。

Reference


カンバン

Issues > Boards から利用できます。

GitLab 上では Boards となっていますが、カンバンの方が馴染みが深い方が多いのではないかと思われます。
GitLab上ではデフォルトでは以下の状態が用意されています。

  • Open
    issue が作成されたときの状態
  • Closed
    作業が完了したら Closed に移動
  • 上記以外にカンバン上の状態を表すラベルを設定可能。

個人的には Redmine でガントチャートベースでタスクを回す事が多かったのですが、幾つかのプロジェクトでは取引先のマネージャの希望等からカンバンベースでタスク管理をしたこともあります ( Redmine の場合、Agileプラグインを利用 )。
カンバン上で関係者でタスクを確認し、それぞれのタスクの状態を変更してゆくという事を定期的に行っていました。

  • タスクの大まかな状態を全員で確認できる。
  • 重要なタスクは順番を入れ替える(上に持ってくる)といったルールで運用する事で、タスクの重要度/優先度も可視化できる
  • 担当者も表示されているので、誰がどの程度のタスクを抱えているかも把握しやすい。

プロジェクトの形態や規模、参加メンバーの属性等によって向き/不向きもあるため、必ず利用すべきといったものではありませんが、利用した事がないのであれば試してみる価値はあるでしょう。

  • 「小規模でガントチャート作るまでは...」といった場合
  • アジャイル的な開発手法を採用している場合

に親和性が高いと思います。

Reference

参考


時間管理

Time tracking と Due dates を利用する事でタスクの時間管理やスケジュール管理をする事が可能です。

プロジェクトを進めるうえで各タスク ( issue ) の時間管理は重要です。 タイムトラッキングするまでもなく、順調に進んでいるプロジェクトの場合にはガチガチな時間管理をする必要はないと個人的には思ってますが、

  • 進捗が芳しくない
  • タスクにどの程度の工数がかかるか把握できていない

といった状況が続いている場合、先ずは見える化する事からはじめるのが良いでしょう。
可視化されていない問題は放置される/改善されない事が殆どなので、可視化するのがファーストステップです。

GitLab の Time tracking と Due dates を利用する事でタスクの時間管理やスケジュール管理をする事が可能です。

各 issue について、

  • どの程度かかりそうか
    見積もり /estimate
  • 実際にかかった工数 /spend
  • いつまでに出来そうか Due date

を記録する事で見える化が可能です。

見積もり

issue のコメントで /estimate 1w 2d 5h といった風に入力する事で見積もり工数を入力できます。

  • コマンドを途中まで入力するとヒントが表示されるので参考にしましょう。
  • 1w == 7d ではなく 1w = 5d なのでその点は注意しましょう。
  • 当然 1d = 24h でもありませんが、これに関して間違う方はいないと思われ

見積もりを取り消す場合は remove_estimate で。

変更する場合には /estimate xxx を再入力します。以前の値に加算されるのではなく、上書きされるようなのでこちらも注意しましょう。

実工数

issue コメントで /spend xxx で入力します。時間のフォーマットは estimate と同じです。

※ /spend に関しては入力した値は加算されます ( /estimate とは異なるようです )。

estimate と spend 両方入力すると、issue 右側の Time tracking 欄に進捗がバー表示されるようになります。

期限

期限は issue の右側にある Due date 欄で入力します。

issue コメントで /due xxx で設定する事も可能ですが、xxx 部分の書式は in 2 days とか this Friday, December 31st とか例に出てきて日本人的には馴染まない可能性が高いので、Due date 欄でカレンダー設定するのがお勧めです。

期限を過ぎている issue は表示色が変わって表示されたり、To-Do List (GitLab右上にあるアイコンからアクセスできます) での表記が変わります。

Reference


ガントチャート

Premium、Ultimate ならば Roadmap 機能でできるらしい。 https://github.com/lamact/react-issue-ganttchart を利用して Due date を元にしたガントチャート表示は行った事があります。CE などでガントチャートを利用してみたい場合には試してみても良いでしょう。
※ GitLab 自体の機能ではありません。


MRのDraft機能(旧WIP)

MRの Title 入力欄の下に Start the title with Draft: to prevent a merge request that is a work in progress from being merged before it's ready. という記載があり、Start the title with Draft: リンクをクリックすると、この MR がドラフト状態だと示す事ができます。
これは且て WIP (Work In Progress) と呼ばれていた機能で、Draft状態で作成された MR はマージボタンが押せない状態で作成されます。

作業途中でまだ完成していないがレビューやコメントが欲しいといった(ドラフト)状態にある場合に、MR の Draft 機能を利用するとよいでしょう。

GitLab上でドキュメントの管理をしている場合で、メンバーのコメントやチェックが欲しいといった場合にも活用できると思います。

Draft 状態で作成した MR もレビュー内容を反映した後に Mark as ready ボタンで非 Draft 状態に変更する事も可能です。( 再度 Draft 状態に戻す事も可能 )

Reference


それでも発生した問題

上記のようなルールを策定しても、問題が発生する事はあります。
具体的例を示します。

何する issue ?

タイトルだけや、概要説明が不十分な issue が作られ、何するの?状態になった事がありました。

流れを書くと、以下のような感じ

  1. メンバーB:「〇〇に関して××の問題があるので、対応すべき」
  2. メンバーA:「対応します」
  3. メンバーB:「issue 書いてください」
  4. メンバーA:「了解」
  5. メンバーA:issue 作成 (タイトルのみ)
    タイトル内容も 〇〇を決める 等、何の? となるようなタイトル。

その後、暫く issue 対応はされずに放置される ( 他に優先するタスクがある等の理由 )。

  1. メンバーA:「決める必要のあるものがない」といった理由で issue クローズ。
  2. メンバーB:問題は解決していない旨コメント。
  3. メンバーA:もう覚えていない旨告白。

issue に必要十分な内容が記載されていれば、避けられる問題です。

※ 同様の問題は繰り返し引き起こされる場合があります ( 経験的に )。
※ 繰り返し発生する場合には、メンバー自身に対応策を策定してもらうのがベストですが、無理な場合には issueのテンプレートを用意 しましょう。

ブランチ名が命名規約に従っていない

命名ルールに従いましょう。
新規ブランチを GitLab に push する際には、

  • ブランチ名が適切か?
  • 既存のブランチがどうなっているのか?

といった点を確認するのをお勧めします。

ブランチの作成手順に問題 ( 多分 )

かつて、MR に既にマージ済みの変更が含まれていた問題がありました。
feature ブランチ作成時に最新の develop からではなく、( おそらく ) ローカルの develop を最新状態にせずにブランチを作成したのではないかと思われます。
仮に誤ってそのまま MR に進んだとしても、MR 作成前に差分を確認していれば ( GitLab 上で確認できる )、自分が当該の feature ブランチで行っていない変更が含まれるために気づくはずです。
この問題が発生した理由としては以下の二つが含まれます。

  • ブランチ作成ルールがダメ
  • MR時にレビューしていない
    レビュアーがいない場合でも自分でMRに含まれる差分が適切かどうかの確認は必要です。セルフレビューの場合、自分自身できちんとチェックしましょう。

まとめ

権限まわりザルな設定するのはホント止めた方がよいと思う。