Semantic Versioning形式のGitタグをインクリメントしてpushするスクリプト

2023-03-27Bash,Git

はじめに

先日ネット上で見つけたエントリを見て書こうと思ったエントリです。

Git のタグとして Semantic Versioning 形式を採用している事例でした。
そのエントリでは、パッチバージョン ( vXXX.YYY.ZZZ の ZZZ 部分 ) をインクリメントするのが面倒なのでスクリプト化してみたと書かれていました。

それをみて、僕も同じようにスクリプト化してみました。

検証環境

$ uname -moi
arm64 unknown Darwin

$ bash -version | head -n 1
GNU bash, バージョン 5.2.15(1)-release (aarch64-apple-darwin22.1.0)

前提

前提として、 バージョニングのフォーマットは vXXX.YYY.ZZZ としました。

タグの先頭に固定の文字として v という文字列を付与しています。

その後に数値が続き、 メジャーパージョン + . + マイナーバージョン + . + パッチバージョン の形式で続くものとしました。

ただし、 v を不要にしたり、 ドットを 4 つにしたりは容易にできる作りとなっています。

スクリプト

スクリプト名は何でも良いですが、 git-tag-inc として保存しました。

#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o noclobber

declare TAG_FORMAT='v[0-9]+.[0-9]+.[0-9]+'

echo "[CAUTION] The tag format is '${TAG_FORMAT}'." >&2

IFS=. read -r MAJOR MINOR PATCH < <(
  git tag \
    | grep -E "${TAG_FORMAT}" \
    | sort -t "." -k1,1n -k2,2n -k3,3n \
    | sed -n '$s/^v//p'
) || true

TAG="v${MAJOR:-1}.${MINOR:-0}.$((${PATCH:- -1} + 1))"

git tag "${TAG}" \
  && echo "${TAG}" >&2

git push --tags

使い方

Git のローカルワークスペースで、 git-tag-inc コマンドを実行してください。

Git ワークスペースに vXXX.YYY.ZZZ 形式のタグが存在しない場合、 タグ v1.0.0 を作成しリモートブランチにプッシュします。

# Git で管理されているディレクトリ
$ ls -ld .git
drwxr-xr-x - genzouw 13 2 09:42 .git/

# まだタグは存在していない
$ git tag

$ git-tag-inc
[CAUTION] The tag format is 'v[0-9]+.[0-9]+.[0-9]+'.
v1.0.0
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
To ssh://github.com/genzouw/x.git
 * [new tag]         v1.0.0 -> v1.0.0

# タグが作成されている
$ git tag
v1.0.0

Git ワークスペースに vXXX.YYY.ZZZ 形式のタグが存在する場合、 メジャー・マイナー・パッチバージョンが最も高いバージョンを探し、パッチバージョンをインクリメントしたタグを作成しリモートブランチにプッシュします。

ちなみにコマンドは git-tag-incgit tag-inc のいずれでも実行できます。

$ git tag-inc
[CAUTION] The tag format is 'v[0-9]+.[0-9]+.[0-9]+'.
v1.0.1
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
To ssh://github.com/genzouw/x.git

- [new tag] v1.0.1 -> v1.0.1

# インクリメントしたタグが追加されている
$ git tag
v1.0.0
v1.0.1

ひとこと

今のところ問題なく利用できています。

2023-03-27Bash,Git