Today we’re announcing a new project called Divergence. It was built to streamline staging server testing by avoiding developer conflicts and by removing the deployment process altogether. All of this is done by taking advantage of the way Git branches work.

What’s Divergence?

At LayerVault, we’ve always made a habit of developing new features on their own branches. Also known as the Github Flow, it’s a great way to keep your master branch clean and to avoid development conflicts with other features. Unfortunately, it can be expensive to run multiple staging servers, so before testing any production-ready code we always have to ask if the staging server is in use to avoid confusing fellow co-workers. To add to the problem, fixing even the smallest issues are a pain. You have to deploy code, test, fix bugs, push the fixes, deploy again, test, and so on.

If we’re always testing a new feature against a specific branch, then that branch name has special meaning. It’s a unique identifier. What if we could completely eliminate the annoyingly repetitive parts of the testing process by taking advantage of this fact?

We had a revelation. Subdomains are unique. Branch names are unique. Why not make them one and the same? Just use the branch name as the subdomain and magically get back the version of the site you needed to test.

# Before git push origin feature_1 cap staging deploy # Go grab some coffee open http://staging.layervault.com # After git push origin feature_1 open http://feature-1.layervault.com

How It Works

Divergence is actually a proxy, built with Rack. It sits between you and your actual web application, and runs on the same server as the application. It also has access to the git repository for your application locally on the server.

A request looks something like this:

Divergence gets an incoming request with a subdomain. Lets assume it’s “feature-1”. It automatically figures out the branch you want based on the subdomain. In this case, it could be “feature_1” and it would still find it. Next, it checks to see if the branch has been cached yet. Divergence caches the latest few branches accessed for super fast feature testing. Depending on whether the branch was cached, it will make sure everything is up to date and ready to go on the file system. We can automatically run a ‘bundle install’ here, or any other arbitrary code, if needed. Once things are ready, Divergence will link the application folder (defined in config) to the cached folder. This is very much modeled after Capistrano’s setup. Since everything on the server is now ready, we pass the request on to your actual application, and proxy the response back to you.

This sounds like a lot to accomplish in the span of a single request, but Divergence is smart. It will only switch branches (and run Git operations) when needed. It caches code from multiple branches for rapid switching. It only fires certain callbacks when needed.

Divergence also takes advantage of Github Service Hooks to automatically keep everything up to date. Simply push your new code, wait a few seconds for the service hook to be sent from Github and for Divergence to process it, and refresh.

What’s Left?

There is so much more that can be done with Divergence, which is one reason why we’re open-sourcing it. We primarily use Ruby at LayerVault, but that doesn’t mean Divergence should be limited to Ruby. It was developed to be framework and language agnostic (in regards to your web application), but it should already work with most setups. That said, there is a lot of work that can be done with testing and assisting the user in making the process as smooth as possible. Many more problems/ideas are listed in the GitHub repository.

We’ll answer any questions about the project on Hacker News.

—Ryan