Integrating Compass with a Git / Capistrano deployment workflow

When we added the Compass CSS authoring framework to our projects, new wrinkles appeared in the deployment process (which is based on Capistrano. Several workflow options were considered:

  • Committing the artifacts to Git
  • Generating the artifacts on the server
  • Using the Drupal Compass or Sassy module
  • Generating the artifacts on the workstation running Capistrano

Committing the artifacts to Git was used for our first prototypes, but is unsuitable for team projects because it's a sure-fire way to introduce merge conflicts. Running compass on the server (either with Cap or the Drupal module) is appealing, but a minority of our projects deploy to hosts without the ability to install Compass. Rather than support multiple strategies, we decided on the last option - executing Compass on the workstation running Capistrano.

Changes are needed to several files:

.gitignore

compass_app_log.txt
.sass-cache
compass_generated_stylesheets
*-s[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].png

config.rb (Compass)

http_path = "/sites/all/themes/metaltoad/"
css_dir = "compass_generated_stylesheets"
sass_dir = "sass"
images_dir = "images"
javascripts_dir = "compass_javascripts"
fonts_dir = "fonts"

theme.info

stylesheets[all][] = compass_generated_stylesheets/screen.css
stylesheets[all][] = compass_generated_stylesheets/media.css
stylesheets[all][] = compass_generated_stylesheets/print.css

config/deploy.rb (Capistrano)

# build Compass artifacts
set :theme_path, "#{app_root}/sites/all/themes/metaltoad"
 
after "deploy:update_code" do
  run_locally("cd #{theme_path}; compass clean")
  run_locally("cd #{theme_path}; compass compile --output-style compressed")
  upload("#{theme_path}/compass_generated_stylesheets",
    "#{release_path}/#{theme_path}/compass_generated_stylesheets")
  # Glob is nasty, but the generated_images directory
  # option isn't supported until Compass 0.12.
  Dir.glob("#{theme_path}/images/*-s[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].png").each do|f|
    upload(f, "#{release_path}/#{f}")
  end
end

Long-term, we'll probably migrate after "deploy:update_code" to a proper Capfile task.

Ready to get started?