13/12: Ruby, Rake, and Continuous Integration
I decided it was time to explore more Ruby, so I decided to implement my standard programming kata using Ruby without Rails. My primary intent was to further familiarize myself with the Ruby platform and some of it's most useful gems. Given that much of my Ruby and Rails work has been with small projects, the secondary intent of this endeavor was to simulate the type of environment in Ruby that I have grown accustomed to working with in Java. That is, large teams and applications, and the environment necessary to support the development effort. I had planned to document my steps and share them on this blog. It was supposed to go something like this:
- Develop my standard loan payment calculator to show the monthly payment of a loan based on a rate, term and principle.
- Use Test::Unit and further explore ways to separate test code from application code, understand directory structures and loadpaths, other environmental issues.
- Add a test suite to aggregate multiple tests into a single test run.
- Introduce a Rake build file to run the test suite and perform any other build related tasks
- Deploy the application as a REST service along with an html front end
- Setup a continuous integration environment with scheduled builds and deploys.
I had a good start, encountering a few rather interesting challenges along the way. Eventually, I hope to compile my notes and share them. However, I got sidetracked. Above all else, there was one glaring deficiency I struggled with tremendously.
Rake is a powerful build platform. There is something very nice about specifying the build in Ruby over xml configuration. Knowing Ruby means you know Rake minus a few useful tasks, and the power of a procedural over declarative language makes some things easier, such as conditional expressions and looping. Having my Rake build setup, I decided I'd take the next step and setup a continuous integration server on top of Rake. It's quite astonishing that given all the wonderful frameworks and utilities available for Ruby development, there is not a defacto standard continuous integration server that integrates with Rake. I did find a few, but none that have reached the epidemic proportions of CruiseControl. DamageControl is in hibernation. There is CIA, but it looks like that's been replaced by the Continuous Builder Plugin. The Continuous Builder Plugin appears to only work with Subversion, and documentation is rather sparse. Then there is Cerberus, which appears to be a solid candidate, but which also requires Subversion as your source repository, and is not a persistent server. It requires an external scheduler, such as Cron.
Overall, this has led me to a few revelations, and has left me wondering. Are teams practicing continuous integration on their Ruby projects? If so, how? And if not, then I'm left wondering how these teams are able to produce high quality source code? Are they simply relying on discipline to ensure all tests always execute? We know this practice cannot scale to large teams. Or are Ruby teams currently so small, they can rely solely on communication between developers? Maybe there aren't any true Ruby enterprise development efforts taking place? Given that Ruby doesn't require compilation, a robust suite of tests in Ruby is as close to compilation as it gets. Ruby/Rails has been touted as the perfect platform for agile development. Without a de facto standard continuous integration server, how are teams practicing continuous integration? And without continuous integration, how are they working in team environments? Without continuous integration, how are teams integrating and testing frequently enough to achieve 3-5 times, up to 10 times, productivity increases while avoiding the problems that must be ten-fold in an environment with no compilation?
Mostly, this has left me with a few unanswered questions, as well as some concern, related to all that I read about the joy and productivity of programming with Ruby/Rails, and the tools available to support the environment. I know that I enjoy the language. It makes me feel like a developer again, instead of a "configuration specialist". I know you can do much more with much less in Ruby/Rails, and I believe Ruby/Rails is a compelling alternative to other languages and platforms. But I am left wondering, "what else is missing"?
- Develop my standard loan payment calculator to show the monthly payment of a loan based on a rate, term and principle.
- Use Test::Unit and further explore ways to separate test code from application code, understand directory structures and loadpaths, other environmental issues.
- Add a test suite to aggregate multiple tests into a single test run.
- Introduce a Rake build file to run the test suite and perform any other build related tasks
- Deploy the application as a REST service along with an html front end
- Setup a continuous integration environment with scheduled builds and deploys.
I had a good start, encountering a few rather interesting challenges along the way. Eventually, I hope to compile my notes and share them. However, I got sidetracked. Above all else, there was one glaring deficiency I struggled with tremendously.
Rake is a powerful build platform. There is something very nice about specifying the build in Ruby over xml configuration. Knowing Ruby means you know Rake minus a few useful tasks, and the power of a procedural over declarative language makes some things easier, such as conditional expressions and looping. Having my Rake build setup, I decided I'd take the next step and setup a continuous integration server on top of Rake. It's quite astonishing that given all the wonderful frameworks and utilities available for Ruby development, there is not a defacto standard continuous integration server that integrates with Rake. I did find a few, but none that have reached the epidemic proportions of CruiseControl. DamageControl is in hibernation. There is CIA, but it looks like that's been replaced by the Continuous Builder Plugin. The Continuous Builder Plugin appears to only work with Subversion, and documentation is rather sparse. Then there is Cerberus, which appears to be a solid candidate, but which also requires Subversion as your source repository, and is not a persistent server. It requires an external scheduler, such as Cron.
Overall, this has led me to a few revelations, and has left me wondering. Are teams practicing continuous integration on their Ruby projects? If so, how? And if not, then I'm left wondering how these teams are able to produce high quality source code? Are they simply relying on discipline to ensure all tests always execute? We know this practice cannot scale to large teams. Or are Ruby teams currently so small, they can rely solely on communication between developers? Maybe there aren't any true Ruby enterprise development efforts taking place? Given that Ruby doesn't require compilation, a robust suite of tests in Ruby is as close to compilation as it gets. Ruby/Rails has been touted as the perfect platform for agile development. Without a de facto standard continuous integration server, how are teams practicing continuous integration? And without continuous integration, how are they working in team environments? Without continuous integration, how are teams integrating and testing frequently enough to achieve 3-5 times, up to 10 times, productivity increases while avoiding the problems that must be ten-fold in an environment with no compilation?
Mostly, this has left me with a few unanswered questions, as well as some concern, related to all that I read about the joy and productivity of programming with Ruby/Rails, and the tools available to support the environment. I know that I enjoy the language. It makes me feel like a developer again, instead of a "configuration specialist". I know you can do much more with much less in Ruby/Rails, and I believe Ruby/Rails is a compelling alternative to other languages and platforms. But I am left wondering, "what else is missing"?
(RSS 2.0)
Rob Sanheim wrote:
Here at Seeking Alpha we are definitely doing continuous integration. Our setup is something like this:
- local development done using Autotest, which is part of the ZenTest gem. Autotest is basically a lean CI tool on your local build machine that you leave running constantly while you develop. There is some info here and a short movie:
http://nubyonrails.com/arti...
- For "true CI" we use the continuous builder plugin on our staging box. Its not documented well, but I was able to get it setup after a little tweaking. We use SVN here, so that wasn't a concern. We do have issues with test runs "overrunning" each other, as they are setup to use some of the same database resources. The fix shouldn't be too tough, just haven't had time for it.
To be honest I've felt much less need for something like Cruise Control because of autotest and the constant communication our team has via IM/email/trac/etc.
Hope that helps!
- Rob