Keeping Redmine Git Repositories Synchronized Using Jenkins3 min read

Redmine is a software project management tool with many great features. One such feature is the ability to link to your source code repository.  When this link has been established, you are able to view individual commits and the contents of the repository. A downfall however, is the repository directory has to be physically located on the Redmine host. To complete this, you simply clone a mirror of the repository to a directory on the server. To perform this clone execute the following command in the directory where your repositories will reside:

git clone --mirror git@<address>:<repository name>

This will create the repository that Redmine can display. Now, the issue remains of how to keep it synchronized. That is, each time code is committed to the repository we need to update the repository on Redmine. This is solved by creating an update script which will reside in the same directory as the repositories. My update script looks like this:

#!/bin/bash

echo "Updating ${repoName}"
cd /path/to/your/repositories/${repoName}
git fetch -q --all -p
echo "Repository update for ${repoName} completed."

You will need to update the path to meet your repository location. For my setup, I use gitolite to control repository access. This can pose some challenges because the user who will perform the update has to have access to gitolite as well. I will not cover gitolite setup in this article, but you can read a good article here.

The Jenkins server performs all of its tasks as the system user jenkins. In my article Performing Auto Updates with Jenkins, I talk about setting up Jenkins to have access to other VMs on your network. Jenkins will need to be able to run the following command as a super user to perform the update:

sudo runuser -l <user with git access> -c 'export repoName=<repo name>.git && /path/to/your/repositories/updateRepo'

Super user must be used because the jenkins user on the Redmine host is executing a script who is owned by a different user with Git access. The command exports the environment variable needed for the update script and then executes the update script. In my case the script is named updateRepo. This approach was chosen because a single script can be used to update all repositories and the only change needed is the repository name exported by Jenkins.

In Jenkins, I configure a separate build item with the sole purpose of updating the repository. It is configured to build after the actual software project builds even if the software build fails. The reason for this is the software build is triggered from a Git hook which indicates a change to the repository has occurred. If the software build fails from a bad commit, the repository on the Redmine server will still be updated.

This method of updating your Redmine repositories is very useful when your Git repositories are not hosted on the same host as Redmine. For example, if you have a Redmine instance on your home network and choose to use GitHub for your Git repositories you could perform these steps and keep your Redmine instance up to date.

Hope you found this article to be helpful. Please visit my site often for more home networking articles.

Leave a Reply

Your email address will not be published.