06. September 2010

Maven Repositories on GitHub

I love git! And therefore I also love github.com! I use GitHub very often to publish smaller or even large projects and share them with others. As I mostly use Maven to build my Java projects, I recently searched for an easy way to publish Maven artifacts via GitHub. I learned that it is in fact very easy! Interested? Read on! :-)

The basic idea of hosting Maven repositories on GitHub is to use GitHub Pages. This GitHub feature offers a simple but powerful way for creating and hosting web sites on their infrastructure. Fortunately this is all we need to create Maven repositories. I'll explain the process by example. Therefore I'll show you how I created a repository for jsf-maven-util, one of my recent spare time projects.

The first step is to create a separate clone of your GitHub repository in a directory next to your primary local repository:

$ pwd
/home/ck/workspace/jsf-maven-util
$ cd ..
$ git clone git@github.com:chkal/jsf-maven-util.git jsf-maven-util-pages
$ cd jsf-maven-util-pages

The GitHub Pages web site must be created as a branch named gh-pages in your repository. So lets create this branch and empty it. Refer to the GitHub Pages Manual if you are interested in the exact meaning of these commands.

$ git symbolic-ref HEAD refs/heads/gh-pages
$ rm .git/index
$ git clean -fdx

We will place the Maven repository in a subdirectory of this new branch:

$ mkdir repository

We also want to have a pretty directory listing. Unfortunately GitHub Pages doesn't have native support for this. So we will create our own directory listing with a simple bash script.

Create a file named update-directory-index.sh in the root of the new branch (next to the repository directory). This script will walk recursively into the repository directory and create index.html files in each subdirectory. Please be careful when using this script as it overwrites all exiting index.html files it finds.

#!/bin/bash

for DIR in $(find ./repository -type d); do
  (
    echo -e "<html>\n<body>\n<h1>Directory listing</h1>\n<hr/>\n<pre>"
    ls -1pa "${DIR}" | grep -v "^\./$" | grep -v "^index\.html$" 
        | awk '{ printf "<a href=\"%s\">%s</a>\n",$1,$1 }'
    echo -e "</pre>\n</body>\n</html>"
  ) > "${DIR}/index.html"
done

Congratulations! Your repository is ready. Now you will have to modify the distributionManagement section of your pom.xml to let Maven deploy your artifacts to the new repository. Go back to your primary repository clone and edit your pom.xml:

<distributionManagement>
  <repository>
    <id>gh-pages</id>
    <url>file:///${basedir}/../jsf-maven-util-pages/repository/</url>
  </repository>
</distributionManagement>

Now you are ready to deploy your first artifact to the repository:

$ mvn -DperformRelease=true clean deploy

You will see that Maven copies the artifacts to your local checkout of the GitHub Pages branch. After Maven has finished you'll have to update the directory listings, commit the changes made to the repository and push them to GitHub:

$ cd ../jsf-maven-util-pages/
$ ./update-directory-index.sh
$ git add -A
$ git commit -m "Deployed my first artifact to GitHub"
$ git push origin gh-pages

Now let's check the result. Please note that the first publish may take some time to appear on the web server.

Looks great, doesn't it? :-)

If you want to use your repository in another project, just add the following repository entry to the pom.xml:

<repository>
  <id>jsf-maven-util-repo</id>
  <name>jsf-maven-util repository on GitHub</name>
  <url>http://chkal.github.com/jsf-maven-util/repository/</url>
</repository>

As you can see deploying Maven artifacts to GitHub is very simple. You can also use a similar approach to publish your Maven generated project site to GitHub. But that's a different story.... :-)