Continuous integration and pull requests are two important concepts for almost any development team. Besides many other benefits, ensuring code stability and quality, ease of collaboration with other developers and fast release cycles are some of the key aspects. This post describes a solution to combine and Jenkins for automated builds of pull requests and reporting back the status to Stash. Thereby we build not the last commit of the pull request but merge the pull request automatically into the target branch. This gives a much better view if the result of merging the pull request will compile and if other coding guidelines are followed, e.g. static code analysis checks.
[Update 1: 2015-08-02]
- Starting with version 1.15 of Pull Request Notifier for Stash the RESCOPED event is removed.
- Starting with version 2.4.0 one can pass additional parameters in the Push Notification Support of the Jenkins Git Plugin. We use this to set the build description with the pull request ID and a link back to the Stash pull request with a System Groovy Script using the Jenkins Groovy Plugin.
[Update 2: 2015-08-13]
- Starting with version 1.18 of Pull Request Notifier for Stash the url for the pull request is now provided as a parameter (PULL_REQUEST_URL). The parameter can now be past directly and we don’t need to build the parameter manually.
- In order to set the build description also when there is a problem with merging the source and target branch we now set the build parameter already before we clone the repository. For this the Pre SCM Buildstep Plugin is used.
Workflow
Here the workflow we try to achieve:
- Users creates a topic branch (e.g. feature, bugfix).
- After completing his development work and pushing his changes to Stash the user creates a pull request.
- In order to approve a pull request we require at least one successful Jenkins build. Thereby we would like to get not only the build result of the code checked in for the pull request but get the build status after the code has been merged with the target branch.
- When a pull request is created/updated Jenkins shall be triggered automatically for real continuous integration.
- The source of the pull request shall be automatically merged with the target branch.
- Set the build description with the pull request ID and a link back to the Stash pull request.
- The build result shall be reported back to Stash.
- Only if the build was successful and the number of successful builds configured in Stash is reached the pull request shall be approved and merged.
Design Criteria
The following design criteria and features are addressed by this solution:
- Re-use existing plugins as much as possible
- Keep configuration to a minimum
- Clear responsibility split between Stash (PR management and notification) and Jenkins (Job management and configuration)
- Automatic merge into the correct target branch
- Support for different Jenkins job configurations (target branches) in parallel
- Different jobs for regular continuous integration and pull request pre-merge builds.
Ingredients
- Jenkins (1.609)
- Jenkins Git Plugin (2.4.0)
- Used to checkout the code from Stash and build the correct branch
- Pre SCM Buildstep Plugin (0.3)
- Jenkins Stash Notifier Plugin (1.8)
- Used to report the build result back from Jenkins to Stash
- Pull Request Notifier for Stash (1.15)
- Used to automatically trigger Jenkins on Pull Request creation/update.
- Jenkins Groovy Plugin (1.26)
Step-by-Step Configuration
- Install and configure Pull Request Notifier for Stash
- Configure Pull Request Configuration in Stash
- Install and configure Jenkins Git Plugin
- Install and configure Jenkins Stash Notifier Plugin
- Create/Update Jenkins job
Install and configure Pull Request Notifier for Stash
- Install the Pull Request Notifier for Stash add-on via the Universal Plugin Manager or manually by downloading from the Atlassian Marketplace.
- Choose Administration > Manage Add-ons > Pull Request Notifier > Configure to configure the plugin.
- Select the following triggers. They will trigger a new build when a pull request is opened, reopened, or either the target or source branch content has changed.
- OPENED
- REOPENED
- RESCOPED
- RESCOPED_FROM
- RESCOPED_TO
- Enter Jenkins and proxy credentials as required
- Choose GET as HTTP method
- Enter http://localhost:8080/jenkins/git/notifyCommit?url=${PULL_REQUEST_TO_SSH_CLONE_URL}&branches=pr/${PULL_REQUEST_TO_BRANCH}&sha1=${PULL_REQUEST_FROM_HASH}&PULL_REQUEST_URL=${PULL_REQUEST_URL}&PULL_REQUEST_ID=${PULL_REQUEST_ID} as the URL to invoke. The trick here is the pr prefix in the branch name which is then used also in the branch name in the Jenkins job configuration. By this we can differentiate between regular commits to the target branch and the pull requests and can have two jobs in parallel. This notification will trigger automatically the correct builds using the Push Notification Support of the Jenkins Git Plugin based on the target branch and automatically merges the pull request with the target branch. Please adjust the Jenkins URL (http://localhost:8080/jenkins) to match with your environment.
- Save the trigger configuration with Save.
Configure Pull Request Configuration in Stash
- Choose in your Stash repository Settings > Pull requests and select the Requires a minimum of successful builds and enter the number of builds. Example: If you have two builds for the pull request, e.g. one continuous integration and one static code analysis build and both should be successful as a prerequisite to merge the build request, enter 2 as the number of builds.
Install and configure Jenkins Git Plugin
- Install the Jenkins Git Plugin via Jenkins > Manage Jenkins > Manage Plugins
- Perform all standard configuration so that you can access Stash via SSH and can pull repositories from Stash.
Install and configure Jenkins Pre SCM Buildstep Plugin
- Install the Pre SCM Buildstep Plugin via Jenkins > Manage Jenkins > Manage Plugins
- Perform all standard configuration so that you can access Stash via SSH and can pull repositories from Stash.
Install and configure Jenkins Stash Notifier Plugin
- Install the Jenkins Stash Notifier Plugin via Jenkins > Manage Jenkins > Manage Plugin
- Choose Jenkins > Configure System > Stash Notifier and enter the data for your Stash installation.
Install and configure Jenkins Groovy Plugin
- Install the Jenkins Groovy Plugin via Jenkins > Manage Jenkins > Manage Plugins
Create Jenkins job to Build the Pull Request
- Add the Git configuration for your Jenkins job as follows
- Select Git in the Source Code Management section
- Update the Repository URL to point to your Stash installation.
- Update Branch Specifier (blank for ‘any’) and Branch to merge to to the branch name which should be build and act as the target branch. If the target branch is master, then the values should be entered in the format as shown in the following picture. Please note the pr prefix in the Branch Specifier (blank for ‘any’) field, which we have used in the URL in the Pull Request Notification Plugin configuration in a previous step.
- Set the build description with the pull request ID and a link back to the Stash pull request.
- Select in the Build Environment section the Run buildstep before SCM runs and add an Execute system Groovy script step using the following script:
def currentBuild = Thread.currentThread().executable def PULL_REQUEST_URL = build.buildVariableResolver.resolve('PULL_REQUEST_URL') def PULL_REQUEST_ID = build.buildVariableResolver.resolve('PULL_REQUEST_ID') def description = "<a href='$PULL_REQUEST_URL'>PR #$PULL_REQUEST_ID</a>" currentBuild.setDescription(description)
- This will set add pull request ID in format PR #ID, e.g. PR #1 with a link back to the Stash pull request. Here we use the new capabilities of the Jenkins Git Plugin to pass additional parameters in the commit notification, here PULL_REQUEST_ID and PULL_REQUEST_URL.
- Select in the Build Environment section the Run buildstep before SCM runs and add an Execute system Groovy script step using the following script:
- Create/update the Stash notification configuration of your Jenkins job(s) as follows
- Save job configuration with Save
- Optionally, if you have additional jobs which build the same repository/branch combination and which should not be build on pull request notifications, update the Git configuration in these jobs and add the Don’t trigger a build on commit notifications as an additional behaviour as shown on the following example.
Final Result
Congratulations, all configuration is done!
When everything is setup correctly and you have created your first pull request in Stash you should see a new build triggered in Jenkins along with the ID of the pull request in the build description.
Furthermore after the build has finished you should see the build status information updated on the pull request in Stash.
When you click on the 1 build link on the top right then you see more details on the build including a link to the respective Jenkins build.
Nice post =)
I was a bit unclear on how the RESCOPED event works. The RESCOPED_FROM and RESCOPED_TO should be checked in the example above.
More details on that discussion here:
https://github.com/tomasbjerre/pull-request-notifier-for-stash/issues/34
Thanks for the feedback. I updated the screenshot and description and added RESCOPED_FROM and RESCOPED_TO. Thanks for updating the documentation on the plugin wiki page.
What about using this with remote forked repostiories? I did the setup according to this website, but I was unable to get PR from forks to work. The jobs fails with unknown commitID (the master repo om the build machine doesn’t know the commit and I’d need to be trackign developers’ reposiroties, whcih is no go). Any ideas how to get this working with remote forks?
The solution currently works only in a setup where the source and target branch are in the same repository. Main reason for this is that the Jenkins Git plugin is used to trigger the correct build and that only one repository can be past as part of the notification. In order to trigger for changes both in the source and the target branch this would then require at least two jobs as the repositories for source and target branch are different. When source and target branch should be monitored also the “other” (the one which is not used for notification) needs to be passed so that Jenkins can do the merge. Currently the Jenkins Git plugin doesn’t allow to pass additional parameters on the commit notification, but I already submitted a PR to the Jenkins Git plugin to allow this in the future. With this it should be possible then in the future to trigger also PR builds when source and target branch are in different repositories. It nonetheless needs to be made sure, that Jenkins can reach both (source and target) repositories. So if you manage your forks also via Stash and the forks are accessible to Jenkins then it should be possible in the future. I try to do some test once the Jenkins Git plugin is released containing the necessary changes and post an update here.
Can you point me to this PR please? I am interested in helping if I can. Thanks!
https://wiki.jenkins-ci.org/display/JENKINS/Git+Plugin 2.4.0 is now released which supports passing additional parameters. I haven’t tried to build a PR where source and target repository are different but it should be possible now. Maybe I find some spare time in the next days.
I’m probably missing something, but the “refs/heads/pr/{branch}” are not handled automagically by stash, are they?
The thing is that I’m using generators, which end up failing, because pr/{branch} does not exist. I guess the generator should use {branch}, and only the generated job should use pr/{branch} ((( “use” is not the proper word, but maybe “have it in the configuration”, since I guess the job run will **use** the git hash that is passed in the notifyCommit URL and totally ignore the branch ref )))
The ref “refs/heads/pr/{branch}” actually doesn’t exists but is a necessary twist to have two builds in Jenkins.
One build which works on the actual branch (after PR approval) and another build to build on the PR. Not sure what you mean with generators but in the generated jobs the “Branches to build” should contain the refspec in the format “refs/heads/pr/{branch}” to make this two builds working You can also use any other prefix then “pr” but it felt natural to use this one. For building the branch is indeed ignored and the git hash is used.
Pingback: Set Jenkins Build Description With a System Groovy Script | Code Addiction
I used this URL with the described Stash plugin:
http://jenkins.example.com:8080/git/notifyCommit?url=$PULL_REQUEST_TO_SSH_CLONE_URL&branches=$PULL_REQUEST_FROM_BRANCH&sha1=$PULL_REQUEST_FROM_HASH&PULL_REQUEST_URL=https://stash.example.com/projects/$PULL_REQUEST_TO_REPO_PROJECT_KEY/repos/$PULL_REQUEST_TO_REPO_NAME/pull-requests/$PULL_REQUEST_ID&PULL_REQUEST_ID=$PULL_REQUEST_ID
I set the refspec for git SCM in the Jenkins job to:
+refs/pull-requests/*:refs/remotes/origin/*
Branches to build:
**
Poll SCM: H 0 1 1 0 (is an example, but this works very nice. This seems to modify the behaviour of the Git SCM plugin somehow, because this will accept the trigger URL above)
This will work with branches on the main repository, but also pull requests from forks!! Thanks a lot for this awesome blog post.
Brilliant, thank you! Note that you can actually leave the polling schedule blank and it will still work with your configuration as far as I can tell.
I am using this URL :
“http://localhost:8080/git/notifyCommit?url=${PULL_REQUEST_TO_SSH_CLONE_URL}&branches=${PULL_REQUEST_FROM_BRANCH}&sha1=${PULL_REQUEST_FROM_HASH}&PULL_REQUEST_URL=http://nidhi@localhost:7990/projects/${PULL_REQUEST_TO_REPO_PROJECT_KEY}/repos/${PULL_REQUEST_TO_REPO_NAME}/pull-requests/${PULL_REQUEST_ID}&PULL_REQUEST_ID=${PULL_REQUEST_ID}”
But dont see PULL_REQUEST_ID and PULL_REQUEST_URL getting fetched, I am doing echo for them but getting null output, also as groovy script content I get “PR#null” below the build
Can you please help me here if I am missing anything?
Which version of the Git plugin are you using? Starting with version 2.5.0 you need to configure some extra steps, see this comment.
I have kept this URL as invoke URL in stash plugin, but dont see build getting triggered when pull request is created. Am I missing anything in this URL? Git plugin is latest version one.
http://localhost:8080/git/notifyCommit?url=$PULL_REQUEST_TO_SSH_CLONE_URL&branches=pr/$PULL_REQUEST_TO_BRANCH&sha1=$PULL_REQUEST_FROM_HASH&PULL_REQUEST_URL=$PULL_REQUEST_URL&PULL_REQUEST_ID=$PULL_REQUEST_ID
I have added following in jenkins.xml and restarted service still no luck
-Xrs -Xmx256m -Dhudson.plugins.git.GitStatus.safeParameters=PULL_REQUEST_ID,PULL_REQUEST_URL -jar “%BASE%\jenkins.war” –httpPort=8080 –webroot=”%BASE%\war”
Works like a dream man! You’re a life saviour! Thanks !
First, thanks for the great post! I have got a setup working as you have described 🙂
Now I am wondering how I get at the parameters in Jenkins so I can differentiate between pull requests that are opened and rescoped and pull requests that are approved. So How do I get at the PULL_REQUEST_ACTION parameter?
The use case is 2 seperate jenkins jobs.
* One job reacts on the opening and updating of a pull request. It will merge to our integration branch, build and execute a “trimmed” down set of tests. It will not push merge back to repository.
* Another job reacts on pull request approval. It will merge to our integration branch, execute a more robust set of tests and push the merge back to repository, if all goes well.
Nice to hear that I was able to help.
The event type is available as the PULL_REQUEST_ACTION parameter.
I see the following two options
1. For each job type/event combination a configuration in the Stash plugin and add an additional parameter in trigger URL, e.g. ACTION=${PULL_REQUEST_ACTION}. In order to trigger the correct job type update the refspec in the git configuration and the URL and set the two different values, e.g. origin/pr_open/master and origin/pr_approved/master
2. Similar to the first approach create for each job type/event combination a configuration in the Stash plugin and add an additional parameter in trigger URL, e.g. ACTION=${PULL_REQUEST_ACTION}. Instead of using different refspecs to trigger the correct Jenkins job, one can use only one Jenkins job type and differentiate between the types using the Conditional BuildStep Plugin to execute the trimmed version or full version based on the ACTION parameter. I haven’t tested this approach but it should work.
Thank you so much. This was a great post and has helped me immensely!
One problem I have run into is that a Pull Request that has a conflict (so it cannot be auto-merged) will cause problems for other Pull Request builds. I am not exactly sure why because I wipe/re-clone the repository before each job, but I get the message “ERROR: Branch not suitable for integration as it does not merge cleanly: Could not merge ” for branches that can be merge. (If I force the PR build to kick off again later, it will work just fine).
I have seen others with the issue resolve it by setting the branch specifier to “refs/remotes//”, but I wasn’t sure how that could apply to Pull Requests specifically.
We are are running about 300 Jobs with this setup and we haven’t encountered this problem so far. We clean the workspace after each build with the https://wiki.jenkins-ci.org/display/JENKINS/Workspace+Cleanup+Plugin. You also need to make sure that you run only one build at a time for a particular job.
The jobs are using the “Wipe out repository & force clone” setting from the Jenkins GIT plugin, which seems to be clearing out the whole workspace as far as I can tell.
However, your comment that we should make sure to only run one build at a time makes me wonder if I have made a different mistake. For reasons I can’t defend on the internet, the repository actually contains several independently-built products, so each pull request triggers several separate Jenkins jobs (each with its own repo clone). Many PRs only affect one or two of the products, so I added Groovy Script to check the sub-folder and exit (successfully) early if there are no changes. This means that we often have different builds running against different Pull Requests- though we never have the same build running twice. In picture form:
Repository A
|—-> Product 1
|—-> Product 2
|—-> Product 3
At any time we could have the following jobs running:
– Product 1 Build (for Pull Request AA-123)
– Product 2 Build (for Pull Request BB-456)
– Product 3 Build (for Pull Request CC-789)
Though we would never have two builds of the same product going at once (for example Product 1 building twice).
I would not have thought this would be an issue since each job has its own full clone of the repo, but the issue does seem to occur around the time that one product is building with an unmerge-able pull request.
First of all, thank you: I’ve been despairing of coming up with a decent solution to this problem, and it looks like what you’ve put together here actually works!
My only gripe is the tiniest of things:
def description = “<a href=’$PULL_REQUEST_URL’>PR #$PULL_REQUEST_ID</a>”
currentBuild.setDescription(description)
…doesn’t seem to work, as jenkins escapes the html and thus you end up with a literal “<a href=…” displayed as the build description. Is there some groovy or jenkins setting that has to be adjusted for this to work? (And does doing so open us up to XSS?)
I’m glad to hear that the blog post was helpful to others as well. I currently don’t have access to a Jenkins instance so I can’t check the details but as far as I remember there is a setting in the global configuration of Jenkins which enables or disables the rendering of HTML in various places, e.g. build descriptions.
I will check the configuration when I have access to a Jenkins instance. In the meantime this link might be of help (https://issues.jenkins-ci.org/browse/JENKINS-22028).
I had this issue and the setting is in the security global section of jenkins.
change the Markup Formatter option to safe HTML rather than plain text.
This works !!! Thank you
This works !!!!!!!!! Thanks
Hi!, works for bitbucket cloud service?
Hi,
although having Bitbucket in the name, Bitbucket Server and Bitbucket Cloud are two different products. The approach here is tested with Bitbucket Server.
Great article, works like a charm!
Many thanks Rick.
Do you have to configure the add-on in stash for each repo (jenkins .git url)?
No, the plugin is configured on a global level.
ok. However, you do need to configure ‘each block’ for every jenkins invoke url. Correct? Meaning, for every Jenkins job you want to execute based on the PR and STASH repo.
You also need to configure each Jenkins instance only once but not each Jenkins job. Jenkins (actually the Git Plugin) automatically triggers the correct build.
Do these instructions work anymore? I was not able to install stashNotifier because it said there were missing dependencies of plain-credentials (1.1) and ssh-agent (1.3) … I had newer versions installed. When I attempted to downgrade, my entire Jenkins system would not start and had to be re-installed.
it’s also not clear what things like this mean: Perform all standard configuration so that you can access Stash via SSH and can pull repositories from Stash.
You can’t use HTTP?
1. If you have a specific problem with installing a plugin you should check on the plugin home page and file an issue on the plugin issue tracker.
2. You need to configure the correct URL for you repo in Bitbucket Server. You can also use HTTP but from a performance point of view I advise to use ssh.
Pingback: Manage the lifecycle of pull requests with Bitbucket, Jenkins and ElasticBox | ElasticBox
Please note that there is a difference between Bitbucket and Bitbucket Servers. Although they share the name they are actually different products having also a different code base. My post is about Bitbucket Server.
Christian, thanks for this great post and for your feedback. That’s the reason why we decided to include “(having Stash but not Bitbucket)” in that part. Anyway, every feedback an comment is always welcome and again, congrats!
Great writeup! Our BitBucket Server and Jenkins setup recently broke due to incompatibilities introduced by a couple of updates so I decided to give your setup a shot. Unfortunately I can’t seem to get it to work. Jenkins doesn’t seem to see the pull requests from BitBucket Server. Do you have any suggestions for how I could troubleshoot this?
We’re using Jenkins 2.8 with all the plugins at their latest version.
You can check in the Jenkins log if the you get the request from the Bitbucket server. If I remember correctly I think you should see some logs if you grep for “notifyCommit”. If you have Apache/Nginx fronting Jenkins then you can also check their log files.
Could it be related to the “lazy ref updates” in Bitbucket (described at https://answers.atlassian.com/questions/239988/answers/3038176)? We had to implement something that would do a get to the REST API for the pull-request/*/changes before the call to the jenkins /git/notifyCommit url.
Without that, anytime we pushed new code to an already open pull request, jenkins would be triggered to poll for changes, but would never find changes until someone manually visited the pull request page in BitBucket.
I’ve been looking for another solution to this problem, but we do not control the BitBucket server, so I can’t change any settings there, but if I can get enough ammunition, I might be able to convince those admins to make changes.
Our setup is jenkins 1.642, Git plugin 3.0 & BitBucket 4.10.2 with Bitbucket Server Webhook to Jenkins (not sure of version) with Branch Options set to “build all: pull-requests/* develop”
Hi
Firstly just want to say thanks for this post. Its been instrumental in helping me get a build process setup that does pull requests.
Only minor issue I’ve had is that I don’t seem to have values for the variables in the groovy script. Which means my build ends up with a description
PR #null
and a link to null as well.
I’ve double checked the name of the parameter in the Bitbucket configuration and in the Jenkins configuration and it seems to be the same. Its just missing this value. Is there something else I need to configure to get this bit to work?
Many thanks Again
Starting with the Git Plugin 2.5 parameters send via the notification are not automatically passed as parameters to the job for security reasons.
In order to allow again to pass the parameter to the job an additional environment parameter needs to be set containing the name of the parameters to pass.
More details can be found at https://github.com/jenkinsci/git-plugin/commit/cb778dd7ee1c7a3f820ac1021be89e60d56ac057.
Currently I don’t have an installation available with Git Plugin 2.5 so it would be great if you can configure your system as documented in the link with the additional environment parameters and leave a comments if this works.
First of all thank you for this very handy article Christian! I am new to Jenkins and went with it because Bamboo is just way to expensive for us at the moment and I never thought that Jenkins can be integrated with Bitbucket at this level.
Unfortunately I haven’t been able to solve one thing and since you seem to be active here I’d like to ask your help.
It seems that the Groovy script can’t extract the PULL_REQUEST_URL and PULL_REQUEST_ID parameters from the build environment. I am using Jenkins 2.10 with version 2.5 of the Git Plugin. I can see in the webserver’s logs in front of Jenkins that the parameters are passed on and everything else is working fine, although the job’s description shows ‘null’ where those variables should’ve been extended.
Do you have any suggestions on how should I proceed?
Starting with the Git Plugin 2.5 parameters send via the notification are not automatically passed as parameters to the job for security reasons.
In order to allow again to pass the parameter to the job an additional environment parameter needs to be set containing the name of the parameters to pass.
More details can be found at https://github.com/jenkinsci/git-plugin/commit/cb778dd7ee1c7a3f820ac1021be89e60d56ac057.
Currently I don’t have an installation available with Git Plugin 2.5 so it would be great if you can configure your system as documented in the link with the additional environment parameters and leave a comments if this works.
Hi Christian,
thank you for pointing me in the right direction. Here’s what I did to make it work.
I passed Java the ‘-Dhudson.plugins.git.GitStatus.safeParameters=’PULL_REQUEST_URL,PULL_REQUEST_ID” parameter, and configured the job as parameterized and added the above two as string parameters without any default values.
Glad to see that it works. Out of curiosity did you also tried without the additional job parameters but only specifying the hudson.plugins.git.GitStatus.safeParameters?
Yes I tried it. Jenkins rejects the parameters because they are not defined at the job level. I think that’s another layer of security.
Thanks for testing. I will update the post in the next days with the details for the Git plugin 2.5.
After some tinkering I now have a job that uses parameters in the build, mainly to have a job that takes one branch merges it to another and running tests etc on the result.
To make it work in 2.5.0
1. add the “-Dhudson.plugins.git.GitStatus.safeParameters=XXX,YYY,ZZZ” to the startup of jenkins (https://wiki.jenkins-ci.org/display/JENKINS/Features+controlled+by+system+properties)
2. add String parameters to the build with name equal to the notifyCommit params. e.g XXX,YYY.ZZZ. No need for default values. If the job is not parameterized this way, I can’t get it to work…
3. Use them as $XXX (or ${XXX}) in the build steps.
Thanks for the work on this! It’s a really good feature of the notifyCommit handler.
I tried adding them in jenkins.xml and restarted jenkins service as I am using jenkins on windows machine. But still it dint help.
-Xrs -Xmx256m -Dhudson.plugins.git.GitStatus.safeParameters=PULL_REQUEST_ID,PULL_REQUEST_URL -jar “%BASE%\jenkins.war” –httpPort=8080 –webroot=”%BASE%\war”
Hello Nidhi:
The issues is that you are trying to append safeParamters to JENKINS_ARGS not JAVA_ARGS. Please remove -Dhudson.plugins.git.GitStatus.safeParameters=PULL_REQUEST_ID,PULL_REQUEST_URL from JENKINS_ARGS and add them to JAVA_ARGS.
Hope that helps.
Hi
First of all thank you very much for the comprehensive guide. Very enlightening 🙂
Hi Nikos,
thank you very much for your kind works, always glad to help.
Regards
Christian
Hi Christian,
Thanks for the great article.. Really helpful…
My use case is slightly different than explained, but helped in configuring most of it.
I need to trigger a SONAR Build when a Pull request is created. for the same we have installed SONAR STASH plugin on SONARQube server and now with the this plugin trying to invoke the Jenkins job for that project.
Queries :
1. Is the URL mentioned in article suffice for SONAR as well?
Geting 404 code. Not sure why, as Jenkins is up and running
If not, can you please direct me to correct one.
2. I was not sure, and created 2 configs on STASH/BitBucket . How to get hold of them and remove the incorrect one?
Thanks in advance.
Milind
Hello Christian,
Thanks for the very detailed tutorial. I configured the Jenkins and Stash server as per the instructions, however I don’t see any job triggers on Jenkins when a PR is created on stash server.
How can I debug the issue?
Thanks
Rishabh
Now I am getting triggers, the trick was to change the notifyCommit url from `PULL_REQUEST_TO_SSH_CLONE_URL` to `PULL_REQUEST_TO_HTTP_CLONE_URL`.
This of course depends what you have configured in the Jenkins jobs. If you use HTTP as the protocol then you also have to use the HTTP URL. If you use SSH (what most people do and I recommend due to better performance) the SSH URL needs to be used.
Great article. Thanks a lot for putting the time to write this up.
A couple of questions here:
– I am using Sonar Qube Plugin & Sonar for Bitbucket to perform to display any sonar violations on pull requests in Bitbucket
https://mibexsoftware.atlassian.net/wiki/display/SONAR4STASH/Usage
and
https://mibexsoftware.atlassian.net/wiki/display/SONAR4STASH/Jenkins
In order to decline the pull request if either fails, do I set the minimum number of successful builds required to 2?
ISSUE: Bitbucket Push Notify Fails
===========================
Git Plugin: Push notification from repository
See: https://wiki.jenkins-ci.org/display/JENKINS/Git+Plugin#GitPlugin-Pushnotificationfromrepository
The Git Plugin accepts the build trigger only when “Build Triggers-> Poll SCM” is selected. No CRON schedule should be entered in the text area.
ERROR: from HTTP GET:
====================
No git jobs using repository: ssh://git@codecloud.web.att.com:7999/st_titan/goss.git and branches:
No Git consumers using SCM API plugin for: ssh://git@codecloud.web.att.com:7999/st_titan/goss.git
I found that the Jenkins (version 2.44) build trigger made by “Pull Request Notifier for Bitbucket” must have the “Poll SCM” feature enabled. This doesn’t appear in the directions. Please, add it.
Hi,
We have Jenkins version 2.7.1 and git plugin 3.1.0
Our Jenkins running on Linux OS
Still whenever we raised request in jenkins still showing PR #null;
In Linux please can you help where to add those parameters.
The id is passed as parameter PULL_REQUEST_ID from Bitbucket using the Pull Request Notifier add-on, see step 6.
You also need to make sure to configure all the parameters which shall be passed through, see my comment from 2016-06-27 AT 18:30 and the answer by Mate.
This is our settings:URL to invoke this is we have.These are parameters.
http://localhost:8008/jenkins/git/notifyCommit?url=${PULL_REQUEST_TO_SSH_CLONE_URL}&branches=pr/${PULL_REQUEST_TO_BRANCH}&sha1=${PULL_REQUEST_FROM_HASH}&PULL_REQUEST_URL=${PULL_REQUEST_URL}&PULL_REQUEST_ID=${PULL_REQUEST_ID} &PULL_REQUEST_TO_BRANCH=${PULL_REQUEST_TO_BRANCH}
Please can you guide and we are not aware were these should be added-Dhudson.plugins.git.GitStatus.safeParameters=PULL_REQUEST_URL,PULL_REQUEST_ID,PULL_REQUEST_FROM_HASH,PULL_REQUEST_TO_BRANCH
Do we need to change anything in build step.
Thanks
First of all thanks.
I am having a issue with the triggering the pull request one is for commit build on the branch and another for pull request. If the branch name is develop/feature then i have configures the branch pr/develop/feature for pull request build and develop/feature for commit build, this is not triggering the build but if i add **/ prefix in the branch name the build was triggering, but the problem is when ever there is a pull request trigger commit build also will be triggered.
Is there any way to stop the commit build.
You should add the remote name to the branch spec as in the examples, e.g. origin/pr/develop/feature. For the build which should not be triggered please make sure to select “Don’t trigger a build on commit notifications” as in indicated in step 5 of the Jenkins job configuration.
Pingback: pull requests with jenkins and stash – DevOps meets QA
Pingback: pull requests with jenkins and stash – DevOps meets QA
Thanks for the post.
I am interesting in a different scenario. I am looking for triggering the jenkins build only for Pull Request. But not trigger build for the commits that are made before creating the pull request.
Eg:
I made a commit to my feature branch (let’s say there are 4 commits). I don’t want the build to trigger for all the 4 commits. But once I create a pull request, the build should start triggering right then.
With your solution, jenkins triggers the build for all the commits before even creating the pull request, which I don’t want.
Can you please suggest any solution ?
Hi,
actually the configuration above is only triggered when the PR is created, i.e. commits on feature branches before the PR is created will not trigger a build.
Please double-check the configuration especially the following settings on Jenkins and the branch configuration (read the “pr” prefix) and the Jenkins Bitbucket notification URL
Hi,
How do we achieve trigger pull request for Pipeline job ? Does commit notify work for pipeline job as well? What are the required changes when working with jenkins pipeline for triggering build on pull request?
Unfortunately I have not used pipeline jobs so far, so can’t really say if there is a difference or not and/or if this is possible at all.
Hi,
If I understand correctly , you want to trigger a build based on Pull Request … Which agains has different events including :
Created
Updated
Approved
Approval removed
Merged
Declined
Comment created
Comment updated
Comment deleted
If you want to trigger a build, then you can configure Bitbucket plugin and trigger your pipeline Job. Have not seen a Pipeline method for the same, but can be achieved.
Step 1 : Configure Bitbucket plugin. Configure it (different for cloud and server)
Step 2 : add a web hook on the repo which you want something like — http://jenkinsurl/bitbucket-hook/
Step 3 : Tick Check box “Trigger build when Push on Bitbucket” on the job configured
Should do the trick and it works on Free style jobs…
Regards
Milind
Thanks! Very useful post.
Please, add a note to your post regarding Jenkins 2. It requires some additional configuration in order to get parameters working due to some security changes.
You can allow all parameters by adding
“-Dhudson.model.ParametersAction.keepUndefinedParameters=true” to your startup options or specify a certain parameters to allow (this is more secure).
More information:
https://jenkins.io/blog/2016/05/11/security-update/
Is there a way to reject the PR if the build fails?
I general there are two ways.
1. In Bitbucket one can specify how many successful builds are necessary. If you set this to 1 than you can’t merge the PR, but the PR is not declined.
2. You can use the Bitbucket REST API (https://developer.atlassian.com/static/rest/stash/3.0.1/stash-rest.html?_ga=2.110131269.1955833390.1509989598-636621228.1450025476#idp1074112)
can anyone help me by, making a video on this.. i am not able to get it work even after following the same configurations. Thanks for this !!
What exactly is not working? Have you checked the logs of Jenkins and Bitbucket to see potential problems and/or see which URLs are triggered and what are the response codes.
thanks Christian, now the job is getting triggered and everything is working accordingly. The only issue i am facing is that i am not able to get the proper build description in bitbucket. In jenkins, i am getting PR#_ ..while, bitbucket description is looking something like this PR # .Can u throw some light on this …
bitbucket decription is like this PR #
Please check if &PULL_REQUEST_ID=${PULL_REQUEST_ID} is part of the triggering URL and that you have copied the groovy script correctly.
i can see two types of groovy script execution in prebuild scm, one is execute groovy script and other one is execute system groovy script… which one i have to choose?
if my jenkins is CSRF protected, do i need to use crumb issuer and all in injection url or it should work fine without any injection url also…..
The thing is actually,, the pull request plugin is not triggering the job, its the poll scm which is looking at the change and triggering the job.. dn know .. what i am doing wrong.
Thanks for ur patience 🙂
First, as documented it is “System Groovy Script” you have to use.
Second, enable “Poll SCM” but do not specify a cron expression,
Third, make sure that you add the “pr” prefix in the triggering URL and the branch name configuration
Hello Christian,
This was very very helpful, but I have one question. 🙂
Do you know how to take the value of the branches(branch1 -> branch2)? I want to trigger another Jenkins job with the value of the branch1.
Thank you in advanced,
George
Not sure if I understand your question correctly. The source branch (I guess branch1 in your example) is in the PULL_REQUEST_FROM_HASH parameter.
Hi.
Yes, you have understood good, but when I try to extract the value from it, I get the “null” value.
I am trying on this way:
def id = manager.build.buildVariables.get(“PULL_REQUEST_FROM_HASH”);
Thank you!
George
Please check https://christiangalsterer.wordpress.com/2015/07/28/set-jenkins-build-description-with-a-system-groovy-script/ how to extract build parameters in a groovy script. Please also check if the parameter is actually really passed from Bitbucket to Jenkins, e.g. by checking the log files.
This is a great post and I’m looking to implement it. One question around the automatic merge that Jenkins builds from: Am I right in thinking that Jenkins will merge the source branch (develop in my case) into the PR branch on the local repository in Jenkin’s GIT workspace? i.e. It doesn’t actually commit & push any merge back to the origin.
The merge is actually the other way around, i.e. the PR source branch is merged into the target branch of the pull request. The merge is only done locally and temporarily and not pushed anywhere.
Thanks – makes sense.
I’m having trouble though. My target branch is develop not master, and my branch specifier is ‘origin/pr/develop’ as per your screenshot (develop substituted for master), but when I have it set to this, the build does not get triggered when `git/notifyCommit?` is invoked.
However, if I set it to `origin/pr/feature/pull-request-branch` it does get triggered.
Although it does fail with:
MSBUILD : error MSB1009: Project file does not exist.
And I can see that the $BRANCH variable isn’t being resolved for the solution file path:
“%WORKSPACE%\$BRANCH\MySolutionFile.sln”
My notifyCommit URL looks like:
https://jenkins/git/notifyCommit
?url=ssh%3A%2F%2Fjenkins%40%3A7999%2Fvon%2Frepo.git
&branches=pr%2Ffeature%2Ftest-pr
&sha1=aaa5cd0386f6fc9b166fe1bd7effc2fde1ffb1e7
&PULL_REQUEST_URL=https%3A%2F%2Fbitbucket%2Fprojects%2FVON%2Frepos%2Frepo%2Fpull-requests%2F371
&PULL_REQUEST_ID=371
Ignore this, I realised that the “&branches=” parameter in the URL contained the source branch rather than the target (develop).