When hosting a project on GitHub, it's likely you'll want to use GitHub Pages to host a public web site with examples, instructions, etc. If you're not using a continuous integration service like Travis, keeping your gh-pages site up to date requires continuous wrangling.
The steps below outline how to use Travis CI with GitHub Releases and GitHub Pages to create a "1-button" deployment workflow. After testing and running a release build, Travis will upload your release assets to GitHub. It will also push a new version of your public facing site to GitHub Pages.
Let's assume you are hosting a JavaScript project that will offer a single JavaScript file as a release asset. It's likely you'll organize your files like this.
myproject/
.gitignore
app.js
package.json
README.md
Gruntfile.js
.travis.yml
deploy-gh-pages.sh
node_modules/
src/
apple.js
orange.js
test/
apple.js
orange.js
public/
css/
scripts/
index.html
Let's assume app.js exposes a global variable as the entry point for our library. Also assume our Gruntfile defines a build process that concatenates the modules in src/ as well as app.js and places a minified js file in a new folder called release/.
We want Travis to upload the minified js file to our release on Gitub as well as push the contents of public/ to gh-pages.
If you haven't already, login to Travis CI and enable your repo. You can also enable it via the CLI.
travis enable
You'll need to add a .travis.yml file to the root of your project with at least the following.
language: node_js
node_js:
- '0.10'
To upload your minified release file to GitHub Releases, following the Travis instructions for updating your .travis.yml file. It's highly recommended to use the travis cli.
travis setup releases
To set up npm publishing with your builds, use the CLI.
travis setup npm
If you run these back to back, you'll like get an error like, "deploy section already exists in .travis.yml, run with --force to override". You may need to take a few steps to combine the output (ie. cut the first deploy setup and paste back in after the second).
You need to supply GH_REF (path to your repo) and GH_TOKEN (OAUTH TOKEN) environment variables so the gh-pages deploy script (more on that below) can push a gh-pages branch to the repo. Your GH_TOKEN variable should be encrypted. Since keys used for encryption and decryption are tied to the repository, you'll need to encrypt a token for each repo.
You can generate a GitHub personal access token from AccountSettings -> Applications -> Click 'Generate New Token'. The token will only be visible until you leave the page. Copy it and encrypt it using travis encrypt.
travis encrypt GH_TOKEN=yourpersonalaccesstoken --add
You can read about encrypting values using 'travis encrypt'.
Once done, your file should look like this.
language: node_js
node_js:
- '0.10'
env:
global:
- GH_REF: "PATH TO YOUR REPO (github.com/username/repo)"
- secure: "GITHUB PERSONAL ACCESS TOKEN"
before_install:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
- npm install -g grunt-cli
after_success: grunt release
before_deploy: "echo 'ready to deploy?'"
- provider: releases
api_key:
secure: "GITHUB PERSONAL ACCESS TOKEN"
file: "FILE(S) TO UPLOAD"
on:
repo: <github-username/repo>
tags: true
all_branches: true
- provider: npm
email: <your npm email>
api_key:
secure: "ENCRYPTED NPM API KEY"
on:
tags: true
all_branches: true
repo: <github-username/repo>
after_deploy:
- "echo 'deployed!'"
- ./deploy-gh-pages.sh
The deploy-gh-pages.sh command in the after_deploy section of .travis.yml runs the following.
#!/bin/bash
rm -rf out || exit 0;
mkdir out;
echo "starting deploy..."
( cd out
git init
git config user.name ${GIT_NAME}
git config user.email ${GIT_EMAIL}
cp -r ../public/* ./
cp ../release/myproject.min.js ./scripts/myproject.min.js
git add .
git commit -m "Deployed to Github Pages"
git push --force --quiet "https://${GH_TOKEN}@${GH_REF}" master:gh-pages > /dev/null 2>&1
)
The commands create a new repo in an 'out' folder and copy the minified release file to the scripts folder. Finally, the files are committed and forced pushed to the gh-pages branch.