見出し画像

デプロイ失敗から Git のタグが2種類あることを知った話


はじめに

開発エンジニアのくっしーと申します。猫が好きです。
クラウド製品の開発チームで、インフラ構築や CI/CD に関わっています。

この記事では Git タグの種類と仕様について、
デプロイ時の失敗談を交えながら紹介します。
この記事の中に、少しでもお役に立てる内容があれば幸いです。

この記事で伝えたい情報(忙しい人向け)

  • Git のタグは下記の2種類がある。

    • lightweight タグ:コミットへの参照。それ自体は SHA を持たない。

    • annotated タグ:データオブジェクト。独自の SHA を持つ。

  • 接尾辞 ^{} で非タグオブジェクト(コミット)の SHA を取得できる。

注意

本筋に絡まない箇所はかなり省略・簡略化しています。

チームでの Git とデプロイ運用について

私のチームでは製品のコード管理に Git を利用しており、
ブランチは開発用とデプロイ用に分け、下図のように運用しています。

v1.0.0 デプロイ用のコード fix 作業
v1.0.1 デプロイ用のコード fix 作業

v1.0.0 タグの追加時は下記の git tag コマンドを利用しました。

git tag v1.0.0 bz6sebw

デプロイは下記の2つのフェイズに分けています。
(時間のかかるビルドを事前に対応しておくための施策です。)

  1. ビルド処理:コードをビルドして成果物置き場にアップロード

  2. デプロイ処理:ビルド成果物を稼働用の環境にアップロード

下図は v1.0.0 デプロイの処理フローです。滞りなく完了しました。

v1.0.0 デプロイの処理フロー

v1.0.1 デプロイでは Git の GUI クライアントの画面からタグを付けました。
そして、後続のデプロイ処理は失敗してしまいました。

デプロイ処理が失敗した経緯

v1.0.1 のデプロイ処理はビルド成果物の検索部分で失敗していました。
調査の結果、失敗の経緯は以下の通りでした。

  • v1.0.1 タグはそれ自体に SHA が付いていた(≠ コミットの SHA)。

  • ビルド処理ではコミットの SHA を取得できており、
    ビルド成果物にもコミットの SHA が識別用メタデータとして付いた。

  • デプロイ処理では v1.0.1 タグ自体の SHA を取得してしまい、
    ビルド成果物が見つからず失敗した。

下図は v1.0.1 デプロイの処理フローです。

v1.0.1 デプロイの処理フロー(デプロイ処理のビルド成果物検索が失敗)

ここで改めて Git のドキュメント(下記リンク参照)を確認したところ、
Git タグには下記の2種類があることがわかりました。

  • lightweight タグ:コミットへの参照。それ自体は SHA を持たない。

  • annotated タグ:データオブジェクト。独自の SHA を持つ。

ドキュメントの記述通り、下記のように git tag コマンドをオプション無しで実行した場合は  lightweight になりました。

git tag v1.0.0 bz6sebw

また、v1.0.1 のタグ付けに利用した Git GUI クライアントでは、
作成したタグは annotated になっていました。(lightweight では作成不可)

解決策

接尾辞 ^{} を利用することで、非タグオブジェクトの SHA を取得できます。

<rev>^{}, e.g. v0.99.8^{}

A suffix ^ followed by an empty brace pair means the object could be a tag, and dereference the tag recursively until a non-tag object is found.

引用元:https://git-scm.com/docs/gitrevisions#Documentation/gitrevisions.txt-emltrevgtemegemv0998em

今回は下記のように ^{} を追加することで、
意図通りコミットの SHA を取得することができました。

git rev-parse HEAD^{}
git rev-parse FETCH_HEAD^{}

明示的にコミットの SHA を取得するという意味合いを含めて、
HEAD の利用箇所(ビルド処理、今回問題無し)にも追加しています。

また、現在はデプロイ用の lightweight タグ付け処理をスクリプト化して、
基本的にそちらを利用していただく運用としています。
作業担当者の環境依存による操作結果のズレを避けるためです。
(対象のリポジトリが多いため、時短の目的もあります。)

あとがき

デプロイ失敗を通して、Git タグの種類と仕様に関する知見を得られました。
タグ付け方法によってタグの種類が異なっていたこと、
特定の場合にだけタグの種類に起因する挙動変化があったことは、
この知見が無いと回避できない落とし穴のように思えました。

この記事をお読みになった方が落とし穴を飛び越せれば、
もしくは早期に脱出できれば幸いです。
最後までお読みいただきありがとうございました。

いいなと思ったら応援しよう!