This guide walks you through the steps of publishing a website that is built using Awestruct to GitHub Pages from Travis CI, automatically!

In this guide, you’ll learn:

  • How to setup a git repository for your website and share it on GitHub

  • How to add a branch to your repository that gets deployed to GitHub Pages

  • How to publish your website to GitHub pages using the Awestruct deployer

  • How to activate Travis CI on your repository

  • How to configure Travis CI to publish your website automatically

After reading this guide, you’ll be able to make a change to your website source, commit it and push it to your GitHub repository. Then, just a few minutes later, the change will automatically appear on your website!

You’ll soon discover that publishing a website has never been so easy!

Note
Throughout this tutorial, replace <username> with your GitHub username and demosite with the name of your website repository.
Note
A code block that begin with $ indicates a command that you should type in your terminal. When you type the command, don’t include the $ prefix.

We’ll assume that you’ve already setup an Awestruct-based website on your computer. If not, follow the Getting Started guide on the Awestruct website to quickly get one setup. Once you have an Awestruct website ready, we’ll begin by turning the project into a git repository and sharing it on GitHub.

Git setup

Open a terminal and switch to the directory containing your Awestruct project.

$ cd demosite

Next, initialize a git repository by typing the following git command:

$ git init

Your project is now a git repository. It doesn’t have any files or history, though, so we’ll need to add some. Before we do that, let’s first tell git and Awestruct what files to ignore.

Ignore files

Ignore files are used to tell version control systems and build tools which files to ignore. When Awestruct runs, it generates some temporary files and directories that we don’t want git to manage. Let’s add the names of those files and directories to git’s ignore file, .gitignore:

$ cat > .gitignore << LINES
/.awestruct/
/.bundle/
/.sass-cache/
/_site/
/_tmp/
/Gemfile.lock
LINES

There are also some files in the project (or will be) used to launch Awestruct that we don’t want Awestruct to put into the website it generates. Let’s add the names of those files to Awestruct’s ignore file, .awestruct_ignore:

$ cat > .awestruct_ignore << LINES
Gemfile
Gemfile.lock
Rakefile
vendor
LINES

Since you’re deploying to GitHub Pages, you should be aware that Jekyll normally run on the files on the publish branch. The our site is pre-built by Awestruct, we don’t need Jekyll and, besides, it would slow down the publishing step. Fortunately, Jekyll can be disabled by including an empty .nojekyll file in the project. Create the file using this command:

$ touch .nojekyll

Now all that should be ignore is being ignored, let’s move on to adding the remaining files to the git repository.

Initial source import

We’ll now do an initial import of files. Add all non-ignored files to the git repository using this command:

$ git add .

Next, commit the files, recording it as an initial import:

$ git commit -m "Initial import of website sources"

By default, the files get added to the master branch. Keep in mind, we’ll be storing both the source and published files in the same repository. In one case, the master branch is reserved for the published files. Therefore, we’ll follow the convention to use a different name for the branch holding the source files.

Rename the current branch to develop:

$ git branch -m master develop

The branch for the source files has been created. Now let’s create the branch for the published files.

The “publish” branch

GitHub Pages monitors the publish branch of your website repository and synchronizes the files in that branch to a web server whenever new commits appear.

In most cases, the name of this branch is gh-pages. For legacy reasons, if the name of the repository follows the pattern <username>.github.io, then the name of the publish branch is master. Thus, the pattern is:

Table 1. Name of publish branch
Repository name Branch name

<username>.github.io

master

any other name

gh-pages

Since the name of our repository is demosite, we’ll be using the gh-pages branch as the publish branch.

Creating the “publish” branch

The source branch and the publish branch are going to hold different sets of files that don’t share a common history. Therefore, when we want create the publish branch, we want to make it an orphaned branch, which gives it its own history.

Create the gh-pages branch as an orphan using the following checkout command:

$ git checkout --orphan gh-pages

The history from the develop branch is not transfered to this branch, but we need to cleanup the files that are now lying around. Execute these commands to wipe the slate clean:

$ rm -rf *
$ rm -rf .awestruct* .sass-cache .gitignore
$ git rm --cached *

If you type ls, you should see that the project is now clean. Don’t worry, the project files are stored safely in the develop branch. You can confirm they are still there using git’s ls-tree command:

$ git ls-tree --name-only develop

Let’s commit these changes:

$ git add --all .
$ git commit -m "clean publish branch"

To wrap-up the creation of the publish branch, let’s give it a stub history:

$ echo "GitHub Pages placeholder" > index.html
$ git add index.html
$ git commit -m "Seed publish branch for GitHub Pages"

By running git’s ls-tree command, you can see that there are two files in the repository:

$ git ls-tree --name-only gh-pages

Your output should look like this:

.nojekyll
.index.html

The source (develop) and publish (gh-pages) branches are all setup. You’re now ready to publish the repository to GitHub and put GitHub Pages into action.

GitHub push

To publish the repository to GitHub, you first need to create a place to push the files.

  1. Sign in to GitHub

  2. Click the "Create a new repo" button.

    Tip
    You can go directly to https://github.com/new if you can’t find the button.
  3. Enter the following information into the form:

    Owner

    <username>

    Repository name

    demosite

    Description (optional)

    An Awestruct demo site

  4. Finally, click the "Create repository" button.

You will be presented with instructions about how to push files to the repository. Since we already have a git repository to push, we are interested in the box label: Push an existing repository from the command line.

Add the link to the remote repository on GitHub:

$ git remote add origin git@github.com:<username>/demosite.git

Make sure you’re on your local develop branch:

$ git checkout develop

Then, push the develop branch to the remote repository:

$ git push -u origin develop

Also push the gh-pages branch:

$ git checkout gh-pages
$ git push -u origin gh-pages

By pushing the gh-pages branch, you also activated GitHub Pages to publish your website. Check it out! (It could take up to ten minutes for changes to be updated)

http://<username>.github.io/demosite

You should see the contents of the index page that you created when you setup the gh-pages branch.

Where’s the Awestruct site?

Ah, that’s where the Awestruct deployer comes in. We still need to do a little bit of work.

Awestruct deployer

We’ll now setup Awestruct to publish the generated website to the gh-pages branch, which will subsequently be deployed to the web server by GitHub Pages.

We need to tell Awestruct how to publish the site. For that, we’ll use a configuration profile.

Switch to the develop branch:

$ git checkout develop

Next, add the following content to the bottom of the _config/site.yml file:

profiles:
  production:
    base_url: http://<username>.github.io/demosite
    deploy:
      host: github_pages
      # use gh-branch for repositories other than <username>.github.io
      branch: gh-pages
      # use master branch for <username>.github.io repository
      #branch: master

The host property controls which Awestruct deployer is used. The value github_pages is a special token that tells Awestruct it’s working with a website deployed to GitHub Pages.

Commit your changes and push them to the remote repository:

$ git add _config/site.yml
$ git commit -m "Add profile for production deployment"
$ git push origin develop

Now you can tell Awestruct to build and publish your site:

$ awestruct -P production -g --deploy

Once that command completes successfully, check out your site again.

http://<username>.github.io/demosite

Your Awestruct-based website is now live, and available worldwide!

Of course, your first thought might be, "Yikes, that’s a generic site. I want to customize it."

Let’s discuss changes.

Manual publish workflow

Making a change to the website and publishing it is easy. You just need to edit the file, commit it and run Awestruct again.

Let’s walk through the process. Say you want to change the title on the site.

  1. Open up the _layouts/base.html.haml file in your editor.

This is no longer true. Project name is set in the site.yml . Find the words "Built on Foundation. Baked by Awestruct." and replace them with "Built by <username>"

  1. Save the file

  2. Add the changed file to git

    $ git add _layouts/base.html.haml
  3. Commit the change, leaving a description of what you changed

    $ git commit -m "Change built by to username"
  4. Push the change to the remote repository

    $ git push origin develop
  5. Generate and publish the site using Awestruct

    $ awestruct -P production -g --deploy

Wait for the command to finish (a moment or two longer), then view your website again to see the change (It can take up to ten minutes to display).

That’s the basic workflow for changing the site. But there’s certain room for automation. Let’s see how to use a continous integration (CI) server to automate the build and publish step.

Automated publishing using Travis CI

Travis is a sleek continuous integration (CI) server that’s tightly integrated with GitHub. Like GitHub, it’s a hosted service so you don’t have to worry about setting anything up. All you need to do is sign in using your GitHub account.

Once you’ve signed in, hover over your name and click on the "Accounts" link, which will take you to your profile. Scroll down to the <username>/demosite repository and click the radio button from Off to On.

Note
If you don’t see your repository, you need to click the "Sync now" button.

Travis is now ready and waiting for instructions about how to build your project. Let’s give it the details.

Travis build configuration

You control Travis from a configuration file in the root of your project named .travis.yml. This file puts a wealth of automation at your fingertips. We’re only going to tap into a small part of it.

Create the file .travis.yml and populate it with the following configuration:

travis.yml
language: ruby
rvm:
- 1.9.3
branches:
  only:
  - develop
script: rake travis

This configuration tells Travis the following things:

  • Our project has a Ruby build

  • We want to use Ruby 1.9.3

  • We only want to build the develop branch

  • We want to run the command rake travis

Travis will setup the appropriate Ruby environment, checkout the repository and run the requested command. So what does rake travis do? We need to define it.

A rake for Travis

We’re going to use Rake to bundle up the commands we want Travis to execute. Rake (Ruby Make) is a build tool for Ruby projects.

Here are the steps we want this travis task to perform (above setting up the Ruby environment and cloning the repository):

If triggered by a pull request
  • Build the site with Awestruct and exit

If triggered by a commit
  • Configure git to be able to push to the remote repository

  • Setup the git credentials to allow a commit to be pushed

  • Run Awestruct to generate and publish the site to the publish branch

Here’s the Rake build file, Rakefile, that defines the travis task:

Rakefile
require 'rubygems'

desc 'Generate site from Travis CI and publish site to GitHub Pages'
task :travis do
  # if this is a pull request, do a simple build of the site and stop
  if ENV['TRAVIS_PULL_REQUEST'].to_s.to_i > 0
    puts 'Pull request detected. Executing build only.'
    system 'bundle exec awestruct -P production -g'
    next
  end

  repo = %x(git config remote.origin.url).gsub(/^git:/, 'https:')
  deploy_branch = 'gh-pages'
  if repo.match(/github\.com\.git$/)
    deploy_branch = 'master'
  end
  system "git remote set-url --push origin #{repo}"
  system "git remote set-branches --add origin #{deploy_branch}"
  system 'git fetch -q'
  system "git config user.name '#{ENV['GIT_NAME']}'"
  system "git config user.email '#{ENV['GIT_EMAIL']}'"
  system 'git config credential.helper "store --file=.git/credentials"'
  File.open('.git/credentials', 'w') do |f|
    f.write("https://#{ENV['GH_TOKEN']}:x-oauth-basic@github.com")
  end
  system "git branch #{deploy_branch} origin/#{deploy_branch}"
  system 'bundle exec awestruct -P production -g --deploy'
  File.delete '.git/credentials'
end

Don’t let that script scare you. Most of the code involves configuring git so that Awestruct can commit and push the changes to the publish branch, using the HTTPS protocol along with a token-based authentication. In the future, this may get rolled into the Awestruct deployer.

GitHub commits from Travis

You’ll notice references to three environment variables in the travis task:

  • GIT_NAME

  • GIT_EMAIL

  • GH_TOKEN

This is crucial information for this process to work, but also sensitive. That’s why Travis provides a way to encrypt this data so that it can be safely stored in your git repository. Once you encrypt the information, it won’t be visible anywhere except on Travis during the build.

Before we encrypt, we need to get a new authentication token from GitHub. An authentication token allows a script to have the permission to push changes to your repository using the HTTPS protocol, instead of using the ssh protocol which would require you to deploy your private key on Travis.

The following curl command will send an OAuth token creation request on github:

$ curl -u <username> \
  -d '{"scopes":["public_repo"],"note":"CI: demosite"}' \
  https://api.github.com/authorizations

Enter your GitHub password at the prompt. In the output, you’ll see a token property. Save that value.

(If you have two factor authentication enabled on GitHub, it is easier to go to your settings page and generate a new OAuth token there.)

Next, install the travis gem:

$ gem install travis

The Travis gem provides the travis command. Use the travis command to encrypt the three environment variables listed above. Replace <token> with your GitHub authentication token:

$ travis encrypt GIT_NAME=<Your_Name> --add
$ travis encrypt GIT_EMAIL=<Your_Email> --add
$ travis encrypt GH_TOKEN=<token> --add

Each call to the encrypt command will output a long string that looks like:

secure: ABC123ABC123ABC123ABC123ABC123ABC123ABC123ABC123ABC123...

directly into the .travis.yml file under the env / global node.

env:
  global:
  - secure: "<encrypted string for the github user name>"
  - secure: "<encrypted string for the github user email>"
  - secure: "<encrypted string for the github user token>"

Each secure string contains one of the environment variable encrypted using Travis' public key. It can only be unencrypted by Travis' private key (secured in some vault, somewhere).

That defines the secure environment variables, which Travis will decrypt at the start of the build, so that they can be used by the build task (in our case, rake travis).

All that’s left is to commit your changes, push them to GitHub and let Travis work it’s magic.

$ git add .
$ git commit -m "Configure Travis to build and publish site"
$ git push origin develop

You’ll have to wait a little longer this time before viewing the site. It takes a few minutes for your build to make it it to the top of the queue and for Travis to setup the build environment. Aside from the extra steps, Travis is effectively running the command you previously had to run manually:

$ awestruct -P production -g --deploy

Now, to make changes to your site, you just have to push to the develop branch, then sit back and wait!

Revise in the browser

Now that you have Travis CI monitoring your repository for commits, you don’t even need to use git to make changes to your site. You can use GitHub’s in-browser editor to edit and commit files.

Navigate to your repository at GitHub in your browser. Select one of the files in your repository, perhaps a blog entry. Then click the "Edit" button and type away. You can even go into full-screen mode by clicking the box in the lower right-hand corner of the editor. How zen.

When you are done editing, just click "Commit Changes", entring an optional message if you choose. Once again, sit back and wait. Those changes are headed to your website!

Not only can you edit files in the browser, you can also create new ones. That means you can create and publish blog entries directly from the GitHub website using this setup!

Gotchas

  • The GitHub Pages deployer in Awestruct only adds files to deployment, does not compute removed files

Summary

In this tutorial, you learned how to get Travis CI to do the work of deploying your site as soon as you push to the develop branch. In fact, you can create and edit files directly in the browser!

To begin, you took one of your Awestruct sites and turned it into a git repository. Then, you created an orphan gh-pages branch to hold the production version of the site. Once both branches were setup correctly, you pushed them to GitHub. Next, you configured Awestruct to use the GitHub Pages deployer to build and publish the site to that branch. Finally, you configured Travis to watch for changes and run the Awestruct deployer with the git credentials and GitHub token you passed to it securely.

You are blogging like a hacker now!