Triggering Jenkins build from locally hosted git repository using the post-receive commit hook

11 Jun 2023 - tsp
Last update 11 Jun 2023
Reading time 6 mins

So it’s very easy to integrate Jenkins with your GitHub repository by simply using the GitHub plugin of Jenkins. This provides a webhook and automatically registers it with a remote repository after providing an authentication token to GitHub. But when one hosts ones own source code source repository on an on premises system using git and builds software using Jenkins triggering a Jenkins job requires a little bit more work. This very short blog article shows one of many ways of solving that problem by using an post-receive hook on the server side repository as well as an build trigger via https.

The Jenkins side

The Jenkins side requires:

To create a new user go to Manage Jenkins > Manage Users > Create User. To add an API token edit a user via Manage Jenkins > Manage Users > [select a user] > Settings > API-Token. Note that this API token can be used to trigger any actions the user is authenticated for. This API token has to be stored - it won’t be shown by Jenkins any time in future after leaving that dialog. This token can then be used instead of the password to authenticate with Jenkins when doing API calls.

To create and add the SSH credentials to Jenkins first create them using ssh-keygen in case you don’t already have some:

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/usr/home/sampleuser/.ssh/id_rsa): /usr/home/sampleuser/.ssh/id_jenkinsgit
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /usr/home/sampleuser/.ssh/id_jenkinsgit.
Your public key has been saved in /usr/home/sampleuser/.ssh/id_jenkinsgit.pub.
The key fingerprint is:
SHA256:WQHxR3YPWqPwOuXX3r4Ri7RKfVo9e+wojaKvfKr5a1U sampleuser@samplehost.example.com
The key's randomart image is:
+---[RSA 2048]----+
|        ooo o =  |
|         . * = + |
|          o *   .|
|         o =E  . |
|        S o......|
|          ..o.o.=|
|         . . * B+|
|       o. + + =o*|
|      o+BB.o o.+=|
+----[SHA256]-----+
$

Now add the public key from id_jenkinsgit.pub into your .ssh/authorized_keys on the repository server (see below). The private key has to be added to Jenkins credential store. Go to Manage Jenkins > Manage Credentials and select the credentials store under Stores scoped to Jenkins. Select the security domain and select Add Credentials. There use the SSH username and private key type. The ID can be left out, the description is arbitrary. Enter your username and upload the content of the id_jenkinsgit file into the entry box after selecting Enter directly. In case you’ve added a passphrase during creation of the key also enter the passphrase. Store the key and take a note of it’s key ID. This will be required later on.

Then configure the pipeline of the given job. There the checkout line could look like the following:

checkout changelog: true, poll: true, scm: [
	$class: 'GitSCM',
	branches: [[name: '*/master']],
	doGenerateSubmoduleConfigurations: false,
	extensions: [[$class: 'WipeWorkspace']],
	submoduleCfg: [],
	userRemoteConfigs: [[url: 'sampleuser@192.158.1.38:/usr/home/sampleuser/git/reponame', credentialsId: '273096b7-0cba-4a8e-adda-21a8378ea79f' ]]
]

As one can see this project has configured to wipe it’s workspace every time due to some project specific reasons. In addition the userRemoteConfigs contains the SSH username, the hostname or IP as well as the path on the servers filesystem. The credentialsId refers to the SSH private key ID in Jenkins keystore that should be used to authenticate against the repository.

As a last step go to Build triggers and tick Trigger builds remotely. There also take a note about the URI - that also contains the job name.

In case you have hostkey verification enabled (which is a good idea) add the SSH host key of the remote system to the known_hosts of the machine that will do the git access - i.e. the Jenkins host or some of it’s slaves. The easiest way is to just execute a simple ssh connection using Jenkins user to the repository - this will also verify networking is setup correctly and everything works out as expected. One can of course also manually add the public key of the host to the ~/.ssh/known_hosts on the Jenkins machine.

The repository side

Now on to the repository side. This can be any machine that you have SSH access to. First lets add the public SSH key to the local authorized_keys file. Usually this is located at ~/.ssh/authorized_keys. It’s a good idea to try to log into the machine using your generated key manually to rule out some problems later on.

Then just generate a directory where you want to host your git repository - for this example the decision fell onto /usr/home/sampleuser/git/reponame:

$ mkdir -p /usr/home/sampleuser/git/reponame```

Then initialize a bare repository:

$ cd /usr/home/sampleuser/git/reponame
$ git init --bare
Initialized empty Git repository in /usr/home/sampleuser/git/reponame

Now one will have to create one’s post-receive commit hook. This is located under hooks/post-receive inside the repository directory. The most simple hook is just a shell script executing a curl to trigger the build:

#!/bin/sh

curl -X POST "https://sampleuser:APITOKEN@JENKINSHOSTORIP/job/JOBNAME/build"

exit 0

That’s it. Mark that file executable (for example chmod 750 post-receive). Now one can move on the client and use that remote repository.

How to add the remote to the client side

This is the simplest part and works just like for any other remote.

git remote add origin sampleuser@192.158.1.38:/usr/home/sampleuser/git/reponame

From this moment on one can directly push and pull to and from the repository. Each push will trigger the build using this simple script. In case one wants to provide filtering the script received on it’s standard input 3 values:

This article is tagged: Basics, System administration, Jenkins


Data protection policy

Dipl.-Ing. Thomas Spielauer, Wien (webcomplains389t48957@tspi.at)

This webpage is also available via TOR at http://rh6v563nt2dnxd5h2vhhqkudmyvjaevgiv77c62xflas52d5omtkxuid.onion/

Valid HTML 4.01 Strict Powered by FreeBSD IPv6 support