auto publish from Travis-CI


GitHub Pages is a convenient place to host OSS project docs.
This post explains how to use Travis CI to deploy your docs automatically on a pull request merge.

1. Generate a fresh RSA key in some directory

Make a directory outside of your project first.
Pick a key name deploy_yourproject_rsa, so you can distinguish it from other keys.

$ mkdir keys
$ cd keys
$ ssh-keygen -t rsa -b 4096 -C ""
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/xxx/.ssh/id_rsa): deploy_website_rsa
Enter passphrase (empty for no passphrase):

Keep the passphrase empty.

2. Switch to your website project

Move to your website project, start a branch on your project, and create .travis directory.

$ cd ../website
$ mkdir .travis

3. Install travis utility, and encrypt the private key

Run travis encrypt-file --repo foo/website ../website_keys/deploy_website_rsa .travis/deploy_rsa.enc where --repo foo/website represents your GitHub repo.

Note: If you don't specify --repo it will pick up on git origin, which for me often points to my private fork.

$ gem install travis
$ travis login --auto
$ travis encrypt-file --repo foo/website ../website_keys/deploy_website_rsa .travis/deploy_rsa.enc
encrypting ../keys/deploy_website_rsa for foo/website
storing result as .travis/deploy_rsa.enc
storing secure env variables for decryption
Please add the following to your build script (before_install stage in your .travis.yml, for instance):
    openssl aes-256-cbc -K $encrypted_1234_key -iv $encrypted_1234_iv -in .travis/deploy_rsa.enc -out ../website_keys/deploy_website_rsa -d
Pro Tip: You can add it automatically by running with --add.
Make sure to add .travis/deploy_rsa.enc to the git repository.
Make sure not to add ../website_keys/deploy_website_rsa to the git repository.
Commit all changes to your .travis.yml.

See Encrypting Files. Double check that your environmental variables are set correctly by going to the Travis Settings You should see the entries for the encrypted key and the initialization vector (iv).

4. Add

Add under .travis directory.

#!/bin/bash -ex
if [[ "${TRAVIS_PULL_REQUEST}" == "false" && "${TRAVIS_BRANCH}" == "master" && "${TRAVIS_REPO_SLUG}" == "foo/website" ]]; then
  openssl version
  echo -e "Host\n\tStrictHostKeyChecking no\nIdentityFile ~/.ssh/deploy_rsa\n" >> ~/.ssh/config
  openssl aes-256-cbc -K $encrypted_1234_key -iv $encrypted_1234_iv -in .travis/deploy_rsa.enc -out .travis/deploy_rsa -d
  chmod 600 .travis/deploy_rsa
  cp .travis/deploy_rsa ~/.ssh/
  sbt ghpagesPushSite
  • Replace "master" with your branch.
  • Replace "foo/website" with your repo.
  • Replace -K $encrypted_1234_key -iv $encrypted_1234_iv with your own.
$ chmod +x .travis/

This script was originally written by Yoshida-san. According to him, this was in turn based on GitHub push from Travis by eiel.

5. Edit .travis.yml

  - .travis/

6. Add public key to the GitHub pages repo

Go to the GitHub pages repo, Settings > Deploy keys, and add the content of your public key Name the entry as travis-ci-website or something along the line so you'll remember what it's for.

7. During syncLocal configure git

The following is specific to the behavior of sbt-ghpages. It might not be needed if you're doing something else.

  lazy val siteEmail = settingKey[String]("")
  val syncLocalImpl = Def.task {
    // sync the generated site
    val repo = ghkeys.updatedRepository.value
    val git = GitKeys.gitRunner.value
    val s = streams.value
    gitConfig(repo, siteEmail.value, git, s.log)
  def gitConfig(dir: File, email: String, git: GitRunner, log: Logger): Unit =
    sys.env.get("CI") match {
      case Some(_) =>
        git(("config" :: "" :: "Travis CI" :: Nil) :_*)(dir, log)
        git(("config" :: "" :: email :: Nil) :_*)(dir, log)
      case _           => ()

A note about Pamflet + Pandoc

Travis CI's rencent build environments allow the use of apt-get inside the container-based images, so now we can install latex-cjk-all and pandoc in addition to sbt.

Because Pamflet can generate a single-page markdown file per localized languages, I can not only automatically deploy the static HTML website, but also build PDF document both in English and Japanese from Travis CI.