As you have learned in the first part, running middleman build will compile all files to the build folder. The generated files are completely static and can be run on any web server. While using a FTP client and manually uploading the files might sound like a easy and quick solution, it is not a very robust one.

In this part I am going to explain the deploy process I use for my own website.

Workflow

My workflow is simple:

  1. Commit my code changes, git commit.
  2. Push my commits to GitHub, git push.

When the code is pushed to GitHub, Codeship automatically gets notified via webhooks and triggers a new build. A set of predefined commands will run and if everything is successful, the new code gets deployed to a bucket on Amazon S3.

Codeship

Getting started with Codeship is easy. You log in with your GitHub account, select the repository containing your website and the webhook is automatically set up.

Go to Test and select I want to create my own custom commands instead of a technology stack. Specify the commands that Codeship will run.

Codeship test commands

Setup commands

These are my setup commands that runs before any tests:

# Use Ruby 2.2.0
rvm use 2.2.0

# Install dependencies specified in Gemfile
bundle install

Test commands

Since I want to keep my code clean, Codeship lints my SCSS files before deployment using SCSS-Lint. If no errors are found it starts testing my JavaScript code with Jasmine.

At last, it tries to build the site with middleman build.

# Run SCSS-lint
bundle exec scss-lint source/assets/stylesheets

# Run Jasmine tests
bundle exec rake jasmine:ci

# Compile the project
bundle exec middleman build

I also lint my SCSS/JS code during development with the Syntastic plugin for Vim. At the moment no JavaScript linter is run before deploys since I am planning to replace JSHint with ESLint.

Deploy to Amazon S3

When your code is linted, tested and compiled it is time to deploy it to Amazon S3. I use a great extension called middleman-s3_sync that syncs the build folder to any bucket on Amazon S3. It determines which files need to be updated, added or deleted and only transfers what is necessary.

To use it, add this line to your Gemfile:

gem 'middleman-s3_sync'

The extension has a lot of settings, but for me most of the defaults are fine. In my config.rb:

activate :s3_sync do |s3_sync|
  s3_sync.bucket = 'richardkall.se'
  s3_sync.region = 'eu-west-1'
end

default_caching_policy max_age: (60 * 60 * 24 * 365)
caching_policy 'application/xml',
  public: true,
  max_age: 0,
  must_revalidate: true
caching_policy 'text/html',
  public: true,
  max_age: 0,
  must_revalidate: true

Here I specify my S3 bucket and region, along with some caching policies. Asset files are cached for one year, which is possible thanks to the asset_hash setting. I will not cover how to create a S3 bucket in this guide, read the AWS documentation instead.

Go back to Codeship, click on Environment under Project Settings and enter your AWS credentials.

Codeship environment variables

Almost finished. Now all we need to do is to tell Codeship to run middleman s3_sync as our deployment command. Click on Deployment and choose Custom Script. Add the following line and save:

bundle exec middleman s3_sync

Codeship deployment commands

The next time you push changes to your GitHub repo your website will be automatically deployed!