08 February 2014

How to trigger a Jenkins build on git commit

I spent quite some time figuring this out, but was happy when it worked. This is for Windows. In Linux, the process is the same, but it's far easier.

First, you have to know that if you've installed Git in Windows, it comes with curl pre-installed. So just open the Git bash prompt and start typing your commands.


Let's say you have a Jenkins job setup on localhost, named "someJob". To initiate a build, just type the following command in the Git Bash prompt:

curl http://localhost:8080/job/someJob/build?delay=0sec

That's it. Once you've typed the command, just have a look at your Jenkins dashboard and you'll see your project building. (you might also want to know about this)

Now to make a Git commit trigger the build, you have to navigate to the hidden ".git" directory in your git repository. Enter the "hooks" directory and you'll see there, a "post-commit.sample" file. You can open it with Notepad++ to see the contents of it.

Make a copy of the file and name it "post-commit". It does not need an extension. This is the file that Git will invoke whenever you do a commit to this particular Git repository. Don't worry about the fact that it looks like a Linux bash script. When Git triggers it, it will run even in Windows. If the file has a line ": Nothing", you can remove that line and insert this new line:

curl http://localhost:8080/job/someJob/build?delay=0sec

Now save the file, make some changes to your git repository and commit the changes. The moment you commit, you'll see the build being triggered in Jenkins! Awesome! :)


-----------------------------------------------------------------

Additional note: Many people reach this page via a StackOverflow answer. One such person (see comment below answer) mentioned being confused about what "someJob" was and also had faced an issue with his project name having a space in between, so he had to substitute "%20" in place of a space "codecept%20tests". Hope his response would be of help to anyone else who faces a similar situation. Thank you Paul.


19 comments:

Anonymous said...

Hmmmh, if _you_ push changes to a remote repository, and if _you_ (want to) trigger the build, it's going to work this way. BUT: typically the receiving repository shall have the 'post-receive' hook (which will trigger the build). You would do this only _once_ on the receiving system. Else everybody pushing to the repository will need to configure such a hook.

Nav said...

That's a good idea. Thanks for sharing! The post-commit hook can come in handy though, in situations where a team wants finer grained control on how their builds should get triggered.

Anonymous said...

What if i want to trigger a build only when a new TAG is applied to repository? How do we do that?

Nav said...

Hi Nir. You can use the Parameterized tag plugin https://wiki.jenkins-ci.org/display/JENKINS/Parameterized+Trigger+Plugin
Use the tag as a parameter.
Rather than build on a tag, I would recommend building on every change that is committed to the repository. That's the whole purpose of CI. You can use the Heavy Job Plugin (https://wiki.jenkins-ci.org/display/JENKINS/Heavy+Job+Plugin) to run parallel builds if you're worried about multiple people building too often. Also, remember that everyone on the team is supposed to do a local build with Jenkins before pushing the code to the main repository where the integrated build takes place.

Vijay Polsani said...

curl -X POST http://:/job/job-name-in-jenkins/build?delay=0sec --user user:password

Nav said...

Thanks for posting the command for a REST client, Vijay. Much appreciated!

Unknown said...

I didn't find any sample file named
post-commit.sample in my .git/hooks folder.
I am using git version 1.9.1

Nav said...

@Bavanasi: that's odd...the latest version of Git also creates the post-commit file. Even bare repositories do. Please ask on the Git forum, as the problem seems to be something else.

Unknown said...

Just like Bavanasi, I couldn't find a post-commit.sample file too. Could you share yours please, I use a Mac OS X to run Jenkins?

Nav said...

@Hariharan: I hope both of you created new git repositories and searched for the file in that? The .git folder is a hidden folder. If you still did not find it, please ask your question on a Git forum and post back here if you find a solution. My giving you the file won't help.

Tom said...

I have no sample file "post-commit" too, but you can just create one, it's very simple:

#!/bin/sh
curl "http://192.168.99.200:8080/job/Test01/build?delay=60sec"

save it as "post-commit" and you are done.
in windows, you can use for example "start chrome http://www.google.de" to see, if your post-commit works (file is executed afer commit)

Nav said...

Hi Tom. Thanks for sharing the technique. I haven't encountered this problem on Linux or Windows. Even on asking on a Git forum, nobody responded. They haven't been through such a situation, apparently.
https://groups.google.com/forum/#!topic/git-users/WgY6Bce6_ho

Anonymous said...

I had the same problem (Linux,Ubuntu), it was because my post-commit file was not writable. A chmod a+x post-commit might be you solution

Unknown said...

@Navin IPE . I am using ubuntu machine, As you said in the first line , will it be different in ubuntu ?

Surendra Vadlamudi said...

Hi Navin,
i need small information:I want to do build on every pull if there are changes @ Java files.could you please suggest.
I know in general it is 'post-receive' hook where we do trigger the build.But we dont want to create hooks on remote server.So we poll every 15 mins, and if there is a change in java files we want to trigger build.

Nav said...

Well Surendra, as you'd already know, polling is not recommended. If you really want it, in Jenkins there is the poll SCM option in build triggers. You could have saved time by Googling it:http://lmgtfy.com/?q=jenkins+poll+for+changes+in+repository

adiyaman said...

It has to be a POST request as :

from Python :

call(["curl", "-sS", "-X", "POST", "http:///job//build"])

adiyaman said...

sorry, above comment did not format well.

PYTHON call:

call(["curl", "-sS", "-X", "POST", "http://JENKINS_SERVER:PORT/job/JOB_NAME/build"])

Nav said...

Thank you @golfer. I haven't verified the command yet, but I trust you've posted the right solution. Am also considering copying Vijay, Tom and your contributions to the main post, with attribution. Pending verification though...