问题
First off, this is not a duplicate question of "merge before build" feature. I googled and reviewed whatever I found regarding this feature. But none talks about my problem.
We've got Bitbuck Server + Jenkins and I wrote a job for our PRs on Bitbucket:
job('pull-request-job') {
scm {
git {
remote {
name 'origin'
credentials 'jenkins-ssh'
url 'ssh://git@stash.example.com/my/repository.git'
refspec '+refs/pull-requests/*/from:refs/remotes/*'
}
branch '**/pull-requests/**'
extensions {
mergeOptions {
remote 'origin'
branch 'master'
}
}
}
}
triggers {
scm ''
}
steps {
shell './mvnw -e clean verify'
}
}
Quick note: we don't practice gitflow or anything like that. Mostly (not always though) it's just one master
and branches on which developers are working.
Objective: I want to have a job which is triggered by Bitbucket server for each pull-request. In the job I want to checkout the my
branch (the one I worked on and is gonna be merged to master
branch) and run the tests. The default configuration does the job pretty well. Now before running tests, I want to get the latest changes from master
branch (or any other branch that my
branch is gonna be merged to) to my
branch. How can I do that?
Having the above job description won't work. An example of the build is:
commit notification 1606dd8
[EnvInject] - Loading node environment variables.
Building in workspace /var/lib/jenkins/workspace/pull-request-job
using credential jenkins-ssh
> git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
> git config remote.origin.url ssh://git@stash.example.com/my/repository.git # timeout=10
Fetching upstream changes from ssh://git@stash.example.com/my/repository.git
> git --version # timeout=10
using GIT_SSH to set credentials Jenkins User SSH Private Key
> git fetch --tags --progress ssh://git@stash.example.com/my/repository.git +refs/pull-requests/*/from:refs/remotes/*
> git rev-parse 1606dd8^{commit} # timeout=10
> git branch -a -v --no-abbrev --contains 1606dd8 # timeout=10
Merging Revision 1606dd8 (3, 2, 1) to origin/master, UserMergeOptions{mergeRemote='origin', mergeTarget='master', mergeStrategy='default', fastForwardMode='--ff'}
> git rev-parse origin/master^{commit} # timeout=10
> git config core.sparsecheckout # timeout=10
> git checkout -f origin/master
> git merge --ff 1606dd8 # timeout=10
> git rev-parse HEAD^{commit} # timeout=10
Seen branch in repository 1
Seen branch in repository 2
Seen branch in repository 3
Seen branch in repository origin/master
Seen 4 remote branches
> git show-ref --tags -d # timeout=10
Checking out Revision 1606dd8 (1, 2, 3, origin/master)
> git config core.sparsecheckout # timeout=10
> git checkout -f 1606dd8
Commit message: "Upgrade maven"
> git rev-list --no-walk 1606dd8 # timeout=10
> git rev-list --no-walk 1606dd8 # timeout=10
> git rev-list --no-walk 1606dd8 # timeout=10
[pull-request-job] $ /bin/sh -xe /tmp/jenkins3480907669634770028.sh
+ ./mvnw -e clean verify
As logged, Jenkins, after merging my branch to master
, is checking out the origianl commit again (git checkout -f 1606dd8
) and continue the build. The log shows it is indeed the code without changes from master
branch being built.
Questions:
1. Why is it checking out the original commit after merging? Why is it not continue the build on the merged code?
2. How can I make branch
parameter in mergeOptions
dynamic so that it's always the other branch in the pull-request?
Thanks.
回答1:
I have no idea why, but somehow it fixes the problem. Add localBranch
to scm.git.extensions
entry:
extensions {
cleanBeforeCheckout()
localBranch() // or localBranch('${PR_DESTINATION}')
mergeOptions {
remote('origin')
branch('${PR_DESTINATION}')
}
}
And the log is:
commit notification 1606dd8
[EnvInject] - Loading node environment variables.
Building in workspace /var/lib/jenkins/workspace/rad-test-1-pr
[WS-CLEANUP] Deleting project workspace...
[WS-CLEANUP] Deferred wipeout is used...
using credential jenkins-ssh
Cloning the remote Git repository
Cloning repository ssh://git@stash.example.com/my/repository.git
> git init /var/lib/jenkins/workspace/rad-test-1-pr # timeout=10
Fetching upstream changes from ssh://git@stash.example.com/my/repository.git
> git --version # timeout=10
using GIT_SSH to set credentials Jenkins User SSH Private Key
> git fetch --tags --progress ssh://git@stash.example.com/my/repository.git +refs/heads/*:refs/remotes/origin/*
> git config remote.origin.url ssh://git@stash.example.com/my/repository.git # timeout=10
> git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
> git config remote.origin.url ssh://git@stash.example.com/my/repository.git # timeout=10
Cleaning workspace
> git rev-parse --verify HEAD # timeout=10
No valid HEAD. Skipping the resetting
> git clean -fdx # timeout=10
Fetching upstream changes from ssh://git@stash.example.com/my/repository.git
using GIT_SSH to set credentials Jenkins User SSH Private Key
> git fetch --tags --progress ssh://git@stash.example.com/my/repository.git +refs/pull-requests/*/from:refs/remotes/*
> git rev-parse 1606dd8^{commit} # timeout=10
> git branch -a -v --no-abbrev --contains 1606dd8 # timeout=10
Merging Revision 1606dd8 (4, 3, 2, 1, origin/first-branch) to origin/master, UserMergeOptions{mergeRemote='origin', mergeTarget='master', mergeStrategy='default', fastForwardMode='--ff'}
> git rev-parse origin/master^{commit} # timeout=10
> git config core.sparsecheckout # timeout=10
> git checkout -f origin/master
> git merge --ff 1606dd8 # timeout=10
> git rev-parse HEAD^{commit} # timeout=10
Seen branch in repository 1
Seen branch in repository 2
Seen branch in repository 3
Seen branch in repository 4
Seen branch in repository origin/first-branch
Seen branch in repository origin/master
Seen 6 remote branches
> git show-ref --tags -d # timeout=10
Checking out Revision 663303d (origin/master)
> git config core.sparsecheckout # timeout=10
> git checkout -f 663303d
> git branch -a -v --no-abbrev # timeout=10
> git checkout -b master 663303d
Commit message: "Merge commit '1606dd8' into HEAD"
回答2:
> git config core.sparsecheckout
// Checked out but no local branch yet
> git checkout -f 663303d
// Only when local branch is defined
> git branch -a -v --no-abbrev
// Checkout 663303d into local branch master
> git checkout -b master 663303d
Git Plugin does it very verbose, but it creates a new repository fetching all branches and tags but has no local branches yet, only remote references.
> git checkout -f 663303d
Checks out the commit but there is no local branch available. We are on a detached head now, because there is no local branch.
> git checkout -b master 663303d
Creates local branch master from the formerly checked out (detached head) commit 663303d
Why Git Plugin does it that way is that they have implemented it that way. If you want to have clarification maybe drop them a message.
Why did my Git repo enter a detached HEAD state?
来源:https://stackoverflow.com/questions/55917897/jenkins-job-dsl-git-plugin-how-to-merge-before-build