Git TagとSemVerによるバージョン管理:カオスな状態からプロフェッショナルな標準フローへ

Git tutorial - IT technology blog
Git tutorial - IT technology blog

金曜日の午後、クライアントへの製品リリースの準備。かつての私たちのチームは、よく混乱に陥っていました。開発者Aが「このバージョンはv1.2だ」と言えば、開発者Bは「バグを直したばかりだからv1.2.1のはずだ」と反論します。その結果、サーバー上には source_code_final.zipsource_code_final_v2.zip、さらには source_code_FIX_CUOI_CUNG.zip(最終修正版)といった圧縮ファイルが山積みになりました。それらを見ても、どれが最も安定して動作するバージョンなのか誰にも分かりませんでした。

Git TagSemantic Versioning (SemVer) を導入したことで、すべてが変わりました。このプロセスは混乱を整理し、デプロイ作業をたった一度のpushコマンドへと変えてくれました。私とチームメイトの生活は、以前よりもずっと楽になりました。

バージョン管理における「典型的」な間違い

現在でも多くのチームが、リリースの節目を記録するために以下の3つの手動プロセスを行っています:

  1. フォルダのコピー&ペースト: ソースコードを日付ごとに圧縮する方法です。これは非常にストレージを消費します。5人が同じことをすれば、すぐにコントロールを失うでしょう。
  2. リリースブランチの乱用: リリースごとに release-v1.0 のようなブランチを作成する方法です。Gitのグラフは絡まった電線のようになり、管理が非常に困難になります。
  3. 手動のメモ: CHANGELOGファイルにのみバージョンを記述する方法です。この方法はコンピューターが理解できないため、CI/CDプロセスを自動化することができません。

以前、8人のチームでプロジェクトを行っていた際、ブランチを乱用したことでコードのマージが地獄のようになりました。誰も削除する勇気がなく、1年も放置されたブランチもありました。その時、Git Tagが必須のソリューションであると確信したのです。

Git Tagとブランチの違いは何でしょうか?

Gitを学び始めたばかりの人は、よくこの2つの概念を混同します。こう想像してみてください。ブランチ(Branch)は「建設中の道路」のようなもので、常に変化し、前方へと進んでいきます。一方、タグ(Tag)は、その道路上にある「固定されたキロポスト(距離標)」のようなものです。あるコミットにタグを付けると、その後にどれだけコードを追加しても、タグは永遠にその地点に留まります。

なぜタグを使うべきなのか?

  • 不変性 (Immutable): タグ v1.0.0 は常にその特定のコミットを指します。誰かが誤って上書きコミットをすることはありません。
  • 超軽量: タグは実質的に小さなポインタに過ぎず、リポジトリを重くすることはありません。
  • 高速なアクセス: バグ修正のために、3秒で旧バージョンのコード状態に戻ることができます。

実践的なSemantic Versioning (SemVer) の適用

タグ名を v1v2 のように適当に付けてはいけません。MAJOR.MINOR.PATCH(例:1.2.3)という標準を使いましょう。これにより、誰もが変更の規模を一目で理解できるようになります:

  • MAJOR(最初の数字): 互換性を損なう大きな変更(ブレーキングチェンジ)があった場合に増やします。例:APIの構造を全面的に変更し、旧アプリが呼び出せなくなった場合など。
  • MINOR(真ん中の数字): 既存のコードと互換性を保ちつつ、新機能を追加した場合に増やします。例:「チャットで画像を送る」ボタンを追加した場合など。
  • PATCH(最後の数字): バグ修正(Bug fixes)のみの場合に増やします。機能追加もなく、既存の動作も壊しません。

このルールを導入してから、テストチームの効率が格段に上がりました。PATCHの数字だけが増えたなら、彼らはクイックテストを行うだけで済みます。MAJORが増えたなら、システム全体の総点検が必要だと判断できるからです。

Git Tagの実装:覚えておくべきコマンド

タグには2つの種類があります。Lightweight(単なる名前)と Annotated(作成者情報や日付を含む)です。リリースの際は、よりプロフェッショナルで情報量が多い Annotated tag を優先的に使用することを推奨します。

1. 新しいタグの作成

表示バグを修正し、バージョン v1.0.1 に上げたい場合を想定します:

# 説明付きのAnnotated Tagを作成
git tag -a v1.0.1 -m "Safariでの表示バグ修正およびAPIエンドポイントの更新"

# 既存のタグ一覧を表示
git tag

2. タグをサーバーにプッシュする

注意:通常の git push コマンドではタグは GitHub/GitLab に送信されません。専用のコマンドを使う必要があります:

# 特定のタグをプッシュ
git push origin v1.0.1

# すべてのタグをプッシュ(取り扱いに注意)
git push origin --tags

3. 間違えてタグを付けた時の対処法

誤ってタグを付けてしまっても心配いりません。以下の手順で削除して再作成できます:

# ローカルのタグを削除
git tag -d v1.0.1

# サーバー上のタグを削除
git push --delete origin v1.0.1

Git TagによるCI/CDの自動化

これが作業時間を大幅に節約するための鍵です。サーバーにログインして手動でコマンドを打つ代わりに、システムが自動でビルドするように設定します。以下は GitHub Actions の例です:

name: Deploy Production
on:
  push:
    tags:
      - 'v*' # 'v'で始まるタグがプッシュされた時にスクリプトを実行

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Build and Push Docker
        run: |
          docker build -t my-app:${{ github.ref_name }} .
          docker push my-app:${{ github.ref_name }}

この設定により、タグ v1.1.0 をプッシュするたびに、システムが自動的にパッケージングして本番環境へデプロイします。プログレスバーを眺めて待つ代わりに、ゆっくりとコーヒーを飲む時間が生まれます。

現場からのアドバイス

長年、大規模なプロジェクトを管理してきた経験から、3つの黄金律を導き出しました:

  • タグ上で直接コードを修正しない: もし v1.0.0 にバグが見つかったら、hotfix ブランチを作成して修正し、その後に v1.0.1 としてタグを打ち直しましょう。
  • 常に接頭辞 ‘v’ を付ける: 1.0.0 ではなく v1.0.0 と命名することで、自動化スクリプトがより正確に動作するようになります。
  • 意味のあるメッセージを書く: -m "Update" だけで済ませないでください。主な変更点を要約しておくことで、後にクライアント向けのChangelogを自動生成する際に役立ちます。

Git TagとSemVerは単なる技術ではなく、管理の考え方です。すべてが明確になれば、開発者、テスター、そしてクライアント間のコミュニケーションはより円滑になります。もしあなたのチームがいまだにzipファイルで苦労しているなら、今日からTagへの移行を試してみてください。

Share: