Automated documentation hosting on github via Travis-CI

In this post, I’m going to cover how you can use continuous integration and source control to build and host documentation (or any other static HTML) for free, and in a way that updates every time your code changes. I’ll cover the generic capability, and then how I apply this to my simplest package, tfsR. In a later post (once I’ve cracked the best method to do it) I’ll cover my more complex use case of multiple documents and a dynamically constructed index page.

NB: This is kicked off from a post from Robert Flight about applying to the technique to R package vignettes. It’s a very useful post but it was quite specific to his situation and I wanted to understand the principles behind it before I started extending it to my more complex cases.

Posts in this series

  1. Automated documentation hosting on github via Travis-CI
  2. Auto-deploying documentation: multiple R vignettes
  3. Auto-deploying documentation: FASTER!
  4. Auto-deploying documentation: Rtraining
  5. Auto-deploying documentation: better change tracking of artefacts


  • Must haves:
    • Travis-CI
    • GitHub
  • Optional:
    • A linux machine (so you can test your bash script that Travis-CI will run)
    • R (for following the specific instructions)

High-level process

  • Get an OAUTH token from github
  • Add OAUTH token to travis
  • Add a *.sh file that gets your HTML (depending on circumstance, you may also need to generate it) and pushes to gh-pages branch
  • Include your .sh file in the after_success part of your travis file
  • Commit & push!

Detailed process

  • Get a token from github – use least privileges so only grant read/write access to public repos

github OAUTH permissions

github OAUTH permissions

  • Store the OAUTH token on travis with the name GH_TOKEN

    • I did this by using the environment variables for the repository (in the settings for the repository) as it had the least dependencies required to do and travis-ci will pick up anywhere I use GH_TOKEN in the build process without me having to add it to my .travis.yml file
    • You can alternatively use the travis CLI to pass the token to travis-ci, which’ll return an encrypted version that you can use in your travis.yml file

      [travis-ci addd an environment variable][9]
      travis-ci add an environment variable
  • Add a bash file that gets the HTML and pushes it to the repository. Robert’s bash script is a really good example of actual code so I only cover the concept here:

    • Create an empty directory you can work in
    • Create a git repository to hold all your HTML pages in
    • Commit all the HTML files (make sure there is one called index.html)
    • Push the repo into the gh-pages branch of your destination repo (which will be at http:://[GH_TOKEN][CONTAINER]/[REPO].git)
  • Add your bash file to the.travis.yml instructions / config file so that it’ll be taken into account on the next push

    Do this bit if you encrypted the string via CLI

    env: global:

    • secure: “travisCLIreturnedstring”

    Do this bit for every situation as it makes it executable and then executes it once the build passes - we don’t docs from bad builds afterall!

    before_install: - chmod 755 ./

    after_success: - ./

  • Commit the two (or potentially more if you need to add your bash file to build ignore files) files and then push the changes. Your next travis build should pick it all up and execute the bash file once the rest of the build has been a success

Putting it together – tfsR

I’ve been using Travis-CI for optiRum and tfsR for a while now. This has given me confidence in that my unit tests are run successfully, and records test coverage. What it didn’t do though was make my vignette or help documentation available – you had to read the un-rendered version of the vignette or download and compile. This wasn’t very accessible, especially for new people.

As this is my simplest package with only one vignette it seemed an ideal test case. To achieve the documentation building I amended or added three files, following Robert’s instructions for the most part:

[embedGitHubContent owner="stephlocke" repo="tfsR" path=""]


[embedGitHubContent owner="stephlocke" repo="tfsR" path=".travis.yml"]


[embedGitHubContent owner="stephlocke" repo="tfsR" path=".Rbuildignore"]

You can see the finished results at

Further reading