Commercial Products
Sep '09

Releasing with Rudy

posted by delano

I have about 10 active opensource projects. I'm lucky because most of them aren't that popular so there's not a lot of overhead. Beyond other people using your work there are some significant advantages in maintaining projects as opensource (I'll talk more about that in a future post). That said, there is additional effort involved so I've automated some tasks with Rudy to reduce the repetitive tasks. One such task is the release process.

Minor warning: The following is specific to Ruby development on Linux/Unix with git because that where I do most of my work. If you've created configurations for other languages (including projects on Windows) let me know and I'll post them or include them in the arcade.

My Rudy Configuration

One of the core features of Rudy is the routines configuration. A routine is like a really concise Rake task that can be associated to a particular machine role. A little known fact is that Rudy also supports defining global routines which are available to all machines.

Rudy looks for global routines in two places:

  • ~/.rudy/
  • /etc/ (linux only)

I put the following configuration into a file called ~/.rudy/release-routines.rb.

commands do
  allow :rm

routines do

publish do before :package_test, :publish_docs local do project = File.basename pwd.first puts "PUBLISH #{project}", $/ end after :publish_github, :publish_gem end

package_test do local do puts 'Creating Test package...' rake 'package', 'clean' end end

publish_docs do before :publish_rubyforge_docs, :publish_github_docs end

publish_rubyforge_docs do local do puts 'Updating Rubyforge docs...' rake 'publish:rdoc', 'clean' end end

publish_github_docs do local do rake 'rdoc' if file_exists?('doc') puts 'Updating Github Pages...' git 'checkout', 'gh-pages' rm :r, :f, 'files', 'classes' unsafely { mv 'doc/*', '.' } rm :r, :f, 'doc' git 'add', '.' git 'commit', :a, :m, 'Updated docs'

    <span class="n">git</span> <span class="s1">'checkout'</span><span class="p">,</span> <span class="s1">'master'</span>
    <span class="n">git</span> <span class="s1">'push'</span>
  <span class="k">else</span>
    <span class="nb">puts</span> <span class="s1">'No docs directory'</span>
  <span class="k">end</span>
<span class="k">end</span>


publish_github do local do puts 'Pushing to GitHub...' git 'tag', :f, 'latest' git 'push', '--all' git 'push', '--tags' end end

publish_gem do local do puts 'Publishing Rubyforge gem...' rake 'publish:gem', 'clean' end end


The Rudy configuration I use to create releases of my open source projects.

My Release Process

With the configuration above in place, I can run the release routines I created from any directory on my machine. But before I run the automated process, there are a few tasks that still require manual attention.

  • Update the change log
  • Update file manifest and dependencies in the gemspec file (if necessary)
  • Increment the release number
  • Commit all local changes
  • Create a release tag

Then I run the following simple command from the project directory:

$ rudy publish

There's huge value in being able to define a routine in one location yet be able to run it from each individual project directory. It establishes a standard process for all of your projects which reduces overhead (including the mental workload) and increases consistency.

For example, you'll note the publish_github routine creates a tag called "latest". That allows me to refer to that tag in long-running or rarely updated documentation when I talk about the most recent release. It's little things like that that make a big difference over the long run. Both in terms of my time and the visible consistency of a project.

Future Additions

Astute readers will note a couple glaring improvements than can and should be made to this process. The first is creating the release tag automatically based on the gemspec (or possibly library version). The second is removing the reliance on Rake. There are some tasks that Rake is specifically suited for, but in this case it's possible to cleanly migrate the calls for building the documentation and Rubygems into Rudy directly.

And that's it. Do you automate your release process?

I'm Delano Mandelbaum, the founder of Solutious Inc. I've worked for companies large and small and now I'm putting everything I've learned into building great tools. I recently launched a monitoring service called Stella.

You can also find me on:

-       Delano (

Solutious is a software company based in Montréal. We build testing and development tools that are both powerful and pleasant to use. All of our software is on GitHub.

This is our blog about performance, development, and getting stuff done.

-       Solutious