Yesterday morning I released a complete rewrite of RailsDiff, which just so happened to be exactly 31 months since I first launched the site. This new version uses a completely different architecture from the previous; this post is to describe some of the motivations behind the changes, and how those changes were made.
Wait, what’s the point of RailsDiff?
When you are going to upgrade a Rails application, RailsDiff is there to help you. It shows you what has changed in the default configurations between the version you are currently using and that to which you want to upgrade. The post where RailsDiff was announced goes into a bit more detail.
RailsDiff is about what you should change about your application’s configuration when upgrading Rails versions, not about what Rails has changed internally.
Motivation for the change
When I started this rewrite, my goal was not to use the latest, shiny tools available; instead it was to solve some real problems that I was having. And, in order to explain those problems, I believe a short review of how the app/site was built previously is in order.
The old implementation was a static site hosted on GitHub Pages. I had good reasons to build the site that way at the time. GitHub Pages is free, and I didn’t need an application to generate diffs on-demand because once a diff is generated it won’t change.
In order to have a static site, something needs to generate HTML files, and for that I turned to Rake. I actually made extensive use of Rake for RailsDiff, I used it to:
- Generate a new Rails app with each new release of Rails
- Generate a diff between each new app and all those that came before it
- Generate HTML files for each new diff
And, I was quite happy with that implementation. I really liked the process of updating the site when a new version of Rails was released, which usually took about a minute to do:
raketo generate all the new files
git add -A
git push origin gh-pagesto deploy the site
But, after 2.5 years and many releases of Rails this approach did have its downsides – most notably in disk space. It was approaching 5GB of generated, static files and growing exponentially faster with each new releases of Rails. Which caused me to be reluctant to add new features to the site, because that would mean more HTML files for each release, and even faster growth of disk space usage. I was also worried about the impact on collaborators, if step 1 was giving up 5GB+ of their hard drive space.
Better, stronger, faster
The first pass at the rewrite still had the diffs generated with Rake,
which I put into the
/public directory of the Ember CLI
app; this had the unfortunate side effect of all those diff files being
copied to the
/dist directory on build, which slowed down the build
process, and meant I wasn’t saving as much disk space. I eventually
worked around this downside by moving the diffs out of the
directory and instead modifying the build process to copy the files
over, which meant for development builds I could just copy a subset of
the diff files; this too was less than ideal, but at least kept
development build faster.
At that point I had a working application, but I needed to figure out
the deployment strategy. Having enjoyed my experience with GitHub Pages
up to that point, I wanted to continue to use it. Unfortunately it’s not
a great host for Ember applications unless you use
location: 'hash' in the router), which I preferred to avoid. The next
option was to deploy to Heroku using the buildpack suggested
by Ember CLI. But, this didn’t actually work for me,
because all of the diff files made the resulting application slug
larger than Heroku allowed limit, which led to me
modifying that buildpack to host pre-built Ember
After updating the UI, adding support for legacy URLs, and some other general polishing of the application, I was ready to release it. I was still a bit worried about the disk usage issue, as generating the diff files still had an exponential growth curve. That’s when a couple of my colleagues (Dray & Nate) convinced me that I needed to make an API app to generate the diff files on-demand; the reason being that only generating a new Rails app with each new release, and not the differences between all the releases, leads to a linear growth curve.
And, that’s where we are today. There are now two apps to be maintained: one for UI & behavior, and the other for data. Each with their own deployment schemes, their own narrow focus, and their own optimizations. It’s been a lot of effort and in the end, I’m very happy with the result. Hopefully, you will enjoy these changes as well.
If you see a problem with these changes or anything else that can be improved, please let us know.