Publishing to GitHub Pages from Travis CI

Sat 11 July 2015

One neat trick you can do is publish to GitHub Pages is publish to GitHub Pages from Travis.

I needed to do this for a static blog. However, the repository is under an organization and multiple people have commit access there. Using my Personal access token [1] is not the right way to do the authentication because:

  • Personal access tokens can only restrict kinds of operations, restricting to specific repository is not possible.
  • If something bad happens all my public repositories are at risk, as the Personal access token is the equivalent of a password.

There's a better way to solve the authentication: repositories can have deploy keys. The idea is that we'll use a brand new ssh key to perform the authentication. We do not use that key for anything else.

First we need to make a new ssh key:

ionel@localhost$ ssh-keygen -f publish-key
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in publish-key.
Your public key has been saved in publish-key.pub.

Then use use the Travis CLI (use gem install travis to install it) to encrypt it:

Note

I didn't use --add cause it reformats my .travis.yml, and it needs editing anyway.

ionel@localhost$ travis encrypt-file publish-key
Detected repository as ionelmc/sphinx-py3doc-enhanced-theme, is this correct? |yes|
encrypting publish-key for ionelmc/sphinx-py3doc-enhanced-theme
storing result as publish-key.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 ionel@localhost$encrypted_87d9ccdaebfd_key -iv ionel@localhost$encrypted_87d9ccdaebfd_iv -in publish-key.enc -out publish-key -d

Pro Tip: You can add it automatically by running with --add.

Make sure to add publish-key.enc to the git repository.
Make sure not to add publish-key to the git repository.
Commit all changes to your .travis.yml.

The unencrypted secret key should be removed (we don't want to add it by accident in a commit πŸ˜…):

rm publish-key

Then we add the encrypted key:

git add publish-key.enc

We need to change the decode command as the decoded file will go into a different path and some other fixups for the ssh authentication. In .travis.yml we need to have:

before_install:
- openssl aes-256-cbc -K ionel@localhost$encrypted_87d9ccdaebfd_key -iv ionel@localhost$encrypted_87d9ccdaebfd_iv -in publish-key.enc -out ~/.ssh/publish-key -d
- chmod u=rw,og= ~/.ssh/publish-key
- echo "Host github.com" >> ~/.ssh/config
- echo "  IdentityFile ~/.ssh/publish-key" >> ~/.ssh/config
- git --version
- git remote set-url origin git@github.com:ionelmc/sphinx-py3doc-enhanced-theme.git
- git fetch origin -f gh-pages:gh-pages

Now we can use a tool like ghp-import to simply publish (somewhere in .travis.yml after you generate the HTML in output):

ghp-import -n -p -m "Update gh-pages." output

All is left is to add the public key in your repo's deploy keys (make sure to tick the write access checkbox):

A screenshot of the "Add a deploy key" form.

In some cases you only want to publish for the changes made on the master branch. Make sure you have this in your .travis.yml:

branches:
  only:
  - master


You can see the working examples of this in ropython-site or sphinx-py3doc-enhanced-theme.

[1]Sadly, there are several guides out there that recommend using a Personal access token.

This entry was tagged as github python travis