Automatically Publish Javadoc to GitHub Pages with Travis CI

Posted on

I hate doing the same thing more than once. Like, a lot. The more things that are automated, better.

With our recent project, swt-bling, I’ve informally taken on a lot of the build and deployment tasks. My goal with this OSS project is to make it as sustainable and attractive for others to use as possible. Thus, documentation is a must.

We’re already using Travis CI to automatically run our unit and integration tests, build our jars and deploy SNAPSHOTs out to Sonatype.

After lots of searching around, I ended up having a hard time finding one definitive source of how to accomplish this with Travis CI. So, here’s how you do it.

How to Do It

  1. Setup GitHub Pages if you haven’t already. This will create a gh-pages branch on your GitHub project. Checking out and automatically committing and pushing to this branch is how this little trick works.

  2. Setup Travis CI if you haven’t already. Travis is neat. In most use cases, it just works with your build system. It also has the ability to encrypt ‘secret’ data (in our case, the token to allow Travis to push to our gh-pages branch).

  3. Create a GitHub Access Token for Travis. As I mentioned, this will allow Travis to push to our gh-pages branch. Make sure the token is set to have the repo scope, otherwise you will get “permission denied” errors on push.
    GitHub Create New Personal Access Token
  4. Encrypt your access token. You’ll need to install the Travis gem with gem install travis. Then you’ll run

     travis encrypt GH_TOKEN=your token from step 4

    Don’t forget to place this in your .travis.yml configuration in your repo in a secure block.

  5. Create a script that you’ll have Travis run. On swt-bling, I created a .utility folder in the root of the repo that contains our Travis shell scripts. You can start off with ours as a sample. I’ll explain the script below, if you’re craving more details.

  6. Tell Travis to run your script. In your .travis.yml file, you’ll tell Travis to run your script after a successful build. For instance on swt-bling we have

    after_success: - .utility/
  7. That’s it! That should get you going with automatic publishes!

Script Explanation

I’ll take a second to explain how we’ve come to the script we’re using today. There was a lot of trial and error with this particular script, so I’ll go through it for clarity.

The Big-Ol’ Conditional

If you tell Travis to publish after_success, it will run on a ton of builds you don’t want Javadoc published for. So, for our purposes, we define a number of prerequisites to publish.

[ "$TRAVIS_REPO_SLUG" == "ReadyTalk/swt-bling" ]

  1. We want this to only happen from our repo, not forks. Since people will clone this script when they fork the repo, we don’t want them to be able to publish Javadoc if they set up Travis. Luckily, our secret GH_TOKEN variable will not work for their fork, but we might as well bail from the script if it’s not our repo.

[ "$TRAVIS_JDK_VERSION" == "oraclejdk7" ]

  1. swt-bling is built against OpenJDK 6 and Oracle JDK 7. JDK 6 has pretty old-school looking documentation, so we specify that we only want Javadoc built by JDK 7 to be pushed out.

[ "$TRAVIS_PULL_REQUEST" == "false" ]

  1. Building pull requests is pretty awesome, we want to make sure that people have pushed solid code before we merge it in. However, we don’t want documentation to be published until we merge it.

[ "$TRAVIS_BRANCH" == "master" ]

  1. If it’s merged to master, we want to publish Javadoc for it.

The Meat of the Script

# Get to the Travis build directory, configure git and clone the repo
cd $HOME
git config --global ""
git config --global "travis-ci"
git clone --quiet --branch=gh-pages https://${GH_TOKEN} gh-pages > /dev/null

# Commit and Push the Changes
cd gh-pages
git rm -rf ./javadoc
cp -Rf $HOME/javadoc-latest ./javadoc
git add -f .
git commit -m "Lastest javadoc on successful travis build $TRAVIS_BUILD_NUMBER auto-pushed to gh-pages"
git push -fq origin gh-pages > /dev/null

And that will do it! It’s pretty straightforward, but hopefully this helps out. Happy publishing!

Find an issue?
Open a pull request against my blog on GitHub.
Ben Limmer