Publishing to GitHub Pages from Travis CI

11 July 2015 (updated 20 September 2018)

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