はじめに
どうも!生産技術部のエンジニアです。Gitのタグを自動更新できる様にGitLab CIに設定してみました。マージされるトピックブランチ毎に更新ルールを変えられるスクリプトを組みましたので紹介します。
GitLabサーバを一から構築される方は、以下からご覧ください。
「proxy環境下でDocker Composeを用いてCentOS7上にGitLab Dockerを作成」
前提条件
GitLab、GitLabRunnerの導入が実施済みであること。
対象のブランチモデル
以下のブランチモデルを利用し、masterブランチにトピックブランチがマージされた時に、タグの更新を行います。利用するブランチモデルについてはここを参照ください。
Developブランチからマージされた場合とそれ以外のブランチからマージされた場合で分けて、タグの更新ルールを以下の様に設定します。
Merge branch 'develop' into 'master'
1.0.0 -> 2.0.0
Merge branch 'hotfix' into 'master'
1.0.0 -> 1.0.1
自動更新スクリプトの作成
作成するスクリプトについて紹介します。作成するファイルは、
- GitLab CI用の設定ファイル(
.gitlab-ci.yml
)、 - マージイベント時に、起動するスクリプト(
release.sh
)、 - タグの更新ルールを設定するスクリプト(
version_up.sh
)
の3つです。
GitLab CIの設定
.gitlab-ci.yml
には、release_job
にリリース用のスクリプトを追加し、リリース用のスクリプト内で、タグ更新用のスクリプトを起動します。masterブランチにマージされた際にタグ更新を実施するように、masterブランチのみに対して設定します。
stages:
- develop
- release
- hotfix
develop_job:
stage: develop
script:
- echo "develop"
only:
- develop
release_job:
stage: release
before_script:
- chmod u+x scripts/release.sh
script:
- scripts/release.sh
only:
- master
hotfix_job:
stage: hotfix
script:
- echo "hotfix"
only:
- hotfix
マージされたトピックブランチを判別
release.sh
では、マージされたトピックブランチがdevelop
かそれ以外かを判別します。マージされた時のコミットメッセージをログ出力し、トピックブランチの名前を切り出しています。git log --grep "<pattern>"
みたいなのを使えばもう少しスッキリ書けるのかもしれないです。切り出した名前がdevelop
だった場合はメジャーアップデート、それ以外の場合はバグフィックスできる様に、version_up.sh
にmajor/bugfix
を引数に与えています。
下記サンプルは更新されるタグを表示するまでで、実際にタグ付けはしていません。
#!/bin/bash
chmod u+x scripts/version_up.sh
# マージ時のgit logからトピックブランチのブランチ名を切り出す
merged_branch_name=$(git log --pretty=oneline --abbrev-commit --merges -n 1 | awk '{print $4}' | sed 's/'\''//g')
# ブランチ名がdevelopだった場合はメジャーアップデート、それ以外はバグフィックス
if [ $merged_branch_name = "develop" ]; then
git tag -l | tail -n 1 | scripts/version_up.sh major
else
git tag -l | tail -n 1 | scripts/version_up.sh bugfix
fi
タグの更新ルールを設定
タグの更新スクリプト(version_up.sh
)は、神速様の「gitでタグ名に日付を含めているのはダサい」を参考に作成させて頂きました。更新ルールは、メジャーアップデート、マイナーアップデート、バグフィックスのみとしました。
#!/bin/sh
version=`awk '{print $1}' < /dev/stdin`
command=$1
major=`echo $version | awk -F '.' '{print $1}'`
minor=`echo $version | awk -F '.' '{print $2}'`
bugfix=`echo $version | awk -F '.' '{print $3}'`
if [ -z "$version" ]; then
echo "USAGE: echo 1.0.0 | version_up.sh [major|minor|bugfix]"
exit 1
fi
if [ "$command" = '' ]; then
bugfix=`expr $bugfix + 1`
elif [ "$command" = 'major' ]; then
major=`expr $major + 1`
minor=0
bugfix=0
elif [ "$command" = 'minor' ]; then
minor=`expr $minor + 1`
bugfix=0
elif [ "$command" = 'bugfix' ]; then
bugfix=`expr $bugfix + 1`
fi
echo ${major}.${minor}.${bugfix}
最後に
タグの自動更新するスクリプトが完成しました。テストに使用したリポジトリはここにあります。もっとスマートなスクリプトがあれば教えてください。