ロカオプ技術ブログ

株式会社ロカオプの技術ブログです。

masterブランチの最新commitにタグをつけるスクリプトを作成してリリース作業の改善を行なった

概要

みなさんこんにちは。フルスタックエンジニアの高瀬 @takasehiromichi です。

今回は、普段の運用フローで実施している、タグをコミットに付与してリリース作業を自動的に行なっているところをもっと楽にするためにスクリプトを作成したので、記事にしようと思います。

背景

株式会社ロカオプでは、プルリクエストを出してマージした後、masterブランチの該当コミットに対してタグを付与してpushします。

例:v20230201.1

これは、その日のうちにまたリリースが発生すれば、小数点以下の値を増やして、タグの名前を変えて新たに異なるコミットにタグを付与し、またリリースを行います。

例:v20230201.2

ただ、手動でタグを付与して手動でpushしている都合上、本来タグを付与すべきでない場所にタグを付与し、誤ったリリースを行なってしまう可能性がありました。

そこで、リリース作業におけるタグ付与については、スクリプトを介してのみ実施することで、誤ったリリースを未然に防ぐことができると考え、今回スクリプトを作成するに至りました。

スクリプト作成

今回作成したスクリプトは、以下のようなスクリプトです。

#!/bin/bash
echo "[executing...] addTagToLatestMaster.sh"
echo ""
echo "git fetchを実行"
git fetch

localMasterHash=$(git rev-parse master)
remoteMasterHash=$(git rev-parse origin/master)

echo ""
echo " localMasterHash: "$localMasterHash
echo "remoteMasterHash: "$remoteMasterHash
echo ""

if [ $localMasterHash = $remoteMasterHash ]; then
    echo "remoteと差分はありません"
    echo "最新のタグを確認します"
    echo ""
    git checkout master
    latestMasterTag=$(git describe --tags --abbrev=0 master)
    latestMasterTagDate=${latestMasterTag:1:8}
    latestMasterTagVersion=${latestMasterTag:10:11}
    todayDate=`date '+%Y%m%d'`

    echo ""
    echo "       latestMasterTag: "$latestMasterTag
    echo "   latestMasterTagDate: "$latestMasterTagDate
    echo "latestMasterTagVersion: "$latestMasterTagVersion
    echo ""

    if [ $latestMasterTagDate = $todayDate ]; then
        echo "今日はすでにリリースが存在します。versionをひとつ増やしてタグを付与します"
        echo ""
        newMasterTag="v"$todayDate"."$(($latestMasterTagVersion+1))
        echo "newMasterTag: "$newMasterTag

        echo ""
        echo "git tagを実行"
        git tag $newMasterTag $remoteMasterHash

        echo ""
        echo "git pushを実行"
        echo ""
        git push origin $newMasterTag

        echo ""
        echo "タグの付与が完了しました"

    else
        echo "今日はまだリリースが存在しません。新たなversionでタグを付与します"
        newMasterTag="v"$todayDate".1"
        echo "newMasterTag: "$newMasterTag

        echo ""
        echo "git tagを実行"
        git tag $newMasterTag $remoteMasterHash

        echo ""
        echo "git pushを実行"
        echo ""
        git push origin $newMasterTag
        
        echo ""
        echo "タグの付与が完了しました"
    fi
else
    echo "remoteと差分があります"
    echo "git fetchを実行"
    git fetch
    echo "git checkout masterを実行"
    git checkout master
    echo "git pullを実行"
    git pull
    echo "masterが最新になっていることを確認して、もう一度実行してください。"
fi

順に解説します。

事前準備

#!/bin/bash
echo "[executing...] addTagToLatestMaster.sh"
echo ""
echo "git fetchを実行"
git fetch

localMasterHash=$(git rev-parse master)
remoteMasterHash=$(git rev-parse origin/master)

echo ""
echo " localMasterHash: "$localMasterHash
echo "remoteMasterHash: "$remoteMasterHash
echo ""

最初に、「addTagToLatestMaster.shというスクリプトを実行してますよ〜」と表示します。

次に、git fetchを実行します。

その次に、remoteのmasterブランチの最新ハッシュと、localのmasterブランチの最新ハッシュを引っ張ります。

remoteのハッシュとlocalのハッシュが同一の場合

if [ $localMasterHash = $remoteMasterHash ]; then
    echo "remoteと差分はありません"
    echo "最新のタグを確認します"
    echo ""
    git checkout master
    latestMasterTag=$(git describe --tags --abbrev=0 master)
    latestMasterTagDate=${latestMasterTag:1:8}
    latestMasterTagVersion=${latestMasterTag:10:11}
    todayDate=`date '+%Y%m%d'`

念のため、一旦masterにチェックアウトします。

remoteのハッシュとlocalのハッシュが同一の場合、そのままタグをつけられますので、最新のタグを確認します。

タグのフォーマットは、「vYYYYMMDD.」なので、YYYYMMDDとを取ります。

また、今日の日付をYYYYMMDDで取ります。

    echo ""
    echo "       latestMasterTag: "$latestMasterTag
    echo "   latestMasterTagDate: "$latestMasterTagDate
    echo "latestMasterTagVersion: "$latestMasterTagVersion
    echo ""

念のため画面にも表示しておきましょう。

既存のタグの日付が今日の日付と同じ場合

    if [ $latestMasterTagDate = $todayDate ]; then
        echo "今日はすでにリリースが存在します。versionをひとつ増やしてタグを付与します"
        echo ""
        newMasterTag="v"$todayDate"."$(($latestMasterTagVersion+1))
        echo "newMasterTag: "$newMasterTag

既存のタグの日付が今日の日付と同じ場合、今日はすでに最低1回はリリースを実施しているということなので、versionをひとつ増やしたタグ名を生成します。

        echo ""
        echo "git tagを実行"
        git tag $newMasterTag $remoteMasterHash

        echo ""
        echo "git pushを実行"
        echo ""
        git push origin $newMasterTag

        echo ""
        echo "タグの付与が完了しました"

該当コミットに、タグを付与してpushして終わりです。

既存のタグの日付が今日の日付と同じではない場合

    else
        echo "今日はまだリリースが存在しません。新たなversionでタグを付与します"
        newMasterTag="v"$todayDate".1"
        echo "newMasterTag: "$newMasterTag

既存のタグの日付が今日の日付と同じではない場合、今日はリリース作業がまだ行われていませんので、今日の日付と、versionは1でタグ名を生成します。

        echo ""
        echo "git tagを実行"
        git tag $newMasterTag $remoteMasterHash

        echo ""
        echo "git pushを実行"
        echo ""
        git push origin $newMasterTag
        
        echo ""
        echo "タグの付与が完了しました"
    fi

該当コミットに、タグを付与してpushして終わりです。

remoteのハッシュとlocalのハッシュが同一ではない場合

else
    echo "remoteと差分があります"
    echo "git fetchを実行"
    git fetch
    echo "git checkout masterを実行"
    git checkout master
    echo "git pullを実行"
    git pull
    echo "masterが最新になっていることを確認して、もう一度実行してください。"
fi

remoteのハッシュとlocalのハッシュが同一ではない場合、想定の作業内容と異なる可能性があるので、masterを引っ張っておいてから、masterが最新になっていることを確認すること、およびスクリプトをもう一度実行することを促します。

package.jsonへの登録

{
  ...
  "scripts": {
    "deploy": "./dev/ops/script/addTagToLatestMaster.sh"
  },
  ...
}

(※一部省略しています)

これで、npm run deploy を実行すると、masterブランチの最新commitにタグをつけることができるようになりました。

まとめ

こういった細かい改善は、やるときは少し面倒ですが、やっておくと後々きいてくるので、積極的に行うようにしています。

今後も開発者体験の向上を行なっていきます。