Don't repeat your capistrano rules

An advice often seen in the Rails world is DRY, Don't Repeat Yourself. As explained on the c2 wiki, duplication (whether inadvertent or purposeful) can lead to maintenance nightmares, poor factoring, and logical contradictions, and so, you should try hard to avoid it.

We deploy our projects with Capistrano, which is a good thing to fight the Not Invented Here syndrome. But the capistrano rules were cloned and modified from one project to another, which was a strong sign that we violated the DRY principle.

So I decided to regroup our rules in a gem: capistrano-af83. This ruby gem is an extraction of the rules of our different projects to avoid their duplication. To be honest, there were other goals in this gem, I'll explain them later.

What I discovered at first was that our rules weren't as good as I hoped so, and the duplication took a large part of it. For example, two projects were setting :keep_releases but didn't call the deploy:cleanup task. I'm in favor of having this rule by default in capistrano but it's not the case for the moment, so I put these 2 lines in our default configuration:

set :keep_releases, 5
after "deploy:update", "deploy:cleanup"

Another example of why duplication of capistrano rules is bad: an enhancement of a task on one project is not automatically applied on the other projects. We were having 2 tasks to handle the mongoid.yml file that behave differently. One was better than the other, but the later was used because the guy who wrote it didn't know of the other way! Now, this rule is in capistrano-af83 (mongoid.rb), so it won't happen again.

As I said, I made capistrano-af83 with other aims. First, I wanted to enforce some conventions for naming the environment. We now have a stages.rb to create our 3 default environments: dev, staging and production.

Secondly, it's become easier to use capistrano on a fresh project as we have a template for Rails and I hope to add others templates later.

After using capistrano-af83 on several projects, I can say it's a real improvement for us. But I'd like to know how do you do for your own projects? Do you practice the clone and modify approach? Or do you have a repository of common rules for your projects? Please explain you way and what you feel are the pros and the cons in the comments.

blog comments powered by Disqus