開発しているコードをリリースするときにバージョンを更新するのは地味に面倒です。
- semver に則って新バージョンを決める or カスタムで決める
- package.json 等の管理情報のバージョンを書き換えて commit する
- 最終的に
git tag
でバージョンのタグ付けを行う
リリースのたびにこのような定型的な作業を行うのは大変なのと、人力でやることでミスを誘発する可能性も高くなるので、これらの一連の作業を自動で行うカスタムコマンド git-release
を作って安全・安心なタグ付けをしましょう。
できること
Usage: git release [-p] [<newversion> | major | minor | patch]
git release NEWVERSION
で、指定したバージョンのタグを付与します。
package.json or build.sbt がある場合には、ファイル内のバージョン情報を上書きして commit します。
package.json or build.sbt で semver を利用している場合、以下のような自動 semver 更新が利用可能です。
git release patch
で 1.1.1 -> 1.1.2 のように patch 部分がインクリメントされます。
git release minor
で 1.1.1 -> 1.2.0 のように minor 部分がインクリメントされます。
git release major
で 1.1.1 -> 2.0.0 のように major 部分がインクリメントされます。
git release -p patch
のように -p
をつけると、origin に自動で push されます。
動作条件
- git-flow(gitflow-avh 等)を導入済みであること
- Mac であれば
brew install git-flow-avh
で OK
- Mac であれば
- git リポジトリが
git flow init
されていること
リリース時のタグ付けを
git flow release
で行っているだけなので、その他のブランチ運用を行っている場合は適宜個々人で改修してください。
設置方法
以下の bash script をchmod 755
した上でパスの通っているところに設置するだけです。
/usr/local/bin
等に設置しても良いですが、~/bin
等 $HOME 以下に閉じたほうが良さげ。
#!/bin/bash
set -e
usage() {
echo "Usage: git release [-p] [<newversion> | major | minor | patch]" >&2
exit 1
}
getVersion() {
local file=$1
case $file in
package.json)
echo $(grep '"version":' $file | cut -d'"' -f4)
;;
build.sbt)
echo $(grep 'version\s*:=' $file | cut -d'"' -f2)
;;
esac
}
setVersion() {
local file=$1
local version=$2
case $file in
package.json)
sed -i '' -e '/"version"/s/"[^"]*",$/"'$version'",/' $file
;;
build.sbt)
sed -i '' -e '/^version :=/s/"[^"]*"$/"'$version'"/' $file
;;
esac
}
incSemver() {
local version=$1
local type=$2
local semver=($(echo $version | tr '.' ' '))
if [ ${#semver[@]} -ne 3 ]; then
echo "$version is not semver." >&2
exit
fi
case $type in
major)
semver[0]=$(expr ${semver[0]} + 1)
semver[1]=0
semver[2]=0
;;
minor)
semver[1]=$(expr ${semver[1]} + 1)
semver[2]=0
;;
patch)
semver[2]=$(expr ${semver[2]} + 1)
;;
esac
echo $(echo ${semver[@]} | tr ' ' '.')
}
while getopts hp OPT
do
case $OPT in
p)
USEPUSH=1
;;
h)
usage
;;
*)
usage
;;
esac
done
shift $((OPTIND - 1))
if [ $# -eq 0 ]; then
echo "VERSION required." >&2
usage
fi
VERSION=$1
for VERFILE in package.json build.sbt ""; do
[ -f $VERFILE ] && break
done
case $VERSION in
major|minor|patch)
if [ -z $VERFILE ]; then
echo "package.json or build.sbt not found." >&2
exit 1
fi
VERSION=$(incSemver $(getVersion $VERFILE) $VERSION)
;;
esac
git flow release start $VERSION > /dev/null
if [ -n "$VERFILE" ]; then
setVersion $VERFILE $VERSION
git add $VERFILE
git ci -m "build: bump version to $VERSION" > /dev/null
fi
GIT_MERGE_AUTOEDIT=no git flow release finish -m release $VERSION > /dev/null
if [ -n "$USEPUSH" ]; then
git push origin $VERSION
git push origin master
git push origin develop
fi
echo "$VERSION released!"
最後に
類似のものは他にもありますが、こういった類のものは行いたい処理が環境によって異なるのと、1スクリプト=導入がシンプル&カスタマイズ性が高いので、この程度であれば自作のほうが使い勝手が良いと思います。
github 上には git-semver のようなツールもありますので、より高度なことを行いたい場合には検討してみても良いでしょう。