テストが辛くなった時のためのPullRequestBuilderまにゅある

KLab Advent Calender 9日目の記事です
実はAdventCalendar初投稿のhohhenです。よろしくお願いします

どんな時のマニュアル?

プロジェクト開発してると必ずと言っていいほど使うのがJekins PullRequestBuilderプラグイン

ですが、プロジェクトの規模が大きくなるにつれてテストの時間は長くなったり、PRラッシュによるテストキューが詰まったり、テストとは関係のないファイルのPRをわざわざテストを通したりと辛くなってきます...

その際にテスト側をチューニングするのはもちろんですが、今回はPrb側を弄ってみます

重複したテストを停止させる

pushされた際にテストする形にしていると細かい単位でpushした際に連続してテストが走ってしまい
先のテストが無駄になってしまうので先のテストは停止させるようにしてしまいましょう

設定は簡単
ジョブの設定 > ビルド・トリガ > Trigger Setup > 追加 > Cancel build on update

はいこれでテスト詰まった時に手動で重複ジョブを止める必要がなくなりましたね

コンフリクト時テストを停止させる

テストが走っているのに対象のPRがコンフリクトしてたらテストしている意味が薄くなってしまうのでさっさと止めてしまいましょう

これは残念ながらPullRequestBuilderには設定が見当たらなかったのでbashで書いていきます
(もっと良い方法あるかも

IS_MERGE_REV=`git name-rev --name-only head | grep merge | wc -l`
if [ ${IS_MERGE_REV} = 0 ] ; then
  echo "[check conflict] Is not merge commit. There is a possibility that This branch has conflicts that must be resolved"
  exit 1
fi

PullRequestBuilderはテスト時リモートブランチである
refs/pull/${PR番号}/(merge|head) (コンフリクトしてた場合はhead)をfetchして
refs/remotes/origin/pr/${PR番号}/(merge|head)にチェックアウトします
なので現在のrev名がmergeじゃなかった場合はコンフリクトしているのでスキップしてしまいます。

テストすべきファイルがPRに含まれているかチェックする

フロントエンド側のプロジェクトに携わっているとちょいちょいGitHubにリソースをコミットするケースが出てきます
もちろんPRは出すわけですが、リソースだけのPRをテストにかけるのはあまりに時間がもったいないのでこれも止めてしまいましょう

これもPullRequestBuilderいい感じの変数がなかったのでがんばってbashで書いていきます

IS_MERGE_REV=`git name-rev --name-only head | grep merge | wc -l`
if [ ${IS_MERGE_REV} = 0 ] ; then
  echo "[check conflict] Is not merge commit. There is a possibility that This branch has conflicts that must be resolved"
  exit 1
fi

TARGET_FILE_COUNT=`git show \
  | grep Merge: \
  | awk '{print $2}' \
  | xargs git diff --name-only head\
  | grep -e "^\(path/to/\(controller\|service\|model\)\)"
  | wc -l`

if [ $TARGET_FILE_COUNT = 0 ] ; then
  echo "Test target file is not modify"
else
  echo "Start test"
fi

前半は先程紹介したコンフリクトチェックで
後半はmergeされたrevisionであることを利用して$2(ベースブランチ)側とhead側のdiffを取った後に
テスト対象のディレクトリであればテストを行うようにしてあります

おまけ

PullRequestBuilder調べてる途中でGitHub側でPRのhead/merge revisionが作られていて、それらがデフォルトのfetchの対象外になっていることに気づいたので以下のようなaliasを作ってみました

[alias]
    ch-pr-head = "!f() { git fetch origin \"+refs/pull/$1/head:refs/remotes/origin/pr/$1/head\"; git ch origin/pr/$1/head; }; f" 
    ch-pr-merge = "!f() { git fetch origin \"+refs/pull/$1/merge:refs/remotes/origin/pr/$1/merge\"; git ch origin/pr/$1/merge; }; f" 

git ch-pr-merge 1234 とすると#1234PRのベースブランチとマージ済みrevisionにチェックアウトすることができます
レビュワーになった時とか便利なので是非

さいごに

初のAdventCalendarでしたが、ちょっと内容泥臭すぎたかなーという印象
もっと良い感じにPullRequestBuilder弄っていきたい

明日は kakkun61 さんの記事です。では

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.