Author Archives: Highwayman

Specifying environments on Heroku

When I first started using Heroku for deployment, it truly was a black box for ‘push button deployment’ as I joked — one simply typed ‘git push heroku master’ into a black box, i.e. your shell, and things ‘should’ work…

But what if they do not, or if you need more options when deploying an application?

So, I took advantage of the holiday weekend to deep-dive into Heroku and first was these two useful rake scripts for adding staging/production deployment environments and rolling back migrations/deployments.

  • Gist by Nicola Junior Vitta for deploying, migrating and rolling back
  • Gist by Michael Dwan for setting up, deploying and breaking down
  • Gist by George Brock for creating and deploying to separate staging and production environments

The .rake files go into the lib/tasks directory for Rails 3 applications, and their usage follow their task naming convention in the .rake file. So, tasks that are nested would be called by ‘rake deploy:rollback_staging’ if rollback_staging were nested inside the deploy task code block.

The reason for these rake files is that Heroku currently supports only one rollback under the release management add-on, and if you are working on a share project where you are not the owner then you cannot enable the add-on… which is where the .rake files come in.

Finally, ‘heroku create’ appears to be a black box but it does come with options like most bash commands, e.g.: heroku create app-staging –stack bamboo-mri-1.9.2 –remote staging, where app-staging is the staging application name / bamboo-mri.1.9.2 is the flavor of Ruby selected for use in deployment / –remote staging is added as the staging branch for the deployment repository.

This write-up stems from my curiosity about deployment after poking around with Linode via Capistrano, which offer more control but also more configuration.

Git Resources

Source control is critical for tracking changes and managing development.

Often, the changes we make to our applications do not work out. We try something new in an experimental branch and either decide to change our minds or something about the project requirements renders it obsolete.

For Rails developers, git is the common practice for source control. Written by Linux Torvalt while workin on the Linux kernel. Practically, it tracks every change to every file (as long as it is being tracked) with a unique key (commit id).

In addition, it is possible to branch, merge and reverse any changes in a given code repository. Nifty stuff, and here are my favorite references whenever I need a quick refresher on which commands to use along with their options:

  • http://gitready.com/
  • http://progit.org/book/
  • http://cheat.errtheblog.com/s/git

Git and source control are large enough topics for many posts, and I may (or not) return to writing more about this topic once I have developed a skill level beyond my current ‘proficiency’ level.

Rollbacks & Release Management on Heroku

While working on an existing RoR application deployed on Heroku, I ran across the issue of rolling back previous deployments and release management into production.

The solution is a .rake file I found in a blog post by Casper Fabricious posted here that includes release management and rollbacks in staging and production environments.

Finally, here are my observations after doing my research on this topic:

General:

  • heroku only deploys from master branch of the git repo.
  • as a result, staging remote branches can be added but will not be deployed nor will any other branch for that matter.
  • heroku_san offers some additional rake tasks but do not manage rollbacks.
  • heroku release management add-on only manages single rollback to previous deployment.
  • work-around is using git tags and series of rake tasks: http://goo.gl/4tCSf
  • put the .rake file into the lib/tasks directory and run from command line, e.g. ‘rake deploy_staging’ or when task is nested under the :deploy namespace, then ‘rake deploy:staging_rollback’

Heroku rollbacks & release management:

Rollbacks via rake:

  • rollbacks via rake on github: http://goo.gl/4tCSf
  • usage: ‘rake deploy_staging’ or when task is nested under the :deploy namespace, then ‘rake deploy:staging_rollback’

 

[rvm] global gemset & 1.8.7-head vs. 1.8.7-p334.

Problem #1: New rvm gemset does not recognize Bundler.
Solution: Download Bundler into global gemset, then run ‘bundle install’.

Problem #2: When running rake, ruby-1.8.7-head throws private method chomp error.
Solution: Issues known in ruby-1.8.7-head. Revert to ruby-1.8.7-p334.

Here are the results via Gist:

# .rvm
# [fiveam] rvm global gemset & 1.8.7-head vs. 1.8.7-p334.

# Problem: rvm gemset does not recognize Bundler.
# Solution: store gem in global gemset, then run 'bundle install'.

me@me:~/classes/eff-tdd/aws-demo$ bundle install
bundle: command not found
me@me:~/classes/eff-tdd/aws-demo$ rvm use 1.8.7-p334@global
Using /home/me/.rvm/gems/ruby-1.8.7-p334 with gemset global
me@me:~/classes/eff-tdd/aws-demo$ gem install bundler
Fetching: bundler-1.0.11.gem (100%)
Successfully installed bundler-1.0.11
1 gem installed
Installing ri documentation for bundler-1.0.11...
Installing RDoc documentation for bundler-1.0.11...
me@me:~/classes/eff-tdd/aws-demo$ rvm use 1.8.7-p334@aws-demo
Using /home/me/.rvm/gems/ruby-1.8.7-p334 with gemset aws-demo
me@me:~/classes/eff-tdd/aws-demo$ bundle install
Fetching source index for http://rubygems.org/

# Problem: when running rake, ruby-1.8.7-head throws error in logger.rb.

me@me:~/classes/eff-tdd/aws-demo$ rake spec --trace
(in /home/me/classes/eff-tdd/aws-demo)
rake aborted!
private method `chomp' called for nil:NilClass
/home/me/.rvm/rubies/ruby-1.8.7-head/lib/ruby/1.8/logger.rb:174

# Solution: Known issues in 1.8.7-head build: http://www.ruby-forum.com/topic/523412, revert to 1.8.7-p334.

me@me:~/classes/eff-tdd/aws-demo$ rvm use 1.8.7-p334@aws-demo
Using /home/me/.rvm/gems/ruby-1.8.7-p334 with gemset aws-demo
me@me:~/classes/eff-tdd/aws-demo$ bundle install
bundle: command not found
me@me:~/classes/eff-tdd/aws-demo$ rvm use 1.8.7-p334@global
Using /home/me/.rvm/gems/ruby-1.8.7-p334 with gemset global
me@me:~/classes/eff-tdd/aws-demo$ gem install bundler
Fetching: bundler-1.0.11.gem (100%)
Successfully installed bundler-1.0.11
1 gem installed
Installing ri documentation for bundler-1.0.11...
Installing RDoc documentation for bundler-1.0.11...
me@me:~/classes/eff-tdd/aws-demo$ rvm use 1.8.7-p334@aws-demo
Using /home/me/.rvm/gems/ruby-1.8.7-p334 with gemset aws-demo
me@me:~/classes/eff-tdd/aws-demo$ bundle install
Fetching source index for http://rubygems.org/
...
view raw .rvm This Gist brought to you by GitHub.

 

Ruby and Rails in 5 Minutes with RVM

Installed Linux on yet another laptop, quick instructions for installing Ruby and Rails in 5 minutes (okay, maybe 10) with RVM.

Basic steps are get RVM installed, download Rubies using RVM, then setup and use .rvmrc gemsets inside your projects.

Here is the Gist to explain it:

# .rvmrc
# Finish downloads required OS prior to installing RVM -- Linux requires curl, bison, autoconf and git before cloning into local repo. Next, download RVM:

$ bash < <(curl -B http://rvm.beginrescueend.com/install/rvm)

# When complete, add this line to the bottom of the .bashrc file located in the /home/<name> directory:

[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # Loads rvm into shell.

# Run test to verify that installation was successful:

$ type rvm | head -1 # Should return 'rvm is a function'

# Install Rubies:

$ rvm install ruby-<version>-<build> # Sample: ruby-1.8.7-p334, can lead off build too.

# Install Rails along with your RVM gemsets -- create .rvmrc system file in your project directory using one line:

rvm use <ruby version>@<gemset> # Sample: 1.8.7-p334@test-app

# Create same gemset named above inside project directory:

$ rvm gemset create <ruby version>@<gemset> # Sample: 1.8.7-p334@test-app

# Begin using newly created gemset:

$ rvm use <ruby version>@<gemset> # Sample: 1.8.7-p334@test-app

# Run bundle install, which installs from Gemfile into gemset -- including Rails

$ bundle install

# These are the general steps, see http://rvm.beginrescueend.com/rvm/install/ with any problems during installation. Result is version of Ruby, Rails and gemsets nicely organized by project using .rvmrc. Repeat the process with .rvmrc, creating and using gemsets with each new project.
view raw .rvmrc This Gist brought to you by GitHub.

RSpec: Best Practices by Carbon Five

I have been focusing on RSpec lately, using it for my projects and taking the Efficient TDD course at Blazing Cloud. Although I prefer textbooks to the Internets for coding advice, the Carbon Five community site is an exception and contains useful bits such as their post on RSpec Best Practices.

The post reinforces what I am learning in the class regarding readability, formatting, and applying the DRY (Don’t Repeat Yourself) principle my spec files.

Benefits of cleaner, well-organize tests include:

  • Saves Code: Know exactly what is being tested so that both the test and code are following DRY.
  • Better Test Cases: Assertions and expectations are explicit so tests are written for specific scenarios vs. basic test coverage.
  • Readability: Test output is readable at run-time.

Thanks again to Carbon Five for the write-up, and I hope to share more test code soon.

Factories.rb: Simple as 1-2-3

Step 1: Add factory_girl to Gemfile and spec/spec_helper.rb.
Step 2: Define factories in spec/factories.rb.
Step 3: Method call from spec files.

See Github Gist below:

# Step 1: Add factory_girl to Gemfile and spec/spec_helper.rb:

# Gemfile:
gem 'factory_girl', '1.3.3'

# spec/spec_helper.rb:
require 'factory_girl'
require File.dirname(__FILE__) + "/../spec/factories.rb"

# Step 2: Define factories in spec/factories.rb
# Define sequence by calling sequence on factory object 'f'.

Factory.define :user do |f|
  f.status "New"
  f.role "Borrower"
  f.sequence(:name) { |n| "user-#{n}" }
  f.sequence(:email) { |n| "user-#{n}@example.com" }
  f.sequence(:password) { |n| "foobar-#{n}" }
  f.sequence(:password_confirmation) { |n| "foobar-#{n}" }
end

# Step 3: Method call from spec files:
@user = Factory(:user)
view raw factories.rb This Gist brought to you by GitHub.

Efficient TDD: Session One Re-cap and Marakana Video Series

I am taking the Efficient TDD course taught by Wolfram Arnold and hosted by Blazing Cloud for the next 6 weeks, which covers best practices, RSpec, integration testing and advanced topic such as API testing.

Marakana posted the video series of the course from the last time that it was taught in 2010. The course will come in handy for my consulting work for Varitan Capital Solutions.

Session one got off to a quick start with RVM setup for everyone and writing our first set of stories (test cases) in RSpec:

This Gist has been deleted.

Github Gist: App-template.rb

Here is a Rails generator file based on a gist by Blazing Cloud for creating RoR application templates in HAML, gemsets and git repository.

Usage: Place in project directory and run ‘rails new <app_name> app-template.rb’.

# app-template.rb

# Developed by Blazing Cloud.
# Usage: Place in project directory and run 'rails new <app_name> app-template.rb'.

rvmrc = <<-RVMRC
rvm gemset use #{app_name}
RVMRC

create_file ".rvmrc", rvmrc

gem "factory_girl_rails", ">= 1.0.0", :group => :test
gem "factory_girl_generator", ">= 0.0.1", :group => [:development, :test]
gem "haml-rails", ">= 0.3.4"
gem "rspec-rails", ">= 2.2.1", :group => [:development, :test]

generators = <<-GENERATORS

config.generators do |g|
g.test_framework :rspec, :fixture => true, :views => false
g.integration_tool :rspec, :fixture => true, :views => true
g.fixture_replacement :factory_girl, :dir => 'spec/factories'
g.template_engine :haml
end

GENERATORS

application generators

# Comment back in for jQuery library.
# get "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js", "public/javascripts/jquery.js"
# get "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/jquery-ui.min.js", "public/javascripts/jquery-ui.js"
#`curl http://github.com/rails/jquery-ujs/raw/master/src/rails.js -o public/javascripts/rails.js`

gsub_file 'config/application.rb', 'config.action_view.javascript_expansions[:defaults] = %w()', 'config.action_view.javascript_expansions[:defaults] = %w(jquery.js jquery-ui.js rails.js)'

layout = <<-LAYOUT

!!!
%html
%head
%title #{app_name.humanize}
= stylesheet_link_tag :all
= javascript_include_tag :defaults
= csrf_meta_tag
%body
= yield

LAYOUT

remove_file "app/views/layouts/application.html.erb"
create_file "app/views/layouts/application.html.haml", layout

create_file "log/.gitkeep"
create_file "tmp/.gitkeep"

git :init
git :add => "."

docs = <<-DOCS

Run the following commands to complete the setup of #{app_name.humanize}:

% rvm gemset create #{app_name}
% cd #{app_name}
% gem install bundler
% bundle install
% script/rails generate rspec:install

DOCS

log docs

Github Gist: Rvmrc, Factories.rb and Gemset for Testing

Here are several snippets of Ruby code I found useful and shared on Github Gists:

Rvmrc, see also: http://rvm.beginrescueend.com/workflow/rvmrc:

This Gist has been deleted.

Factories.rb, see also: https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md:

This Gist has been deleted.

Update on factories.rb for Rails 3 and RSpec 2, using Factory(:user) method call and sequences:

This Gist has been deleted.

Gemset for Testing:

This Gist has been deleted.
Performance Optimization WordPress Plugins by W3 EDGE