tl;dr
Jenkins上でマージするのを諦めよう
使ってるバージョン
- Jenkins v1.643
- Gitlab Merge Request Builder Plugin v2.0.0
- Git client plugin v1.19.1
- Git plugin v2.4.1
エラー詳細
こんな感じのエラーです
19:58:57 > git rev-parse origin/develop^{commit} # timeout=10 19:58:57 > git config core.sparsecheckout # timeout=10 19:58:57 > git checkout -f origin/develop 19:58:57 > git merge -s recursive --no-ff 70659b22c6503833c8d3f71b7754dd3e16e2d71e # timeout=10 19:58:57 > git config core.sparsecheckout # timeout=10 19:58:57 > git checkout -f 70659b22c6503833c8d3f71b7754dd3e16e2d71e 19:58:57 ERROR: Branch not suitable for integration as it does not merge cleanly: Could not merge AnyObjectId[70659b22c6503833c8d3f71b7754dd3e16e2d71e] 19:58:57 Finished: FAILURE
大した差分でもないしGitLab上でもコンフリクト起こしていないしアクセプトボタンも押せる状態なのに、なぜかJenkins上でマージできずにエラーになるということがたまにありました
2年くらい使ってる自分の経験則では
- fast forwardでマージできる場合にはエラーは起きないが、fast forwardでマージできない場合にエラーになる
- MergeRequestのsource branch(送り元のトピックブランチ)とtarget branch(送り先のブランチ)の差分が大きいとエラーになりやすい
という感じでした。
Git flowを使っている場合に、リリースブランチからdevelopブランチへのマージ*1は問題ないのに、masterブランチへのマージ*2でエラーになるのでなかなか厳しいものがありました。(つらい)
エラーが発生してる場所
Jenkinsのコンソールログだけだと特定しづらかったですが、JGitでのマージに失敗してるようでした。 https://github.com/jenkinsci/git-plugin/blob/git-2.4.2/src/main/java/hudson/plugins/git/extensions/impl/PreBuildMerge.java#L76
そりゃJenkinsサーバのgitのバージョンを上げても直らないわけだ。。。
設定をいろいろいじった
思いっきし「This feature is not fully implemented in JGIT.(この機能はJGITでは完全にサポートされていない)」って書いてるなw
Fast-forward modeを --no-ff
にした状態でMerge strategyは全種類試しましたが解決しませんでした。。。
対処法
Additional Behavioursを消した
Before
Gitlab Merge Request Builder Pluginのドキュメントに書いてる設定
After
修正後
Merge before buildを削除。要はsource branchをtarget branchにマージした状態でテストするのではなく、source branch自体をテストするというわけです
「マージした状態でビルドしなくて大丈夫か?」とも思うかもしれませんが、
- 差分がでかい時にマージエラーが起きるくらいならマージしないでビルドしたい
- ビルドに時間がかかるとrebaseしてビルドし直すコストが高い *3
- マージした先のdevelopブランチやmasterブランチもJenkinsでビルドをしている *4
と判断で外しました。
ちなみに同プラグインのGitHub版の GitHub pull request builder plugin だと ${sha1}
(マージしない状態のPullRequestのコミットID)でテストをしていました
しばらく運用してみた
上記設定で1週間くらい運用してみました
ビルドスクリプトを修正してmasterにコミットした時にトピックブランチ側が古い状態でビルドしてエラーになることがありましたが、それ以外はそれなりに快適にやってます。まぁその辺はトレードオフなんじゃないかと。