Git にはタグという機能があります。これは簡単に言うとコミットに名前を付ける機能です。特筆すべき点としてコミットメッセージとは別に付けられる、タグの観点から操作や閲覧ができる、という点があります。
Git – タグ
タグ|サル先生のGit入門【プロジェクト管理ツールBacklog】
タグのよくある使い方はリリースやデプロイなどのバージョン番号の管理です。次の画像の GitHub の releases にあるリリース番号はタグで管理されています。他にも npm、composer、PyPI、Mavenなど様々なパッケージマネージャーのバージョン番号がこのタグ由来です。
タグをつけてデプロイする方法ですが何度も目と手で繰り返すのは意外と手間です。自分が一人親方をする時によくあるローカルの開発をリモートにデプロイするの場合では次の様になります。
- デプロイタイミングのコミットまで済ませておく
git tagやGit用GUIツール上から最新のタグを見つける- 見つけたタグの次のバージョンのタグを
git tag [次のバージョン番号]で追加 git pushでコミットをリモートに反映git push --tagsでタグをリモートに反映
コマンドをまとめるスクリプトを作りってで手間を省きたくなります。pushについては決まりきったコマンドなので楽ですが、タグをつける段階についてはいくらか工夫が必要そうです。
最新のタグを見つける方法は git コマンドできます。具体的には次です。
> git describe --tags --abbrev=0 0.28.1 # 自分の環境のとあるコードの最新バージョン
git describeコマンドはあるコミットを指して使うコマンドで、そのコミットを人間向けの語にして返してくれます。–tags は注釈のない名前だけのタグを探し、–abbrev=0は省略形を返してくれる様になるオプションです。これで最新のタグを得られます。
Git – git-describe Documentation
Git – プロジェクトの運営#ビルド番号の生成
次のバージョン番号を生成するコードは次のJavaScriptで作れます。シンプルなセマンティックバージョニング前提です。RCやbetaなどつける様な場合には対応していませんが、同じ考えで拡張できるかと思います。
セマンティック バージョニング 2.0.0 | Semantic Versioning
/** node getNextTag.js --patch の様に使う想定です */
if (!process.argv.includes('--patch') && !process.argv.includes('--minor') && !process.argv.includes('--major')) {
console.error('--patch か --minor か --major を渡してください');
process.exit(1);
}
const childProcess = require('child_process');
// 最新タグの取得。git コマンドを使う
const latestTag = childProcess.execSync('git describe --tags --abbrev=0').toString();
// [メジャー, マイナー, パッチ]の番号に分ける
const versions = latestTag.split('.').map((v) => Number(v.replace(/\D/g, '')));
// 引数として渡された上げたいバージョン形式に合わせて番号を進める
if (process.argv.includes('--major')) {
versions[0]++;
versions[1] = 0;
versions[2] = 0;
} else if (process.argv.includes('--minor')) {
versions[1]++;
versions[2] = 0;
} else if (process.argv.includes('--patch')) {
versions[2]++;
}
// タグとしての名前の形式にバージョン番号を整形
// v0.1.2 の様な場合は`v${versions.join('.')}`などで対応可能
const nextTag = versions.join('.');
// 次のバージョンのタグを表示
console.log(nextTag);
// 終わり
process.exit(0);
これで自動で次のタグを用意できます。後はデプロイに必要なコマンドをまとめるだけで当初の目的である”デプロイの手間を省く”が達成できます。自分の場合は make コマンドを用いて次の様にしました。これができると最新のバージョンをいたるところで扱えますので、複数か所の設定ファイルやドキュメントなどのバージョンの整合性を取るのも自動化できます。
# make deploy patch, make deploy minor, make deploy major の様に使います
deploy:
# 自動で次のタグを取得して git tag コマンドに渡してタグを追加
node ./gitNextTag.js --${TAG_NEXT_TYPE} | xargs git tag
git push # コミットをプッシュ
git push --tags # タグをプッシュ
