Mobile Factory Tech Blog

技術好きな方へ!モバイルファクトリーのエンジニアたちが楽しい技術話をお届けします!

push 忘れのあるブランチで Jenkins を走らせない工夫

こんにちは、駅奪取チームエンジニアの id:kebhr です。

駅奪取チームでは Pull-Request を本番環境に反映する前に Jenkins を用いてフルテストを実行しています。 手順としては Jenkins をキックするシェルスクリプトを使い、開発環境で次のようなコマンドを実行します。

cd $PROJECT_ROOT

# カレントブランチのテストを実行する
./jenkins

# or

# 特定のブランチのテストを実行する
./jenkins ${branch_name}

しかし、このスクリプトは push 忘れのチェックを行っておらず、ブランチ・コミットを push し忘れた状態でフルテストを走らせてしまうという問題点がありました。

push 忘れに気付いたときに push し、フルテストを走らせれば問題ありませんが、フルテストを二度走らせることになるためリードタイムが長くなります。

そこで、ローカルに push していないコミットが存在する場合は、フルテストを実行せずにエラーを表示するようにスクリプトを変更しました。

全体像

#!/bin/zsh
set -ue

# 中略
# 引数またはカレントブランチを取得し $BRANCH にブランチ名を格納

if ! git show-branch remotes/origin/$BRANCH > /dev/null 2>&1; then
    echo "このブランチは push されていません"
    exit 1
fi

if ! git diff remotes/origin/$BRANCH..$BRANCH --quiet --exit-code; then
    echo "push されていないコミットがあります"
    exit 1
fi

# Jenkins API をキック

ブランチの push 忘れを判定する

if ! git show-branch remotes/origin/$BRANCH > /dev/null 2>&1; then
    echo "このブランチは push されていません"
    exit 1
fi

git show-branch <branch> は、引数に与えたブランチが存在すれば終了コード 0、存在しなければ 128 を返します。 ブランチの push 忘れを判定するためには、origin にそのブランチが存在することを確認すればよいので、引数に remotes/origin/$BRANCH を与えます。

なお、この実装では、fetch していないブランチのテストを実行しようとした際に「このブランチは push されていません」と表示されエラー終了しますが、チーム内でこのような状況には直面しないため許容しています。

コミットの push 忘れを判定する

if ! git diff remotes/origin/$BRANCH..$BRANCH --quiet --exit-code; then
    echo "push されていないコミットがあります"
    exit 1
fi

git diff A..B --quiet --exit-code は A と B の間に差分が存在すれば終了コード 1、存在しなければ 0 を返します。 コミットの push 忘れを判定するためには、リモートとローカルの差分を確認すればよいので、引数に remotes/origin/$BRANCH..$BRANCH を与えます。

git diff> /dev/null 2>&1 といったコマンドを用いずとも、--quiet オプションによって出力を抑制できます。 --exit-code オプションは結果を終了コードでも返すオプションです。しかし --quiet オプションを指定すると暗黙的に --exit-code オプションが有効になります。よって --exit-code オプションは省略できますが、コードの理解を容易にするために記述しています。