Semaphore Blog

News and updates from your friendly continuous integration and deployment service.

Continuous delivery via Cloud66

Get future posts like this one in your inbox.

Follow us on

Today we’re very happy to announce our partnership with Cloud 66. Cloud 66 makes it easy to provision, deploy and manage Ruby on Rails applications on major cloud providers.

The integration makes it very easy to have a full continuous delivery pipeline: from pushing to GitHub to testing on Semaphore, and if with all tests passing, deploying to all your servers via Cloud 66.

To get started, head over to the Deployment tab in project settings to add a new server, and select Cloud 66. The seamless integration only requires you to authorize Semaphore with your Cloud 66 account. We assume that you have an application stack ready on Cloud 66, which is the next thing to select in the configuration wizard.

Semaphore and Cloud 66 integration

If you select automatic deployment, Semaphore will send a redeploy request to Cloud 66 whenever your build passes on the corresponding branch. With manual deployment, you choose when to click and launch a redeploy. Note that while Semaphore tracks every deploy in the project timeline, it sends a blank request to Cloud66 to perform the actual deployment work.

Happy deliveries!

Multi-deployment approaches

Capistrano is a great tool for remote server automation and deployment. The standard practice is to have a single Capistrano setup per application, but if you are working on a complex project that consists of several applications or services, managing deployment configuration can become a daunting task.

There are two approaches for tackling deployment of larger projects with multiple applications.

Decentralized multi-deployment approach

This happens by default. With decentralized multi-deployment approach the deployment configuration is located in each application.

~/projects/my-app/my-app-base$ cap production deploy

~/projects/my-app/my-app-billing$ cap production deploy

~/projects/my-app/my-app-importer$ cap production deploy

Drawbacks:

  • No separation of concerns: application code is mixed with deployment code.
  • Duplication of code: code is duplicated across applications.
  • Difficult workflow: multiple directories require more effort to navigate etc.

Centralized multi-deployment approach

With centralized multi-deployment approach the deployment configuration for each application is located in a single repository.

~/projects/my-app-deployment$ cap base:production deploy

~/projects/my-app-deployment$ cap billing:production deploy

~/projects/my-app-deployment$ cap importer:production deploy

Advantages:

  • Separation of concerns: deployment code is located in a single dedicated repository, separate from application code.
  • DRY: configuration can be shared between applications.
  • Increased security: ability to restrict deployment access to authorized team members.

Drawbacks:

  • Having the deployment script outside application code makes continuous delivery a bit more difficult to set up.

CapHub

CapHub is a tool which can help you set up a central deployment repository by generating a Capistrano skeleton suited for deploying to multiple applications.

$ gem install caphub
$ caphub my-app-deployment
$ tree --dirsfirst my-app-deployment my-app-deployment
├── config
│ ├── deploy
│ └── deploy.rb
├── recipes
├── Capfile
├── Gemfile
└── Gemfile.lock

Using centralized deployment on Semaphore

When adding a new server on Semaphore, select deployment option “Using a deploy script” and adapt the following deploy commands:

echo {SERVER_PUBLIC_KEY} >> ~/.ssh/known_hosts

cd /tmp

git clone https://{GITHUB_TOKEN}:x-oauth-basic@github.com/my-company/my-app-deployment.git

cd ./my-app-deployment
bundle install --path vendor/bundle
bundle exec cap base:production deploy:migrations

What we are doing here is pulling and initializing the central deployment repository before calling the deploy task. More information on the GITHUB_TOKEN mentioned above can be found on our documentation site.

Semaphore partners with Code Climate to provide test coverage service

At Semaphore, we want to empower great teams to test and deliver high quality apps. Besides providing top-notch build and deployment services, enabling our customers to get more insights from their test suite is a big part of that. Today we’re proud to announce that Semaphore has partnered with Code Climate to provide test coverage services for Ruby applications.

Working smartly with application and test code determines the team’s ability to ship at a sustainable pace. You need to make sure that your tests exercise enough of your application code. How do you find out which areas of your app are both low quality and untested? Code-to-test ratio is irrelevant if there are many tests for unimportant code or dead code without tests.

After a very quick setup process, your builds on Semaphore will enable Code Climate to surface test coverage information at the repository, class, and source listing level (down to an individual line of code) and provide feedback as metrics change over time in the form of email alerts, activity feeds, chat notifications and RSS.

How it works

Code Climate accepts coverage data sent from Semaphore as it runs your tests. There is a codeclimate-test-reporter RubyGem that you install into your Gemfile. When the build is finished, the gem sends an HTTPS post to Code Climate with a report on which lines of code were executed.

To make that happen, head over to the Integrations screen in your project’s settings. Code Climate has generously agreed to offer Semaphore customers 20% off their first three months.

We are very much looking forward to seeing how your code gets even better with these new features.

Improved repository caching

Over the past week we rolled out an update to our repository caching system. Previously cache was branch based, and all users suffered one disadvantage: first builds of every new branch took more time as the git clone and bundle install had to be done from scratch.

A brief overview of how repository caching works

Our build platform is powered by dedicated hardware and all build servers maintain a cache of repositories they have worked with. The build scheduler tries to assign a job to an available build server which has worked with a given branch before.

Source code is then taken from the cache, advanced to the revision specified by the build and moved to a virtual machine where the actual build or deploy is performed. When it reaches a certain usage quota, cache frees up disk space by removing repositories by iterating through oldest first.

Repository caching is now global

From now on repositories are cached globally and all branches use the same source. One immediate effect is that the cache lives longer. It also uses less disk space, so a build server can accomodate more projects, resulting in overall fewer cache misses as one project can easily be cached on many servers.

So instead of 100% of all first builds of a branch doing a full git clone and bundle install, that number is now down to about 50%. As most teams work in a workflow with feature branches, this results in reduced build times on many projects. The same applies to deploys as well. Of course, we’ll continue to work on improving the platform further.

Setting up the BDD stack on a new Rails 4 application

Note: An updated version of the tutorial is available at Semaphore Community.

Semaphore has been, and continues to be, developed using the behavior-driven development process. In this post, I will take you through the steps needed to set up our prefered BDD stack on a new Rails 4 application and explain why each tool is important.

Create the application

$ rails new myapp

Install RSpec

We prefer RSpec to other testing frameworks since we find it more natural and expressive. For example, I never find myself using the word “assert” in everyday talk, while I use the word “should” regularly. Also, RSpec’s language for writing tests and output is very readable and can serve as documentation.

Add rspec-rails gem to the development and test groups of your Gemfile.

group :development, :test do
  gem 'rspec-rails', '~> 2.0'
end

Install the gem:

$ bundle install

Bootstrap the app with RSpec:

$ rails generate rspec:install

Create the RSpec binstub. In short, the binstub will allow you to run RSpec with bin/rspec instead of bundle exec rspec:

$ bundle binstubs rspec-core

Install shoulda-matchers

shoulda-matchers lets us spec common Rails functionality, like validations and associations, with less code.

Add shoulda-matchers gem to the test group of your Gemfile:

group :test do
  gem 'shoulda-matchers'
end

Install the gem:

$ bundle install

Let’s take a look at a simple validation spec.

If you are validating the presence of post’s title:

class Post < ActiveRecord::Base
  validates :title, presence: true
end

without shoulda-matchers the spec might look something like the following:

require 'spec_helper'

describe Post do

  describe "title validation" do

    context "title is present" do

      before(:each) do
        @post = Post.new(title: "My first post")
      end

      it "does not add an error on the 'title' attribute" do
        @post.should have(0).error_on(:title)
      end

    end

    context "title is not present" do

      before(:each) do
        @post = Post.new
      end

      it "adds an error on the 'title' attribute" do
        @post.should have(1).error_on(:title)
      end

    end

  end

end

and with shoulda-matchers:

require 'spec_helper'

describe Post do
  it { should validate_presence_of(:title) }
end

Install Factory Girl

Factory Girl is “a library for setting up Ruby objects as test data” or more precisely it is a fixtures replacement.

Add factory_girl_rails gem to the development and test groups of your Gemfile:

group :development, :test do
  gem 'rspec-rails', '~> 2.0'
  gem 'factory_girl_rails'
end

Install the gem:

$ bundle install

Basically, Factory Girl will allow you to create objects that you need in your tests without providing a value for each required attribute. If you don’t provide a value for a required attribute Factory Girl will use a default value that you defined in factory’s definition.

Factory Girl also has a more pleasant system for defining record associations than when using fixtures.

Let’s define a post factory:

FactoryGirl.define do
  factory :post do
    title "My first post"
    content "Hello, behavior-driven development world!"
  end
end

Now, if both the title and content attributes are required to create a valid post, instead of writing in our spec something like the following:

require 'spec_helper'

describe Post do

  describe "creation" do

    context "valid attributes" do

      it "should be valid" do
        post = Post.new(title: "My first post", content: "Hello, behavior-driven development world!")

        post.should be_valid
      end

    end

    context "invalid attributes" do

      it "should not be valid" do
        post = Post.new(title: "My first post", content: "")

        post.should_not be_valid
      end

    end

  end

end

you can just write:

require 'spec_helper'

describe Post do

  describe "creation" do

    context "valid attributes" do

      it "should be valid" do
        post = FactoryGirl.build(:post)

        post.should be_valid
      end

    end

    context "invalid attributes" do

      it "should not be valid" do
        post = FactoryGirl.build(:post, title: "")

        post.should_not be_valid
      end

    end

  end

end

Make sure everything is connected and working

Create a Post model:

$ rails generate model Post title:string content:text

      invoke  active_record
      create    db/migrate/20130726125040_create_posts.rb
      create    app/models/post.rb
      invoke    rspec
      create      spec/models/post_spec.rb
      invoke      factory_girl
      create        spec/factories/posts.rb

Notice, the generator now also creates a model spec and a ‘posts’ factory. That’s the reason why we included the rspec-rails and factory_girl_rails gems in the development group of the Gemfile.

Update the spec to validate post’s title and content:

require 'spec_helper'

describe Post do

  it { should validate_presence_of(:title) }
  it { should ensure_length_of(:title).is_at_least(5) }
  it { should validate_presence_of(:content) }
  it { should ensure_length_of(:content).is_at_least(10) }

end

And update the Post model with validation definitions:

class Post < ActiveRecord::Base

  validates :title, presence: true, length: { minimum: 5  }
  validates :content, presence: true, length: { minimum: 10  }

end

Before running the spec make sure to apply the migration and prepare the test database by recreating it from db/schema.rb.

$ bundle exec rake db:migrate db:test:prepare

After running the spec you can see it pass:

$ bin/rspec spec/models/post_spec.rb

Install Cucumber

Cucumber helps us both focus on the feature-level and as a high-level integration testing tool.

Add cucumber-rails gem to the test group of the Gemfile.

group :test do
  gem 'shoulda-matchers'
  gem 'cucumber-rails', require: false
  gem 'database_cleaner'
end

You can also add the database_cleaner gem which is not required, but it will save you a lot of heartache. It’s used to ensure a clean database state for testing.

Install the gems:

$ bundle install

Bootstrap the app with Cucumber:

$ rails generate cucumber:install

Create the Cucumber binstub:

$ bundle binstubs cucumber

Install selenium-webdriver

To be able to run Cucumber scenarios which use Javascript you need selenium-webdriver.

Add it to the test group of your Gemfile:

group :test do
  gem 'cucumber-rails', require: false
  gem 'database_cleaner'
  gem 'factory_girl_rails'
  gem 'selenium-webdriver'
end

And install it:

$ bundle install

Make sure Cucumber is working correctly

To do that, let’s develop a simple feature.

# features/home_page.feature
Feature: Home page

  Scenario: Viewing application's home page
    Given there's a post titled "My first" with "Hello, BDD world!" content
    When I am on the homepage
    Then I should see the "My first" post
# features/step_definitions/home_page_steps.rb
Given(/^there's a post titled "(.*?)" with "(.*?)" content$/) do |title, content|
  @post = FactoryGirl.create(:post, title: title, content: content)
end

When(/^I am on the homepage$/) do
  visit root_path
end

Then(/^I should see the "(.*?)" post$/) do |title|
  @post = Post.find_by_title(title)

  page.should have_content(@post.title)
  page.should have_content(@post.content)
end
# config/routes.rb
Myapp::Application.routes.draw do

  root to: "posts#index"

end
# app/controllers/posts_controller.rb
class PostsController < ApplicationController

  def index
    @posts = Post.all
  end

end
<!-- app/views/posts/index.html.erb -->
<ul>
  <% @posts.each do |post| %>
    <li>
      <%= post.title %><br />
      <%= post.content %>
    </li>
  <% end %>
<ul>

Now run the feature file and you should see it pass:

$ bin/cucumber features/home_page.feature

Congratulations for making it this far. You should now be fully equipped to work in the BDD cycle and deliver clean, working code.

Introducing continuous deployment

Semaphore is great for testing your web application. Every day, code of thousands of developers is flowing through Semaphore for verification so that they can deliver new features to users with confidence.

But there’s more to delivery than testing, namely you need to deploy your code to the target servers. If you’re working in a team, someone needs to make sure that everyone has the right SSH configuration on their machines to be able to deploy. Done manually, deployment is a repetitive and distracting procedure. And since it has to be done within terminal sessions, there’s no way of keeping track of who deployed what and when.

Today we’re officially launching deployment as a first-class feature to futher increase your development velocity. Now you can let Semaphore automatically deploy working code to your application server. You’ll know exactly which version is on each of your servers. Best of all, this comes completely free - deployment jobs have top priority and do not count against your processor limit.

Here’s how it works:

Setting up a server

Get started by going to your project settings, Deployment tab. Following our goal of making things as simple as possible, you can set up a deploy target in a few easy steps. We are launching with two major options: Heroku and a custom script, which is usually Capistrano.

When using your deploy script, you need one new passwordless SSH RSA key that is present in the .ssh/authorized_keys file on server, inside the deploy user’s home directory.

Is it automatic?

The major behaviour difference comes from this option. Automatic deploys are tied to a particular branch, so for example every passed build of the staging branch will be deployed to this server.

With manual deployment, you can deploy any build from any branch. Note that this action is still possible to do on servers with automatic deployment. For example, you normally deploy to staging server from the staging branch, but sometimes also a snapshot of a short-lived feature branch.

Green builds trigger an automatic deploy

With automatic deployment set up for a specific branch, Semaphore will run a deploy with commands that you’ve provided in the setup process. The deploy in progress and report look similar to the build counterpart.

Deploying manually

To deploy a particular build manually, open it and click on “Deploy manually” in the top right corner of its header. You can then select the target server and write a quick release note. This is very useful because in many cases the last commit message will be something like “Merge ‘staging’ into master”. Instead of that, you can write something which will make it clear what went in with the release.

Notifications come in full package

The project timeline now includes deploys and their status for your viewing pleasure.

Semaphore can send email and chat notifications for each deploy. As with builds, you can turn this off in your project’s notification settings.

For a long time we’ve been sending reports to the login email address, but now every user can specify a different email for notifications on each project.

Deploys also come with full API and webhooks support.

A sidenote for the API: we’re aware that it could be a little bit better - we’ve started with a single endpoint and deliberately been adding new layers over time - so a V2 is in plans.

Viewing deploy history

While the dashboard and project page display the current deploy on each server, when necessary you can go to the server page and see the full deploy history. The entries are separated by dates which is a nice way to get a sense of progress.

We hope that you will enjoy these new features. Our big thanks goes to our power users who have been deploying their apps while this was in beta.

Ship early and ship twice as often.

Exploring CasperJS and Continuous Integration

All Ruby developers are probably familiar with Capybara - the tool for interacting with web pages that we all use and love. A similar thing exists in the JavaScript world - CasperJS.

CasperJS is a navigation scripting and testing utility for PhantomJS.

Since the setup is really simple, I wondered if CasperJS can be used for testing a Rails application and more so, how hard it is to run those tests on Semaphore.

Simple example

Here is a single test that visits the posts page and checks if everything is in order:

// test/javascripts/posts.js
casper.test.begin('Posts', 2, function suite(test) {
  casper.start("http://0.0.0.0:3000/posts", function() {
    test.assertTextExists("Posts");
    test.assertTextExists("Here you can find all posts");
  });

  casper.run(function() {
    test.done();
  });
});

The full example repository can be found here.

Semaphore setup

The setup includes a few steps:

  • preparing the Rails application
  • installing CasperJS (PhantomJS is already available on Semaphore)
  • loading test data
  • running the Rails application server
  • executing CasperJS tests

This translates nicely into several Semaphore build commands:

bundle install --deployment --path vendor/bundle
bundle exec rake db:setup
bundle exec rake db:test:prepare
git clone git://github.com/n1k0/casperjs.git ~/casperjs
cd ~/casperjs
sudo ln -sf `pwd`/bin/casperjs /usr/local/bin/casperjs
cd -
bundle exec rails server -p 3000 -e test &
sleep 30 # wait for server to run
casperjs --direct test test/javascripts/posts.js

Result

The result looks pretty green:

It’s worth noting that in this setup CasperJS tests don’t run in isolation: there are no database transactions so state persists across the whole test suite.

The right tool for the job

Is CasperJS a good fit for testing Rails applications on Semaphore? Probably not… There are other tools that can serve that purpose. But if you are looking for a tool for smoke testing a live instance of your app or you are more into JavaScript than Ruby, CasperJS is worth looking into.

If you do want use CasperJS in a Rails project, consider crafting a Rake task that can serve a similar purpose as the build commands from above.

What cool and unusual tools are you using in your project? Anything interesting in your Semaphore build commands? Let us know!

Book review: Growing object-oriented software, guided by tests

growing object-oriented software book cover

Growing object-oriented software, guided by tests was published in 2010 and is already considered a classic in the TDD community. I have found this to be for a good reason. It is the first book that I am aware of that guides you through development of a non-trivial application using TDD as a paradigm.

It begins with a short introduction of testing practices, where topics such as the TDD cycle and “tell, don’t ask” principle are briefly discussed. These are now well known in the testing world and are not covered in-depth; for those who seek more information there are references to explore further. Testing is just a part of the system design process, so there are some guidelines for object-oriented design as well.

The authors, Steve Freeman and Nate Pryce, then quickly dive in developing a working example: a Java desktop application that watches online auctions and bids over XMPP. There is very little left out: they share their design thinking and coding philosophy on every step in the process. It absolutely reflects real life experience. For example, the very first smoke-test seems quite modest in the beginning, yet reveals more unknowns then initially perceived and we are reminded once again how setting up new applications always takes longer than expected.

It’s as if you’re invited to see how senior engineers from Thoughtworks design and implement a system. However, you will not find authors preaching what is perfect code through artifically prepared examples. The problem is real enough - with external dependencies, asynchronous code and UI challenges. Solutions do not seem to be presented in hindsight; we learn and refactor along with the authors. I think this book will especially help those who, after having absorbed yet another talk, book or blog post about software design or testing, still find themselves slightly lost and producing suboptimal code at work.

The writing style is similar to other books in the Addison-Wesley signature series: rigorous, elaborate and clear. Closing chapters such as those on test readability or testing asynchronous code add even more value. Personally I have found myself sharpening my instinct for recognizing where really is a boundary of responsibility for classes. No matter how nice your programming language or framework is, do not hesitate to create new classes. Also, it helps to pay attention to little details such as not passing special strings / hashes but constants / value types. Maintaining your tests (and their setups) brief, informative and effective will take your project a long way.

Update 2013-07-18: Clarified sentence about writing style after feedback from the authors.

Upcoming platform update

This Sunday (July 7th) we will roll out an update to our build platform. It will include the latest versions of Ruby, Node.js and a few other packages.

Selenium users, Firefox will go up to version 22 so please remember to upgrade your selenium-webdriver gem.

Please see the changelog for the full list of changes.

Testing Rails apps that use Pusher with pusher-fake

Pusher is a great service for sending messages from anywhere to your users’ web browsers. It has all the good features of a cloud service: reliable uptime, great customer service and it enables you to outsource a complicated but probably not critical part of infrastructure.

Within Semaphore we’re using Pusher to send various status updates. For example, our build page has many moving parts but they’re clustered in a few page states. When a build starts, a background job sends a signal to all connected browsers to silently reload the page using Turbolinks and initialize new behaviour.

With an external API doing an important job, testing your system can be tricky. The common solution is to fake the related component with stubbed methods. For example, to test our GitHub integration, we use VCR to store and play back real responses. For Pusher we’d like a different kind of faking: ideally we need to keep the signal going through our backend to the browser but over localhost.

pusher-fake is a fake Pusher server that lets you have just that. The only change to your code is to conditionally load its’ JavaScript in test environment:

<script>
  <% if defined?(PusherFake) %>
    Pusher.host    = <%= PusherFake.configuration.socket_host.to_json %>;
    Pusher.ws_port = <%= PusherFake.configuration.socket_port.to_json %>;
  <% end %>
</script>

And replace the Pusher library’s implementation in the Rails app. If you’re using Cucumber:

require "pusher-fake/cucumber"

If not, recreate cucumber.rb in your initializer. Now you’re ready to run scenarios which trigger code that sends and receives messages.

Get future posts like this one in your inbox.

Follow us on